memcached高性能的分佈式的內存對象緩存系統

memcached是一個高性能的分佈式的內存對象緩存系統。目前全世界不少人使用這個緩存項目來構建自己大負載的網站,來分擔數據庫的壓力,通過在內存中維護一個統一的巨大的hash表,它能夠用來存儲各種格式的數據,如圖像,視頻,文件以及數據庫檢索的結果等。簡單地說就是將數據調用到內存中,然後從內存中讀取,從而大大提高讀取速度。默認啓用11211端口,64M內存。



根據id查詢某條新聞的三種方案:
1.每次都從數據庫中查詢
2.頁面靜態化,把每一條新聞生成一個靜態的.html文件(雖然速度快了些,但是仍然是從磁盤文件獲取,速度還是慢)
3.把數據放入Memcatched緩存中

對於大型網站來說主要考慮併發性,對於中小型網站,平均日訪問量不高的網站頁面靜態化已經足夠。
網站數據讀取速度:
數據庫直接查詢<頁面靜態化後的文件查詢<內存查詢,這裏的充分是以空間(即內存)換時間


Memcatched的原理圖:

安裝步驟:
①下載memcached軟件,安裝memcached Server服務
②將memcached軟件拷貝到某個目錄
③安裝  memcached –d install [卸載使用 memcached -d uninstall]
④啓動 memcached 服務 memcached -d start [如果你的網站,需要的memcached 的內存大於64m,應當這樣啓動memcached –m 256m –d start][如果你希望換一個端口memcached -d -m 30 -l 127.0.0.1 -p 9000 -d start]
  控制面板  管理工具  服務
  (1)直接通過界面啓動該服務
  (2)在控制檯下啓動 memcached –d start   [命令一覽表]
⑤查看memcached 服務是否啓動成功! 默認端口11211,netstat -anb

c#操作Memcached:
1. 將Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll放到bin目錄 
2. 引用Memcached.ClientLibrary.dll 
3. 類中引用using Memcached.ClientLibrary; 

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string[] serverlist = { "192.168.1.7:11211","192.168.1.100:11211" };
            
            //初始化池
            SockIOPool pool = SockIOPool.GetInstance();
            //設置連接池可用的cache服務器列表,server的構成形式是IP:PORT(如:127.0.0.1:11211)
            pool.SetServers(serverlist);

            //初始連接數
            pool.InitConnections = 3;
            //最小連接數
            pool.MinConnections = 3;
            //最大連接數            
            pool.MaxConnections = 5;

            //設置的套接字超時時間
            pool.SocketConnectTimeout = 1000;
            //套接字的讀取超時時間
            pool.SocketTimeout = 60;

            //設置維護線程運行的睡眠時間。如果設置爲0,那麼維護線程將不會啓動,30就是每隔30秒醒來一次
            pool.MaintenanceSleep = 30;
            //獲取或設置池的故障標誌,如果這個標誌被設置爲true則socket連接失敗,Memcached將試圖從另一臺服務器返回一個套接字(如果存在的話);如果設置爲false,則得到一個套接字如果存在的話。否則返回NULL,如果它無法連接到請求的服務器。
            pool.Failover = true;

            //如果爲false,對所有創建的套接字關閉Nagle的算法
            pool.Nagle = false;
            pool.Initialize();

            //獲得客戶端實例
            MemcachedClient mc = new MemcachedClient();
            //是否啓用壓縮
            mc.EnableCompression = false;
            Console.WriteLine("-------------------------測試-------------------------------------");
            
            //增加操作,如果鍵值存在則不能加入
            mc.Add("name", "xiaoming",DateTime.Now.AddSeconds(30));//字符串
            mc.Add("age", 23);//數字

            string[] strs = { "a", "b", "c" };            
            mc.Add("arr", strs);//加入數組

            mc.Add("gender", true);//布爾值

            Person person = new Person() { Name = "ac", Age = 33, Email = "[email protected]" };
            mc.Add("ren", person);//加入對象

            //修改操作
            mc.Set("name", "xm");

            //查詢操作
            Console.WriteLine(mc.Get("name"));
            Console.WriteLine(mc.Get("age"));
            object obj = mc.Get("arr");
            Console.WriteLine(mc.Get("gender"));//返回True

            Person model = mc.Get("ren") as Person;
            Console.WriteLine(model.Name);
            //刪除操作
            mc.Delete("name");
            //刪除所有
            mc.FlushAll();

            Console.ReadKey();
        }

        private static void CheckKey(MemcachedClient mc)
        {
            if (mc.KeyExists("zengzhiwei"))
            {
                Console.WriteLine("zengzhiwei is Exists");
                Console.WriteLine(mc.Get("zengzhiwei").ToString());
            }
            else
            {
                mc.Add("liudehua", DateTime.Now);
                Console.WriteLine("zengzhiwei not Exists");
            }
        }
    }

    [Serializable]
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Email { get; set; }

        public void SayHello()
        {
            Console.WriteLine("大家好!");
        }
    }


Memcached的機制:
1.是c/s結構,使用簡單文本通訊(memcached爲服務器端,memcached的服務器客戶端通信並不使用XML等格式,而使用簡單的基於文本行的協議。因此,通過telnet也能在memcached上保存數據、取得數據)
2.基於libevent處理併發(libevent是一套跨平臺的事件處理接口的封裝,使用libevent來進行網絡併發連接的處理,能夠保持在很大併發情況下,仍舊能夠保持快速的響應能力)
3.是內存緩存(memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啓memcached、重啓操作系統會導致全部數據消失。另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached本身是爲緩存而設計的服務器,因此並沒有過多考慮數據的永久性問題。)
4.基於客戶端的分佈式,各個memcached之間不通訊(memcached儘管是“分佈式”緩存服務器,但服務器端並沒有分佈式功能。各個memcached不會互相通信以共享信息。那麼,怎樣進行分佈式呢?這完全取決於客戶端的實現。)

Memcached的細節:
1.生命週期是在add數據的時候指定的。
2.配置
緩存工具類
public static class CacheHelper
    {
        //單例模式保證進程內實例唯一
        private static readonly SockIOPool sockIoPool;
        public static SockIOPool CurrentPool
        {
            get
            {
                return sockIoPool;
            }
        }

        public static MemcachedClient memcacedClient { get; set; }
        static CacheHelper()
        {
            sockIoPool = SockIOPool.GetInstance();
            var appSetList = ConfigurationManager.AppSettings["MemcachedList"];
            var setArr = appSetList.Split(',');

            CurrentPool.SetServers(setArr);
            CurrentPool.Initialize();

            memcacedClient = new MemcachedClient();
            memcacedClient.EnableCompression = false;
        }

        /// <summary>
        /// 往分佈式緩存中寫內容
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static bool SetCache(string key, object value, DateTime dt)
        {
            if (!memcacedClient.KeyExists(key))
            {
                return memcacedClient.Add(key, value, dt);
            }
            else
            {
                return memcacedClient.Set(key, value, dt);
            }
        }

        /// <summary>
        /// 從分佈式緩存中讀取內容
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object GetCache(string key)
        {
            if (!memcacedClient.KeyExists(key))
            {
                return null;
            }
            else
            {
                return memcacedClient.Get(key);
            }
        }

    }


Memcached的安全性:
windows下設置防火牆後,外界不能直接操作Memcached而是通過網站提供的對外接口訪問

如何使用memcached?
1.如果是一個小網站,pv值不大,就不考慮使用memcached了
2.變化頻繁, 一變化就要入庫[比如股票,金融.](不適合memcached)
3.過大的數據不能放入到memcache(優酷網.受帶寬的影響限制了訪問速度,所以使用memcached沒有意義)
4.變化頻繁,查詢頻繁,但是不一定寫入數據庫(比如用戶在線狀態、在線人數..適合memcached)
5.變化不頻繁,查詢頻繁,不管入不入庫,都比較適合memcached。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章