Memcached,你懂的

1、Memcached簡介數據庫

Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。windows

目前有多種平臺的Memcached版本,好比Linux、FreeBSD、Solaris 、Mac OS X及Windows平臺。緩存

可在官網下載到最新版本: http://memcached.org/ (LINUX) 。安全

這裏,官網上好像沒有找到Memcached for windows
咱們安裝Windows版原本演示。socket

32bit:下載 memcached-win32-1.4.4-14.zip分佈式

64bit:若是須要win64版,下載 memcached-win64-1.4.4-14.zipmemcached

2、安裝和啓動函數

首先,我解壓文件路徑
D:\Memcached\Memcached32性能

 

安裝命令
以管理員身份運行 cmd.exe網站

進入到解壓文件
D:\>cd Memcached\Memcached32

安裝
D:\Memcached\Memcached32>memcached.exe -d install

啓動
D:\Memcached\Memcached32>memcached.exe -d start

 

OK,命令我們已經執行完了.怎麼才知道Memcached服務已經安裝成功並啓動了呢?

cmd  命令 services.msc

 

有時候,爲了方便起見,咱們也不能每次安裝,中止和啓動服務的時候都打開cmd命令框吧

常見的辦法是作成批處理命令,以下:

install.bat

memcached.exe -d install

start.bat

memcached.exe -d start

stop.bat

memcached.exe -d stop

unInstall.bat

memcached.exe -d uninstall

3、.net 項目中使用

筆者查閱了相關資料,發現有不少支持Memcached的客戶端,這裏因爲筆者的我的喜愛,

選擇了EnyimMemcached.2.13

能夠經過Nuget安裝

PM> Install-Package EnyimMemcached

 

筆者特地作了一個Demo來體驗一下,EnyimMemcached使用

首先,咱們要鏈接到這個分佈式數據庫服務,相似之前的關係型數據庫,這裏也是須要配置鏈接的,配置以下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="enyim.com">
      <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection,Enyim.Caching" />
    </sectionGroup>
    <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/>
  </configSections>
  <enyim.com>
    <memcached>
      <servers>
        <!-- put your own server(s) here-->
        <add address="127.0.0.1" port="11211" />
      </servers>
      <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
    </memcached>
  </enyim.com>
  <memcached keyTransformer="Enyim.Caching.TigerHashTransformer,Enyim.Caching">
    <servers>
      <add address="127.0.0.1" port="11211" />
    </servers>
    <socketPool minPoolSize="2" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
  </memcached>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

爲了方便使用,能夠再封裝一下,便於調用,

using Enyim.Caching;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace MemcachdDemo.Helper
{
    public sealed class MemCachedHelper
    {
        private static MemcachedClient MemClient;
        static readonly object padlock = new object();

        //線程安全的單例模式
        public static MemcachedClient getInstance()
        {
            if (MemClient == null)
            {
                lock (padlock)
                {
                    if (MemClient == null)
                    {
                        MemClientInit();
                    }
                }
            }
            return MemClient;
        }

        static void MemClientInit()
        {
            try
            {
                MemClient = new MemcachedClient();
                /*MemcachedClientConfiguration config = new MemcachedClientConfiguration();
                config.Servers.Add(new System.Net.IPEndPoint(IPAddress.Parse("127.0.0.1"), 11211));
                config.Protocol = MemcachedProtocol.Binary;
                //config.Authentication.Type = typeof(PlainTextAuthenticator);
                //config.Authentication.Parameters["userName"] = "memcache";
                //config.Authentication.Parameters["password"] = "password";
                MemClient = new MemcachedClient(config);*/
                /*MemcachedClientConfiguration config = new MemcachedClientConfiguration();
                //config.Servers.Add(new IPEndPoint("127.0.0.1", 11211));
                config.Servers.Add(new System.Net.IPEndPoint(IPAddress.Parse("127.0.0.1"), 11211));
                config.Protocol = MemcachedProtocol.Binary;
                config.Authentication.Type = typeof(PlainTextAuthenticator);
                config.Authentication.Parameters["userName"] = "username";
                config.Authentication.Parameters["password"] = "password";
                config.Authentication.Parameters["zone"] = "";

                MemClient = new MemcachedClient(config);*/
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region getAllKeys

        public static List<string> GetAllKeys(string ipString, int port)
        {
            List<string> allKeys = new List<string>();
            //var ipString = "127.0.0.1";
            //var port = 11211;

            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(new IPEndPoint(IPAddress.Parse(ipString), port));
            var slabIdIter = QuerySlabId(socket);
            var keyIter = QueryKeys(socket, slabIdIter);
            socket.Close();

            foreach (String key in keyIter)
            {
                if (!allKeys.Contains(key))
                    allKeys.Add(key);
            }

            return allKeys;
        }

        /// <summary>
        /// 執行返回字符串標量
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="command">命令</param>
        /// <returns>執行結果</returns>
        static String ExecuteScalarAsString(Socket socket, String command)
        {
            var sendNumOfBytes = socket.Send(Encoding.UTF8.GetBytes(command));
            var bufferSize = 0x1000;
            var buffer = new Byte[bufferSize];
            var readNumOfBytes = 0;
            var sb = new StringBuilder();

            while (true)
            {
                readNumOfBytes = socket.Receive(buffer);
                sb.Append(Encoding.UTF8.GetString(buffer));

                if (readNumOfBytes < bufferSize)
                    break;
            }

            return sb.ToString();
        }

        /// <summary>
        /// 查詢slabId
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <returns>slabId遍歷器</returns>
        static IEnumerable<String> QuerySlabId(Socket socket)
        {
            var command = "stats items STAT items:0:number 0 \r\n";
            var contentAsString = ExecuteScalarAsString(socket, command);

            return ParseStatsItems(contentAsString);
        }

        /// <summary>
        /// 解析STAT items返回slabId
        /// </summary>
        /// <param name="contentAsString">解析內容</param>
        /// <returns>slabId遍歷器</returns>
        static IEnumerable<String> ParseStatsItems(String contentAsString)
        {
            var slabIds = new List<String>();
            var separator = "\r\n";
            var separator2 = ':';
            var items = contentAsString.Split(separator, StringSplitOptions.RemoveEmptyEntries);

            for (Int32 i = 0; i < items.Length; i += 4)
            {
                var itemParts = items[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);

                if (itemParts.Length < 3)
                    continue;

                slabIds.Add(itemParts[1]);
            }

            return slabIds;
        }

        /// <summary>
        /// 查詢鍵
        /// </summary>
        /// <param name="socket">套接字</param>
        /// <param name="slabIdIter">被查詢slabId</param>
        /// <returns>鍵遍歷器</returns>
        static IEnumerable<String> QueryKeys(Socket socket, IEnumerable<String> slabIdIter)
        {
            var keys = new List<String>();
            var cmdFmt = "stats cachedump {0} 200000 ITEM views.decorators.cache.cache_header..cc7d9 [6 b; 1256056128 s] \r\n";
            var contentAsString = String.Empty;

            foreach (String slabId in slabIdIter)
            {
                contentAsString = ExecuteScalarAsString(socket, String.Format(cmdFmt, slabId));
                keys.AddRange(ParseKeys(contentAsString));
            }

            return keys;
        }

        /// <summary>
        /// 解析stats cachedump返回鍵
        /// </summary>
        /// <param name="contentAsString">解析內容</param>
        /// <returns>鍵遍歷器</returns>
        static IEnumerable<String> ParseKeys(String contentAsString)
        {
            var keys = new List<String>();
            var separator = "\r\n";
            var separator2 = ' ';
            var prefix = "ITEM";
            var items = contentAsString.Split(separator, StringSplitOptions.RemoveEmptyEntries);

            foreach (var item in items)
            {
                var itemParts = item.Split(separator2, StringSplitOptions.RemoveEmptyEntries);

                if ((itemParts.Length < 3) || !String.Equals(itemParts.FirstOrDefault(), prefix, StringComparison.OrdinalIgnoreCase))
                    continue;

                keys.Add(itemParts[1]);
            }

            return keys;
        }
    }

    /// <summary>
    /// String擴展函數
    /// </summary>
    static class StringExtension
    {
        /// <summary>
        /// 切割
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="separator">分隔符</param>
        /// <param name="options">選項</param>
        /// <returns>切割結果</returns>
        public static String[] Split(this String str, Char separator, StringSplitOptions options)
        {
            return str.Split(new Char[] { separator }, options);
        }

        /// <summary>
        /// 切割
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="separator">分隔符</param>
        /// <param name="options">選項</param>
        /// <returns>切割結果</returns>
        public static String[] Split(this String str, String separator, StringSplitOptions options)
        {
            return str.Split(new String[] { separator }, options);
        }

        #endregion

    }
}

由於EnyimMemcached幫咱們封裝的很好,剩下的就是調用了

private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                if (String.IsNullOrEmpty(this.txtKey.Text))
                {
                    MessageBox.Show("key不能爲空!");
                    return;
                }
                else
                {
                    var key = this.txtKey.Text.Trim();
                    var value = this.txtValue.Text.Trim();
                    var bRet = client.Store(StoreMode.Set, key.Trim(), txtValue.Text.Trim());
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

截圖以下

因爲是key-value存儲,查詢方法:

var value = mc.Get("name");

 

對於Memcached的安裝,啓動和基本使用,有了簡單的介紹,但願對你有用, 有用的話,請支持一下哈!

相關文章
相關標籤/搜索