缓存应用--Memcached分布式缓存简介(二)
1 命令行查看狀態
? 很多時候我們需要去查看Memcached 的使用狀態,比如Memcached 的運行時間,使用狀態等等。在Windows系統中我們可以使用telnet 命令來查看Memcached 的相關運行情況。
??開始—>運行àcmd 運行得到如下:
?
輸入telnet命令: telnet 服務地址 端口?
?
Memcached 的默認端口號是11211
?? ? ?輸入stats 命令: 在這里屏幕是空白,看不到輸入的內容,回車之后可以看到Memcached的運行相關信息。?
?
Pid: Memcached 服務器中的進程編號
?? Uptime:Memcached服務器啟動之后所經歷的時間,單位秒
?? Time: 當前系統時間,單位秒
??Version: Memcached 的版本號
??pointer_size:服務器所在主機操作系統的指針大小,一般為32或64
??curr_items:表示當前緩存中存放的所有緩存對象的數量
??total_items:表示從memcached服務啟動到當前時間,系統存儲過的所有對象的數量,包括已經刪除的對象
??bytes:表示系統存儲緩存對象所使用的存儲空間,單位為字節
??curr_connections:表示當前系統打開的連接數
??total_connections:表示從memcached服務啟動到當前時間,系統打開過的連接的總數
??cmd_get: 查詢緩存的次數,即使不成功也算一次
??cmd_set: 保存數據的次數,當然這里只保存成功的次數
??get_hits:表示獲取數據成功的次數。
??get_misses:表示獲取數據失敗的次數。
??evictions:為了給新的數據項目釋放空間,從緩存移除的緩存對象的數目。比如超過緩存大小時根據LRU算法移除的對象,以及過期的對象
??bytes_read:memcached服務器從網絡讀取的總的字節數
??bytes_written:memcached服務器發送到網絡的總的字節數
??limit_maxbytes:memcached服務緩存允許使用的最大字節數
??threads:被請求的工作線程的總數量
緩存命中率 = get_hits / cmd_get * 100%?;?2 Memcached 存儲機制
? ?? ??關于Memcached的存儲機制,在網上搜了一下講解基本上都是千篇一律的。
memcached默認情況下采用了名為Slab Allocator的機制分配、管理內存。在之前的版本中,Memcached存儲會導致很多內存碎片,從而加重了操作系統對內存管理的負擔。Slab Allocator的基本原理是按照預先規定的大小,將分配的內存分割成特定長度的塊, 以完全解決內存碎片問題。
借用一張圖說明一下:??????
Slab Allocation 將分配的內存分割成各種尺寸的chunk (塊),并把大小相同尺寸的chunk分為一組,就如上圖一樣:分割了 88b,112b,144b等尺寸。其實Slab Allocation還有重復利用內存的功能,也就是說分配的內存不會釋放,而是重復利用。
當存儲數據的時候,它會自動去查找最為匹配的chunk,然后將數據存儲到其中。比如我存儲數據的大小為110B,那么它會存儲到112B的chunk中。
? ???上面的問題來了,我存儲只需要110B,但是我存儲到112B的chunk中。如下圖(借用):?
?
?? ?那么在110b的存儲中會浪費2B的內存空間
至于如何完全解決這個內存空間浪費的問題,還沒有很好的方案,不過Memcached的 增長因子(Growth Factor)能夠適當解決此問題。目前Memcached的默認增長因子 ? ? ?是1.25,也就是說會以原有的最大值基礎上乘以1.25 來分配空間。?
3 Memcached 對內存資源的有效利用
之前已經提到過了,Memcached 會重復利用已經分配的內存,也就是說不會去刪除已有的數據而且釋放內存空間,而是數據過期之后,用戶將數據不可見。
???????? Memcached 還是用了一種Lazy Expiration (延遲過期[姑且這樣翻譯]) 技術,就是Memcached不會去監視服務器上的數據是否過期,而是等待get的時候檢查時間戳是否過期,減少Memcached在監控數據上所用到的時間。
Memcached 不會去釋放已經使用的內存空間,但是如果分配的內存空間已經滿了,而Memcached 是如何去保證內存空間的重復使用呢!Memcached 是用了 Least Recently Used(LRU) 機制來協調內存空間的使用。LRU 意思就是最少最近使用,當此處內存空間數據最長時間沒有使用,而且使用次數很少,在存儲新的數據的同時就會覆蓋此處空間。?4 Memcached 客戶端使用簡單封裝
本文很多都是理論上的分析,這些大多也是從網絡上看來的,根據自己的理解和實際的應用做了一些總結。有時候我們使用Memcached的客戶端時并不是那么的友好,這里對其做了一下簡單的封裝,抽象出來了一個接口:
1?usingSystem;2?usingSystem.Collections.Generic;
3?usingSystem.Linq;
4?usingSystem.Text;
5?usingSystem.Collections;
6?
7?namespaceMemcachedTest
8?{
9?publicinterfaceICache
10?{
11?boolContainKey(stringargKey);
12?
13?boolAdd(stringargKey,objectargValue);
14?
15?boolAdd(stringargKey,?objectargValue,?DateTime?argDateExpiration);
16?
17?boolAdd<T>(stringargKey,?T?entity)?whereT?:?class;
18?
19?boolAdd<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class;
20?
21?boolSet(stringargKey,?objectargValue);
22?
23?boolSet(stringargKey,?objectargValue,?DateTime?argDateExpiration);
24?
25?boolSet<T>(stringargKey,?T?entity)?whereT?:?class;
26?
27?boolSet<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class;
28?
29?boolReplace(stringargKey,objectargValue);
30?
31?boolReplace(stringargKey,objectargValue,DateTime?argDateExpiration);
32?
33?boolReplace<T>(stringargKey,?T?entity)?whereT?:?class;
34?
35?boolReplace<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class;
36?
37?objectGet(stringargKey);
38?
39?T?Get<T>(stringargKey);
40?
41?boolRemove(stringargKey);
42?
43?boolRemove(stringargKey,?DateTime?argDateExpiration);
44?
45?boolRemove();
46?
47?boolRemove(ArrayList?servers);
48?
49?}
50?}?
下面這段代碼對上面的接口進行了實現,里面的代碼大多數人應該能夠看懂,是比較簡單的代碼封裝,如果能夠了解本人上一篇的簡單應用,對于這個封裝的理解應該沒有難度。實現代碼如下:
1?usingSystem;2?usingSystem.Collections.Generic;
3?usingSystem.Linq;
4?usingSystem.Text;
5?usingMemcached.ClientLibrary;
6?usingSystem.Collections;
7?
8?namespaceMemcachedTest
9?{
10?publicclassMemcache:ICache
11?{
12?privateMemcachedClient?client;
13?privatestaticMemcache?memcache;
14?
15?///<summary>
16?///構造方法
17?///</summary>
18?protectedMemcache()
19?{
20?SockIOPool?pool?=SockIOPool.GetInstance();
21?string[]?servers?={?"127.0.0.1:11211"};
22?pool.SetServers(servers);
23?pool.MinConnections?=3;
24?pool.MaxConnections?=5;
25?pool.InitConnections?=3;
26?pool.SocketConnectTimeout?=5000;
27?pool.Initialize();
28?this.client?=newMemcachedClient();
29?client.EnableCompression?=false;
30?}
31?
32?publicstaticMemcache?Instance()
33?{
34?if(memcache?==null)
35?{
36?memcache?=newMemcache();
37?}
38?returnmemcache;
39?}
40?
41?
42?///<summary>
43?///判斷是否包含某個鍵
44?///</summary>
45?///<param?name="argKey">鍵值</param>
46?///<returns></returns>
47?publicboolContainKey(stringargKey)
48?{
49?returnclient.KeyExists(argKey);
50?}
51?
52?///<summary>
53?///添加緩存數據
54?///</summary>
55?///<param?name="argKey">鍵值</param>
56?///<param?name="argValue">存儲值</param>
57?///<returns></returns>
58?publicboolAdd(stringargKey,?objectargValue)
59?{
60?returnclient.Add(argKey,argValue);
61?}
62?
63?///<summary>
64?///添加緩存數據
65?///</summary>
66?///<param?name="argKey">鍵值</param>
67?///<param?name="argValue">存儲值</param>
68?///<param?name="argDateExpiration">過期時間</param>
69?///<returns></returns>
70?publicboolAdd(stringargKey,?objectargValue,?DateTime?argDateExpiration)
71?{
72?returnclient.Add(argKey,?argValue,?argDateExpiration);
73?}
74?
75?///<summary>
76?///添加緩存數據
77?///</summary>
78?///<typeparam?name="T">存儲對象類型</typeparam>
79?///<param?name="argKey">鍵值</param>
80?///<param?name="entity">存儲值</param>
81?///<returns></returns>
82?publicboolAdd<T>(stringargKey,?T?entity)?whereT?:?class
83?{
84?returnclient.Add(argKey,?entity);
85?}
86?
87?///<summary>
88?///添加緩存數據
89?///</summary>
90?///<typeparam?name="T">存儲對象類型</typeparam>
91?///<param?name="argKey">鍵值</param>
92?///<param?name="entity">存儲值</param>
93?///<param?name="argDateExpiration">過期時間</param>
94?///<returns></returns>
95?publicboolAdd<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class
96?{
97?returnclient.Add(argKey,?entity,?argDateExpiration);
98?}
99?
100?///<summary>
101?///添加緩存數據,如果存在則替換原有數據
102?///</summary>
103?///<param?name="argKey">鍵值</param>
104?///<param?name="argValue">存儲值</param>
105?///<returns></returns>
106?publicboolSet(stringargKey,?objectargValue)
107?{
108?if(ContainKey(argKey))
109?{
110?returnfalse;
111?}
112?returnclient.Set(argKey,?argValue);
113?}
114?
115?///<summary>
116?///添加緩存數據,如果存在則替換原有數據
117?///</summary>
118?///<param?name="argKey">鍵值</param>
119?///<param?name="argValue">存儲值</param>
120?///<param?name="argDateExpiration">過期時間</param>
121?///<returns></returns>
122?publicboolSet(stringargKey,?objectargValue,?DateTime?argDateExpiration)
123?{
124?if(ContainKey(argKey))
125?{
126?returnfalse;
127?}
128?returnclient.Set(argKey,?argValue,?argDateExpiration);
129?}
130?
131?///<summary>
132?///添加緩存數據,如果存在則替換原有數據
133?///</summary>
134?///<typeparam?name="T">存儲對象類型</typeparam>
135?///<param?name="argKey">鍵值</param>
136?///<param?name="entity">存儲值</param>
137?///<returns></returns>
138?publicboolSet<T>(stringargKey,?T?entity)?whereT?:?class
139?{
140?if(ContainKey(argKey))
141?{
142?returnfalse;
143?}
144?returnclient.Set(argKey,?entity);
145?}
146?
147?///<summary>
148?///添加緩存數據,如果存在則替換原有數據
149?///</summary>
150?///<typeparam?name="T">存儲對象類型</typeparam>
151?///<param?name="argKey">鍵值</param>
152?///<param?name="entity">存儲值</param>
153?///<param?name="argDateExpiration">過期時間</param>
154?///<returns></returns>
155?publicboolSet<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class
156?{
157?if(ContainKey(argKey))
158?{
159?returnfalse;
160?}
161?returnclient.Set(argKey,?entity,?argDateExpiration);
162?}
163?
164?
165?///<summary>
166?///替換原有緩存
167?///</summary>
168?///<param?name="argKey">鍵值</param>
169?///<param?name="argValue">存儲值</param>
170?///<returns></returns>
171?publicboolReplace(stringargKey,?objectargValue)
172?{
173?returnclient.Replace(argKey,argValue);
174?}
175?
176?///<summary>
177?///替換原有緩存
178?///</summary>
179?///<param?name="argKey">鍵值</param>
180?///<param?name="argValue">存儲值</param>
181?///<param?name="argDateExpiration">過期時間</param>
182?///<returns></returns>
183?publicboolReplace(stringargKey,?objectargValue,?DateTime?argDateExpiration)
184?{
185?returnclient.Replace(argKey,argValue,argDateExpiration);
186?}
187?
188?publicboolReplace<T>(stringargKey,?T?entity)?whereT?:?class
189?{
190?returnclient.Replace(argKey,entity);
191?}
192?
193?publicboolReplace<T>(stringargKey,?T?entity,?DateTime?argDateExpiration)?whereT?:?class
194?{
195?returnclient.Replace(argKey,?entity,argDateExpiration);
196?}
197?
198?publicobjectGet(stringargKey)
199?{
200?returnclient.Get(argKey);
201?}
202?
203?publicT?Get<T>(stringargKey)
204?{
205?T?entity=default(T);
206?entity?=(T)client.Get(argKey);
207?returnentity;
208?}
209?
210?publicboolRemove(stringargKey)
211?{
212?returnclient.Delete(argKey);
213?}
214?
215?publicboolRemove(stringargKey,?DateTime?argDateExpiration)
216?{
217?returnclient.Delete(argKey,argDateExpiration);
218?}
219?
220?publicboolRemove()
221?{
222?returnclient.FlushAll();
223?}
224?
225?publicboolRemove(ArrayList?servers)
226?{
227?returnclient.FlushAll(servers);
228?}
229?}
230?}?
上面的代碼沒有注釋,因為提交不了這么長的代碼,去掉了注釋。代碼大家可以看懂的,這里不做過多的講解。?
? 學習例子源碼下載?
轉載于:https://www.cnblogs.com/aaa6818162/archive/2011/04/20/2022305.html
總結
以上是生活随笔為你收集整理的缓存应用--Memcached分布式缓存简介(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 跨种族转门派多少钱啊?
- 下一篇: 2011年:签到已死?