2017年10月17日 22:51:36 前言將登陸信息和狀態(tài)保存到哪里一直是我困惑的。保存到cookie里面?不不,太不安全;保存到session?不不,處于進(jìn)程里影響性能降低還易丟失;保存到數(shù)據(jù)庫(kù)?我的確這樣想過(guò)也試過(guò),安全又完整但是讀數(shù)據(jù)庫(kù)讓我不滿意;保存到HttpRunTime.Cache里面? 在查找一些資源后我了解到可以保存到緩存數(shù)據(jù)庫(kù)里面,memcache就是其中一款緩存數(shù)據(jù)庫(kù),并且還擁有其他的好處。 在我們了解memcache之前,先了解以下信息: 傳統(tǒng)數(shù)據(jù)庫(kù)面臨的問(wèn)題Web程序在面臨海量數(shù)據(jù)、高并發(fā)請(qǐng)求時(shí),傳統(tǒng)的數(shù)據(jù)庫(kù)往往會(huì)面臨以下問(wèn)題: 數(shù)據(jù)庫(kù)死鎖數(shù)據(jù)庫(kù)基本操作curd,死鎖是數(shù)據(jù)庫(kù)高并發(fā)的明顯問(wèn)題:r要加S鎖(共享鎖,可以查看但是無(wú)法cud),cud要加X(jué)鎖(排他鎖,可以curd,其他事務(wù)無(wú)法再次加鎖),當(dāng)高并發(fā)請(qǐng)求,數(shù)據(jù)庫(kù)可能產(chǎn)生死鎖(數(shù)據(jù)庫(kù)阻塞,永遠(yuǎn)等待狀態(tài))。這是無(wú)法避免的問(wèn)題。以下是解決死鎖的常見(jiàn)手段: 死鎖預(yù)防 使用數(shù)據(jù)庫(kù)邏輯上來(lái)預(yù)防死鎖,但是這顯然還會(huì)出現(xiàn)慢的問(wèn)題。 讀寫分離 就是做數(shù)據(jù)庫(kù)集群,使用主從數(shù)據(jù)庫(kù):將數(shù)據(jù)保存到多個(gè)主從數(shù)據(jù)庫(kù)里面,主數(shù)據(jù)庫(kù)負(fù)責(zé)cud,多個(gè)從數(shù)據(jù)庫(kù)負(fù)責(zé)r,這樣不僅避免死鎖,也提高了速度。但是同樣帶來(lái)了問(wèn)題: SqlServer sqlserver在數(shù)據(jù)同步方面很弱,并不適合數(shù)據(jù)同步。主要有三種方法實(shí)現(xiàn):買中間件(不可靠)、發(fā)布訂閱(主庫(kù)生成數(shù)據(jù)庫(kù)快照給其他數(shù)據(jù)庫(kù),但是有延遲)、代碼實(shí)現(xiàn)寫入多個(gè)數(shù)據(jù)庫(kù)(不好)。 Mysql 有很多第三方組件可以實(shí)現(xiàn),很多成功的例子。 Oracle 本身就支持?jǐn)?shù)據(jù)庫(kù)同步,只需要配置以下就好了。(另外Oracle因?yàn)闀?huì)最大程序占用資源,所以效率很高)
磁盤IO數(shù)據(jù)庫(kù)把數(shù)據(jù)保存到磁盤上,讀取慢,磁盤IO是一大原因,因?yàn)榇疟PIO是硬件問(wèn)題。常見(jiàn)解決方式如下: 接下來(lái)使用控制臺(tái)應(yīng)用程序來(lái)操作memcache。 正文了解memcachememcache官網(wǎng) memcached是一種高性能,分布式的內(nèi)存對(duì)象緩存系統(tǒng),本質(zhì)上是通用的,但最初旨在通過(guò)減輕數(shù)據(jù)庫(kù)負(fù)載來(lái)加速動(dòng)態(tài)Web應(yīng)用程序。 原理內(nèi)存處理
客戶端實(shí)現(xiàn)分布式: 給memcache配置多個(gè)服務(wù)器ip,當(dāng)需要查詢時(shí)會(huì)尋找哪臺(tái)服務(wù)器或者添加一個(gè)數(shù)據(jù)時(shí)會(huì)保存到哪一個(gè)服務(wù)器上呢?memcache對(duì)key值進(jìn)行哈希計(jì)算然后對(duì)配置的服務(wù)器總數(shù)進(jìn)行取余,余數(shù)是幾就向第幾臺(tái)服務(wù)器進(jìn)行操作。這就導(dǎo)致了一個(gè)問(wèn)題:當(dāng)服務(wù)器數(shù)量發(fā)生變化時(shí)會(huì)導(dǎo)致部分?jǐn)?shù)據(jù)丟失(查詢指向服務(wù)器錯(cuò)誤)。想要這種影響降低到最低,可以使用一致性哈希算法。 走socket 數(shù)據(jù)通信走的是socket。
基本命令這里引用IBM developerWorks里面的一篇文章部分內(nèi)容 基本 memcached 客戶機(jī)命令 您將使用五種基本 memcached 命令執(zhí)行最簡(jiǎn)單的操作。這些命令和操作包括: set add replace get delete 前三個(gè)命令是用于操作存儲(chǔ)在 memcached 中的鍵值對(duì)的標(biāo)準(zhǔn)修改命令。它們都非常簡(jiǎn)單易用,且都使用清單 5 所示的語(yǔ)法: 清單 5. 修改命令語(yǔ)法 command key flags expiration time bytes value key key 用于查找緩存值 flags 可以包括鍵值對(duì)的整型參數(shù),客戶機(jī)使用它存儲(chǔ)關(guān)于鍵值對(duì)的額外信息 expiration time 在緩存中保存鍵值對(duì)的時(shí)間長(zhǎng)度(以秒為單位,0 表示永遠(yuǎn)) bytes 在緩存中存儲(chǔ)的字節(jié)點(diǎn) value 存儲(chǔ)的值(始終位于第二行)
其中key最大長(zhǎng)度255字符。 memcache與memcachedmemcache是項(xiàng)目的名字,memcached是項(xiàng)目被可執(zhí)行代碼的名字,一般指同一個(gè)東西。 memcache的適用范圍可以將其視為應(yīng)用程序的短期內(nèi)存。不適合保存持久化數(shù)據(jù)。其是分布式系統(tǒng),數(shù)據(jù)分布在多個(gè)機(jī)器上遷移很麻煩。也不會(huì)記錄數(shù)據(jù)。這里用戶的登陸狀態(tài)并不需要專門保存,可以使用memcache保存。 memcache的客戶端和服務(wù)端memcache有客戶端和服務(wù)端之分,客戶端編程,需要引用相應(yīng)的dll文件;服務(wù)端開(kāi)啟memcached服務(wù)。 memcache服務(wù)端本身不支持windows下使用,但是一些愛(ài)好者提供了windows下的exe程序來(lái)開(kāi)啟這個(gè)服務(wù)。 請(qǐng)搜索Memcached.ClientLibrary來(lái)下載你需要使用的dll文件和exe服務(wù),我是在sourceforge這里下載的。 memcache與redis異同memcache經(jīng)常與redis進(jìn)行對(duì)比 相同點(diǎn): 都使用內(nèi)存;效率都很高,1s內(nèi)讀1w次,寫10w次都很平常; 不同點(diǎn):
線程 memcache是多線程,redis是單線程,所以寫多數(shù)據(jù)時(shí)memcache效率更好。 數(shù)據(jù)類型 memcached使用key-value存儲(chǔ),本身就是一個(gè)hash(哈希表)。 redis現(xiàn)階段提供五種數(shù)據(jù)類型:string(字符串類型)、list(鏈表)、set(集合)、zset(有序集合)、hash(哈希表)。 數(shù)據(jù)存儲(chǔ) memcache是分布式系統(tǒng),每個(gè)服務(wù)器都值保存一部分?jǐn)?shù)據(jù),遷移很弱(memcache定位就是短期內(nèi)存,保存在memcache里面的數(shù)據(jù)本來(lái)就是不需要遷移的)。斷電丟失數(shù)據(jù)。 redis啟用內(nèi)存但是可以保證數(shù)據(jù)持久化、完整性和同步,即每個(gè)服務(wù)器都保存完整數(shù)據(jù)。這是因?yàn)閞edis的存儲(chǔ)分為內(nèi)存存儲(chǔ)、磁盤存儲(chǔ)和log文件三部分,配置文件中有三個(gè)參數(shù)對(duì)其進(jìn)行配置,斷電之后可以通過(guò)文件來(lái)恢復(fù)數(shù)據(jù);使用快照的方式進(jìn)行數(shù)據(jù)同步。
簡(jiǎn)單使用memcached打開(kāi)memcache服務(wù)這一步相當(dāng)玉開(kāi)啟服務(wù)端的memcache服務(wù)。在windows下開(kāi)啟服務(wù)相當(dāng)簡(jiǎn)單,直接打開(kāi)這個(gè)exe程序就行了
但是這個(gè)程序結(jié)束后服務(wù)就關(guān)閉了。這里把它安裝成windows下的一個(gè)服務(wù)。 打開(kāi)管理員命令提示符,輸入exe文件的路徑和安裝命令
然后memcached就成為windows下的一個(gè)服務(wù)了,可以設(shè)置自動(dòng)手動(dòng)之類的。
 使用memcached命令如果只是布置服務(wù)端的話,上一步就已經(jīng)完成了。如果想要連接服務(wù)端的memcached服務(wù)并且使用命令的話,可以使用以下步驟: 1. 打開(kāi)Telnet客戶端服務(wù)
2. 打開(kāi)管理員命令提示符連接服務(wù)端memcached服務(wù)
3. 使用命令 連接成功后就會(huì)進(jìn)入控制臺(tái)界面
第一行代碼是不可見(jiàn)的,可以按enter再輸入stats(或者直接stats)打開(kāi)memcached統(tǒng)計(jì)信息
 然后就可以愉快地輸入你的命令了,如使用add命令來(lái)添加和get命令獲取值,key值已經(jīng)存在就會(huì)返回NOT_STORED提示,如果正確添加就會(huì)返回STORED提示。

注意: 命令無(wú)法退格,所以輸錯(cuò)就按enter重新輸入 memcached默認(rèn)端口11211
添加引用默認(rèn)memcache引用程序集會(huì)自帶一個(gè)log4net.dll文件以便錯(cuò)誤時(shí)可以記錄日志,這里并不需要記錄日志就不引用。
 程序代碼using Memcached.ClientLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MemcachedDemo
{
class Program
{
static void Main(string[] args)
{
//SockIOPool是Memcached客戶端提供的一個(gè)套接字連接池,是與Memcached服務(wù)器端交換數(shù)據(jù)的對(duì)象。
//SockIOPool在應(yīng)用程序啟動(dòng)時(shí)初始化一次就可以了,我們可以把這個(gè)工作放在 GLOBAL.ASAX.CS的Application_Start方法里。
try
{
MemcachedClient mc = new MemcachedClient();
mc.EnableCompression = false;
string[] serverlist = {"127.0.0.1:11211"};
SockIOPool pool = SockIOPool.GetInstance();
//初始化
pool.SetServers(serverlist);
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 50;
pool.SocketConnectTimeout = 1000;
pool.SocketTimeout = 3000;
pool.MaintenanceSleep = 30;
pool.Failover = true;
pool.Nagle = false;
pool.Initialize();
mc.Add("key1","這是第一個(gè)數(shù)據(jù)",0);
string value= mc.Get("key1") as string;
Console.WriteLine(value);
}
catch (Exception err)
{
//這里可以用Log4Net記錄Error
}
Console.ReadLine();
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
運(yùn)行效果
引申集群和分布式 數(shù)據(jù)庫(kù)集群:往往在同一局域網(wǎng),使用同一個(gè)IP,每個(gè)數(shù)據(jù)庫(kù)有完整數(shù)據(jù),難點(diǎn)是數(shù)據(jù)同步,遷移方便。 數(shù)據(jù)庫(kù)分布式:每個(gè)系統(tǒng)擁有部分?jǐn)?shù)據(jù),使用使用簡(jiǎn)單,數(shù)據(jù)遷移麻煩。 Redis主從數(shù)據(jù)庫(kù) 主庫(kù)負(fù)責(zé)寫,從庫(kù)負(fù)責(zé)讀,壓力分流。 主庫(kù)掛掉,隨機(jī)選擇一個(gè)從庫(kù)成為主庫(kù)。 數(shù)據(jù)如何同步:快照。
總結(jié)memcache的key值最大255字符 memcached的塊最大1M
若有錯(cuò)誤請(qǐng)指正,不勝感激。來(lái)源:http://www./content-4-175951.html
|