Memcached介紹
Memcached 是以LiveJournal
旗下Danga Interactive 公司的Brad Fitzpatric 為首開發的一款軟體。在通常的應用中我們都會將資料保存到資料庫中,每次需要的時候都會從資料庫去查詢這些資料,如果應用程式的使用者很多就會出現大量併發訪問資料庫的情況,這樣就會增加應用程式的回應時間,使用Memcached就可以有效解決這個問題。memcached是高性能的分散式記憶體緩存伺服器。一般的使用目的是,通過緩存資料庫查詢結果,減少資料庫訪問次數,以提高動態Web應用的速度、提高可擴展性。像大名鼎鼎的Facebook網站就使用了Memcached。稍後會提供Windows平臺上32位和64位元的Memcached程式。
為了提高性能,Memcached中的資料都保存在Memcached內置的存儲空間中。因為當Memcached重啟會導致其中的資料全部丟失,所以一般的方案是將資料保存在資料庫中,每次請求資料的時候先查看在Memcached有沒有緩存,如果有就直接從緩存中取出資料;如果沒有,就從資料庫中取出資料返回給應用程式並將請求的資料緩存到Memcached中,這樣一來下次請求相同的資料就可以直接從Memcached中讀取而不用再去查資料庫了;一旦對資料有更新,同時更新資料庫和Memcached。
Memcached是一個命令列視窗程式,可以在命令列視窗中啟動也可以封裝在系統服務中啟動。在啟動Memcached時需要提供一些必須的參數,指定Memcached運行時監聽的埠和最大使用的記憶體大小等。如果緩存的資料大小超過指定記憶體,那麼Memcached就會按照LRU(Least Recently Used)演算法自動“刪除”不使用的緩存(標記為失效),新增的緩存資料就可以使用這些標記為失效的資料所佔用的記憶體,這樣就不用擔心Memcached超出所指定記憶體的問題。此外,為了提高性能,在緩存資料過期後Memcached並不是從實體記憶體中刪除緩存的資料,僅僅在取出改資料的時候檢查它是否已經過了有效期。
目前有多種平臺的Memcached版本,比如Linux、FreeBSD、Solaris
(memcached 1.2.5以上版本)、Mac OS X及Windows平臺,在Windows平臺上還有32位和64位版本。
Memcached有一套協定,利用這套協定可以對Memcached進行資料存取和查看Memcached的狀態,很多程式語言都依據這套協議來操作Memcached,比如PHP、Java、C、C++及C#等。
獲取了對應平臺的Memcached版本就可以運行Memcached了。在這裡僅以Windows平臺上的32位Memcached為例。
運行Memcached:
memcached.exe -p 11121 -m 64
上面的命令是運行Memcached,指定它的監聽埠是11121(這是它的默認埠,可以指定為其它大於1024的埠,因為小於1024的埠已經有了預設指定),最大使用記憶體為64m,如果啟用了Windows防火牆,切記要在防火牆上打開這個埠。
在偵錯工具時可以使用下面的命令列來運行:
memcached.exe -p 11121 -m 64 -vv
這樣就會看到如下的結果:
slab class
1: chunk size 88 perslab 11915
slab class
2: chunk size 112 perslab 9362
slab class
3: chunk size 144 perslab 7281
slab class
4: chunk size 184 perslab 5698
slab class
5: chunk size 232 perslab 4519
slab class
6: chunk size 296 perslab 3542
slab class
7: chunk size 376 perslab 2788
slab class
8: chunk size 472 perslab 2221
slab class
9: chunk size 592 perslab 1771
slab class
10: chunk size 744 perslab 1409
slab class
11: chunk size 936 perslab 1120
slab class
12: chunk size 1176 perslab 891
slab class
13: chunk size 1472 perslab 712
slab class
14: chunk size 1840 perslab 569
slab class
15: chunk size 2304 perslab 455
slab class
16: chunk size 2880 perslab 364
slab class
17: chunk size 3600 perslab 291
slab class
18: chunk size 4504 perslab 232
slab class
19: chunk size 5632 perslab 186
slab class
20: chunk size 7040 perslab 148
slab class
21: chunk size 8800 perslab 119
slab class
22: chunk size 11000 perslab 95
slab class
23: chunk size 13752 perslab 76
slab class
24: chunk size 17192 perslab 60
slab class
25: chunk size 21496 perslab 48
slab class
26: chunk size 26872 perslab 39
slab class
27: chunk size 33592 perslab 31slab class 28: chunk size 41992 perslab 24
slab class 29: chunk size 52496 perslab 19
slab class 30: chunk size 65624 perslab 15
slab class 31: chunk size 82032 perslab 12
slab class 32: chunk size 102544 perslab 10
slab class 33: chunk size 128184 perslab 8
slab class 34: chunk size 160232 perslab 6
slab class 35: chunk size 200296 perslab 5
slab class 36: chunk size 250376 perslab 4
slab class 37: chunk size 312976 perslab 3
slab class 38: chunk size 391224 perslab 2
slab class 39: chunk size 489032 perslab 2
<96 server listening
<112 server listening
<116 send buffer was 8192, now 268435456
<116 server listening (udp)
在用戶端還可以通過telnet來查看和操作Memcached,前提是伺服器端和用戶端都支援Telnet協定,在Windows7和Windows2008中預設都不支援,需要在控制台中安裝和啟用。
首先打開控制台,然後點擊“打開或關閉Windows功能”,如下圖所示:
點擊“打開或關閉Windows功能”之後會看到當前系統啟用的功能的狀態,根據當前機器選擇打開Telnet伺服器端或者用戶端功能,如下圖所示:
經過上面的操作之後就可以在客服端遠端查看Memcached的狀態或者操作Memcached了。下面的命令就是連接到Memcached:
telnet localhost 11121
連接之後會出現一個命令列視窗,在這個命令列視窗中輸入"stats"就可以看到當前Memcached的狀態,如下就是剛剛啟動的Memcached的狀態資料:
STAT pid 852
STAT uptime 1399
STAT time 1300979378
STAT version 1.2.5
STAT pointer_size 32
STAT curr_items 0
STAT total_items 0
STAT bytes 0
STAT curr_connections 3
STAT total_connections 5
STAT connection_structures 4
STAT cmd_get 0
STAT cmd_set 0
STAT get_hits 0
STAT get_misses 0
STAT evictions 0
STAT bytes_read 23
STAT bytes_written 415
STAT limit_maxbytes 67108864
STAT threads 1
END
通過這個資料我們就可以瞭解Memcached的狀態了。
這些資料所代表的意義如下:
pid:32u,伺服器進程ID。
uptime:32u, 伺服器執行時間,單位秒。
time :32u, 伺服器當前的UNIX時間。
version :string, 伺服器的版本號。
curr_items :32u, 伺服器當前存儲的內容數量 Current number of items stored by the server
total_items :32u, 伺服器啟動以來存儲過的內容總數。
bytes :64u, 伺服器當前存儲內容所佔用的位元組數。
curr_connections :32u, 連接數量。
total_connections :32u, 伺服器運行以來接受的連接總數。
connection_structures:32u, 伺服器分配的連接結構的數量。
cmd_get :32u, 取回請求總數。
cmd_set :32u, 存儲請求總數。
get_hits :32u, 請求成功的總次數。
get_misses :32u, 請求失敗的總次數。
bytes_read :64u, 伺服器從網路讀取到的總位元組數。
bytes_written :64u, 伺服器向網路發送的總位元組數。
limit_maxbytes :32u, 伺服器在存儲時被允許使用的位元組總數。
上面的描述中32u和64u表示32位和64位不帶正負號的整數,string表示是string類型資料。
在.NET中應用Memcached
有很多.NET版本的Memcached用戶端程式,在這裡周公使用的Enyim Memcached,可以到https://github.com/enyim/EnyimMemcached/下載最新的版本。
要想在專案中使用Memcached,需要添加對Enyim.Caching.dll的應用。除此之外,我們可能還需要在config檔中配置Memcached的資訊(也可以在程式碼中指定,但那樣不靈活),如下就是一個config檔配置的例子:
如果我們配置了多個Memcached的實例,可以想上面的注釋部分那樣在 節點下添加多個Memcached的實例配置。
這裡需要說明的是如果我們需要向Memcached中添加自訂資料類型時,我們需要將該資料類型添加上[Serializable]標記。
下面是一個Enyim Memcached的例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Enyim.Caching;
using Enyim.Caching.Memcached;
/*
* 日期:2011-03-24
* 原文出處:http://blog.csdn.net/zhoufoxcn 或http://zhoufoxcn.blog.51cto.com
* 版權說明:本文可以在保留原文出處的情況下使用於非商業用途,對此不作任何擔保或承諾。
* */
namespace MemcachedMonitor
{
[Serializable]
public class Person
{
public int UserId { get; set; }
public string UserName { get; set; }
}
public class MemcachedDemo
{
private static MemcachedClient client = new
MemcachedClient("enyim.com/memcached");
public void SetDemo()
{
Person person = new Person { UserId = 1, UserName = "李剛" };
//不帶過期時間的存儲,Memcached將根據LRU來決定過期策略
bool success=client.Store(StoreMode.Add, person.UserName, person);
//帶過期時間的緩存
//bool success = client.Store(StoreMode.Add, person.UserName, person, DateTime.Now.AddMinutes(10));
Console.WriteLine("存儲[{0}]的結果:{1}", person.UserName, success);
}
public void GetDemo()
{
Person person = client.Get(" 李剛");
if (person != null)
{
Console.WriteLine("取回[{0}]的結果——UserId:{1},UserName:{2}", "李剛",
person.UserId, person.UserName);
}
else
{
Console.WriteLine("取回[{0}]失敗!", "李剛");
}
}
public void MultiGetDemo()
{
List personNameList = new List();
for (int i = 0; i < 10; i++)
{
personNameList.Add("李剛00" + i);
}
//批量獲取,只通過一次網路通訊就取回所有personNameList中的指定的所有資料
IDictionary resultList = client.Get(personNameList);
Person person;
foreach (KeyValuePair item in resultList)
{
person = item.Value as Person;
if (person != null)
{
Console.WriteLine("取回[{0}]的結果——UserId:{1},UserName:{2}", "李剛", person.UserId, person.UserName);
}
else
{
Console.WriteLine("取回[{0}]失敗!", "李剛");
}
}
}
}
}
說明:如果需要一次從Memcached中取回多個緩存的資料,可以參考MultiGetDemo()方法,這樣一來只需要一次網路通訊就可以取回全部資料,減少網路連線時間。此外,在Memcached用戶端可以使用Text或者Binary協定,經過周公千萬次測試比較,使用Binary協定性能略高於使用Text協定。在上面的config檔中周公就配置使用了Binary協定。
總結,使用Memcached這樣的分散式緩存可以大大提高應用程式的性能,經過周公測試,正確使用Memcached可以將單台伺服器的併發訪問數從20提高到1000左右,也就是提高了50倍,這是一個相當客觀的提升!限於篇幅,關於Memcached的更深更詳細的用法沒有在本篇介紹,此文算作抛磚引玉,讀者可以自行參考其它相關資料。
本文出自 http://zhoufoxcn.blog.51cto.com/792419/528212
沒有留言:
發佈留言