分布式缓存系统Memcached简介与以及在.net下的实践(转)

缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。但是ASP.NET中的虽然已经可以实现对页面局部进行缓存,但还是不够灵活。此时Memcached或许是你想要的。

Memcached是什么?
Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。

Memcached能缓存什么?
通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。

Memcached快么?

非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)来均衡任何数量的打开链接,使用非阻塞的网络I/O, 对内部对象实现引用计数(因此,针对多样的客户端,对象可以处在多样的状态), 使用自己的页块分配器和哈希表, 因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。

Danga Interactive为提升Danga Interactive的速度研发了Memcached。目前,LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。而这 些,是由一个由web服务器和数据库服务器组成的集群完成的。Memcached几乎完全放弃了任何数据都从数据库读取的方式,同时,它还缩短了用户查看 页面的速度、更好的资源分配方式,以及Memcache失效时对数据库的访问速度。

Memcached的特点
Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。

Memcached的使用
Memcached服务器端的安装 (此处将其作为系统服务安装)
下载文件: memcached-win32-1.4.4-14-服务端安装
    1 解压缩文件到c:\memcached
   2 命令行输入 'c:\memcached\memcached.exe -d install'
    3 命令行输入 'c:\memcached\memcached.exe -d start' ,该命令启动 Memcached ,默认监听端口为 11211
通过 memcached.exe -h 可以查看其帮助
二   .NET memcached client library
   下载文件:https://sourceforge.net/projects/memcacheddotnet/

   下载文件2

   里面有.net1.1 和 .net2.0的两种版本 还有一个不错的例子。

三 应用

1 将Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll 等放到bin目录
2 引用Memcached.ClientLibrary.dll
3 代码

 

namespace Memcached.MemcachedBench
 {
     using System;
     using System.Collections;

     using Memcached.ClientLibrary;

     public class MemcachedBench
      {
          [STAThread]
         public static void Main(String[] args)
          {
             string[] serverlist = { "10.0.0.131:11211","10.0.0.132:11211"    
};

             //初始化池
              SockIOPool pool = SockIOPool.GetInstance();
              pool.SetServers(serverlist);

              pool.InitConnections = 3;
              pool.MinConnections = 3;
              pool.MaxConnections = 5;

              pool.SocketConnectTimeout = 1000;
              pool.SocketTimeout = 3000;

              pool.MaintenanceSleep = 30;
              pool.Failover = true;

              pool.Nagle = false;
              pool.Initialize();

             // 获得客户端实例
              MemcachedClient mc = new MemcachedClient();
              mc.EnableCompression = false;

              Console.WriteLine("------------测   试-----------");
              mc.Set("test", "my value");  //存储数据到缓存服务器,这里将字符串"my value"缓存,key 是"test"

             if (mc.KeyExists("test"))   //测试缓存存在key为test的项目
              {
                  Console.WriteLine("test is Exists");
                  Console.WriteLine(mc.Get("test").ToString());  //在缓存中获取key为test的项目
              }
             else
              {
                  Console.WriteLine("test not Exists");
              }

              Console.ReadLine();

              mc.Delete("test");  //移除缓存中key为test的项目

             if (mc.KeyExists("test"))
              {
                  Console.WriteLine("test is Exists");
                  Console.WriteLine(mc.Get("test").ToString());
              }
            else
              {
                  Console.WriteLine("test not Exists");
              }
              Console.ReadLine();
            
              SockIOPool.GetInstance().Shutdown();  //关闭池, 关闭sockets
          }
     }
}

 

   

   是个不错的东西 ,使用起来也很方便,php ,ruby 的项目中用这个的很多,但是.net项目中用的较少(恕俺孤陋寡闻) 。希望有兴趣的朋友们 多多交流 。

 

 

=============================================

补充:MemCatch基础原理

Socket 服务器端
数据:键值对存储
内存处理的算法:
•本质就是一个大的哈希表。key最大长度是255个字符。
•内存模型:Memcache预先将可支配的内存空间进行分区(Slab),每个分区里再分成多个块(Chunk)大小1MB,但同一个分区里:块的长度(bytes)是固定的。
•插入数据:查找适合自己长度的块,然后插入,会有内存浪费。
•LRU,闲置>过期  >最少访问    
•惰性删除:它并没有提供监控数据过期的机制,而是惰性的,当查询到某个key数据时,如果过期那么直接抛弃。
l集群搭建原理:
•Memcache服务器端并没有提供集群功能,但是通过客户端的驱动程序实现了集群配置。
•客户端实现集群的原理:首先客户端配置多台集群机器的ip和端口的列表。然后客户端驱动程序在写入之前,首先对key做哈希处理得到哈希值后对总的机器的个数进行取余然后就选择余数对应的机器。

 Windows下使用Memcache

l下载Memcache:http://code.jellycan.com/Memcache/
l将服务程序拷贝到一个磁盘上的目录
l安装服务:cmd→Memcached.exe -d install 打开服务监控窗口可以查看服务是否启动。
l启动服务:cmd→Memcached.exe -d start(restart重启,stop关闭服务)
l检查服务是否启动:连接到Memcache控制台:telnet ServerIP 11211  输入命令:stats检查当前服务状态。
l卸载服务:Memcached.exe -d uninstall(先关闭服务)
l遇到问题:win8下安装服务。无法启动此程序,因为计算机中丢失 MSVCR71.dll。尝试重新安装该程序以解决此问题。下载dll地址:http://www.dll-files.com/dllindex/dll-files.shtml?msvcr71
 
 
 
 

MemcacheHelper

public static class MemCacheHelper
    {
        private static MemcachedClient mc;
        static MemCacheHelper()
        {
            string[] serverlist = { "192.168.3.2:11211", "10.0.0.132:11211" };//写配置文件中
            //初始化池
            SockIOPool pool = SockIOPool.GetInstance();
            pool.SetServers(serverlist);
 
            pool.InitConnections = 3;
            pool.MinConnections = 3;
            pool.MaxConnections = 5;
 
            pool.SocketConnectTimeout = 1000;
            pool.SocketTimeout = 3000;
 
            pool.MaintenanceSleep = 30;
            pool.Failover = true;
 
            pool.Nagle = false;
            pool.Initialize();
 
            // 获得客户端实例
            mc = new MemcachedClient();
            mc.EnableCompression = false;
        }

        /// <summary>
        /// 获取缓存中的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static object Get(string key)
        {
            return mc.Get(key); 
        }

        /// <summary>
        /// 向缓存中插入值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public static void Insert(string key,object value)
        {
            mc.Set(key, value);
        }
 
        /// <summary>
        /// 向缓存中插入值
        /// 设置过期时间
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="datetime">过期时间</param>
        public static void Insert(string key, object value, DateTime datetime)
        {
            mc.Set(key, value, datetime);
        }
        /// <summary>
        /// 删除缓存中的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Delete(string key)
        {
            if (mc.KeyExists(key))
            {
                return mc.Delete(key);
            }
            return false;
        }            
View Code

 

在配置configuration文件中添加节点:

<appSettings>
  <add key="Test" value="Test"/>
</appSettings>

Cookie+Memcache模拟Session保持登录状态

l创建登陆页面
l使用Memcache记录登录用户信息
l用Cookie模拟登录用户的会话
l用户登录成功之后,在往客户端写入一个cookie信息【生成一个会话id】来标识当前用户对应的会话信息。然后后续的所有的请求过来时候,从cookie中读取会话相关的id,然后在memcache中查找对应数据,如果为空那么就是没有登录或者会话超时了。如果不为空那么表示用户已经登录。

调用方法:

 

/// <summary>
/// 使用Memcache代替Session解决数据在不同Web服务器之间共享的问题。
/// </summary>
/// <param name="userName"></param>
public void MemcacheRespCookies(string userName)
{
    string sessionId = Guid.NewGuid().ToString();//作为Memcache的key
    Common.MemcacheHelper.Set(sessionId, Common.SerializerHelper.SerializeToString(userName), DateTime.Now.AddMinutes(20));//使用Memcache代替Session解决数据在不同Web服务器之间共享的问题。
    Response.Cookies[LOGINUSER].Value = sessionId;//将Memcache的key以cookie的形式返回到浏览器端的内存中,当用户再次请求其它的页面请求报文中会以Cookie将该值再次发送服务端。
}

 

 

总结的不错  有些文件也是可以下载的

分布式缓存 memcache学习 

高性能文件缓存key-value存储—Memcached

 

 

posted @ 2016-01-27 15:44  无恨星晨  阅读(230)  评论(0编辑  收藏  举报