博主喝口茶,一毛也是爱

收缩

C# Memcached 缓存使用方法

1692 人阅读
分类:

一、memcached是什么

MemCached是一种基于内存的key-value存储,用来存储小块的任意数据。实现原理就是,第一次从数据库获取到结果之后,同时将结果保存在内存中,从而简单对数据库的访问次数,以提高Web应用的速度。

14.png

二、memcached安装:

1、下载memcached文件 给出链接 http://download.csdn.net/download/jx_521/10022727

2、解压将对应memcached.exe 版本放入到文件夹内(F:\memcached.exe)

3、使用命令切换到memcached.exe目录下 cd F:\

4、memcached.exe -d install

5、memcached.exe -d start 启动服务

6、在服务器上开启端口 11211 (防火墙里添加入站规则,如果是本机则不需要设置)


MemCache常用的几条命令:

安装:memcache.exe -d install

卸载:memcache.exe -d unstall

启动:memcache.exe -d start

停止:memcache.exe -d stop


memcache的默认端口是11211,默认内存大小是64M,如果需要修改这二项参数使用下面这条命令:

memcache.exe -p 10000 -m 512 -d start

详细参数:

-p 监听的端口

-l 连接的IP地址, 默认是本机

-d start 启动memcached服务

-d restart 重起memcached服务

-d stop|shutdown 关闭正在运行的memcached服务

-d install 安装memcached服务

-d uninstall 卸载memcached服务

-u 以的身份运行 (仅在以root运行的时候有效)

-m 最大内存使用,单位MB。默认64MB

-M 内存耗尽时返回错误,而不是删除项

-c 最大同时连接数,默认是1024

-f 块大小增长因子,默认是1.25

-n 最小分配空间,key+value+flags默认是48

-h 显示帮助


安装完成之后服务里就可以看到

13.png


三、.net中使用Memcached(添加控制台应用程序)

1、添加Dll

 Enyim.Caching.dll

 MemcachedProviders.dll

 log4net.dll

2、修改配置文件

<configuration>
  <configSections>
    <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
  </configSections>

  <memcached>
    <servers>
      <!-- 注意这里写你自己的IP地址和端口号(memcached端口号默认11211)-->
      <add address="192.168.1.0" port="11211" />
    </servers>
    <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
  </memcached>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
</configuration>

3、添加缓存类 MemCached.cs

public class MemCached
{
    private static MemcachedClient oMemCached;

    static MemCached()
    {
        MemcachedClientSection oServersSection = (MemcachedClientSection)ConfigurationManager.GetSection("memcached");
        MemcachedClientConfiguration oMemConfig = new MemcachedClientConfiguration();
        foreach (IPEndPoint server in oServersSection.Servers.ToIPEndPointCollection())
        {
            oMemConfig.Servers.Add(server);
        }

        oMemCached = new MemcachedClient(oMemConfig);
    }

    public static long DefaultExpireTime = TimeSpan.TicksPerHour;
    public static string KeySuffix { get; set; }

    public static bool Add(string strKey, object objValue)
    {
        return oMemCached.Store(StoreMode.Set, strKey, objValue);
    }

    public static bool Add(string strKey, object objValue, bool bDefaultTimeSpan)
    {
        //var vTimeSpan = TimeSpan.FromMilliseconds(DefaultExpireTime);
        return Add(strKey, objValue, 480 * 60 * 1000);
    }

    public static bool Add(string strKey, object objValue, long lNumofMilliSeconds)
    {
        return oMemCached.Store(StoreMode.Set, strKey, objValue, DateTime.Now.AddMilliseconds(lNumofMilliSeconds));
    }

    public static bool Add(string strKey, object objValue, TimeSpan tspan)
    {
        return oMemCached.Store(StoreMode.Set, strKey, objValue, tspan);
    }

    public static IDictionary<string, object> Get(params string[] keys)
    {
        Dictionary<string, object> dictObjects = new Dictionary<string, object>();
        foreach (string key in keys)
        {
            dictObjects.Add(key, oMemCached.Get(key));
        }
        return dictObjects;
    }

    public static T Get<T>(string strKey)
    {
        return oMemCached.Get<T>(strKey);
    }

    public static object Get(string strKey)
    {
        return oMemCached.Get(strKey);
    }
    public static T GetCache<T>(string key, Func<T> fun)
    {
        T value = Get<T>(key);
        if (value == null)
        {
            value = fun.Invoke();
            Add(key, value);
        }
        return value;
    }
    public static IDictionary<string, object> Get(IEnumerable<string> keys)
    {
        return oMemCached.Get(keys);
    }

    public static bool Remove(string strKey)
    {
        return oMemCached.Remove(strKey);
    }

    public static void RemoveAll()
    {
        oMemCached.FlushAll();
    }
}

4.调用

调用Get方法

static void Main(string[] args)
{
	//获取缓存
    object ob = MemCached.Get("hello");

    if (ob == null)
    {
    	//添加缓存
        MemCached.Add("hello", getHi(1230));

        ob = MemCached.Get("hello");
    }
    Console.WriteLine(ob);
    Console.ReadKey();
}
private static string getHi(int id)
{
    return "hello_" + id;
}

调用GetCache方法

static void Main(string[] args)
{
    string obCache = MemCached.GetCache<string>("hello", () => getHi(1230));
    Console.WriteLine(obCache);
    Console.ReadKey();

}
private static string getHi(int id)
{
    return "hello_" + id;
}

很明显使用委托之后代码很简洁,判断缓存是否存在的方法被封装起来了

四、memcached 分布式原理

memcached不相互通信,那么memcached是如何实现分布式的呢?memcached的分布式实现主要依赖客户端的实现:

15.jpg

memcached分布式

如上图所示,我们看下缓存的存储的一般流程:

当数据到达客户端,客户端实现的算法就会根据“键”来决定保存的memcached服务器,服务器选定后,命令他保存数据。取的时候也一样,客户端根据“键”选择服务器,使用保存时候的相同算法就能保证选中和存的时候相同的服务器。


余数计算分散法

余数计算分散法是memcached标准的memcached分布式方法,算法如下:

CRC($key)%N

该算法下,客户端首先根据key来计算CRC,然后结果对服务器数进行取模得到memcached服务器节点,对于这种方式有两个问题值得说明一下:

1.当选择到的服务器无法连接的时候,一种解决办法是将尝试的连接次数加到key后面,然后重新进行hash,这种做法也叫rehash。

2.第二个问题也是这种方法的致命的缺点,尽管余数计算分散发相当简单,数据分散也很优秀,当添加或者移除服务器的时候,缓存重组的代价相当大。


Consistent Hashing算法

Consistent Hashing算法描述如下:首先求出memcached服务器节点的哈希值,并将其分配到0~2^32的圆上,这个圆我们可以把它叫做值域,然后用同样的方法求出存储数据键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上,如果超过0~2^32仍找不到,就会保存在第一台memcached服务器上:

16.jpg

再抛出上面的问题,如果新添加或移除一台机器,在consistent Hashing算法下会有什么影响。上图中假设有四个节点,我们再添加一个节点叫node5:

17.jpg

添加了node节点之后

node5被放在了node4与node2之间,本来映射到node2和node4之间的区域都会找到node4,当有node5的时候,node5和node4之间的还是找到node4,而node5和node2之间的此时会找到node5,因此当添加一台服务器的时候受影响的仅仅是node5和node2区间。


和博主交个朋友吧
    发布篇幅
    • 文章总数:0
    • 原创:0
    • 转载:0
    • 译文:0
    文章分类
      文章存档
      阅读排行