建站学 - 轻松建站从此开始!

建站学-个人建站指南,网页制作,网站设计,网站制作教程

当前位置: 建站学 > 网站开发 > asp.net教程 >

Discuz!NT中集成Memcached分布式缓存

时间:2009-03-23 19:00来源: 作者: 点击:
大约在两年前我写过一篇关于Discuz!NT缓存架构的文章,在那篇文章的结尾介绍了在IIS中如果开启多个 应用程序池会造成多个缓存实例之间数据同步的问题。虽然给出了一个解决方案,但无形中却把压力转移到了 磁盘I/O上(多个进程并发访问cache.config文件)。其实从那时
      大约在两年前我写过一篇关于Discuz!NT缓存架构的文章,在那篇文章的结尾介绍了在IIS中如果开启多个
应用程序池会造成多个缓存实例之间数据同步的问题。虽然给出了一个解决方案,但无形中却把压力转移到了
磁盘I/O上(多个进程并发访问cache.config文件)。其实从那时起我就开始关注有什么更好的方案,当然今
天本文中所说的Memcached,以及Velocity等这类的分布式缓存方案之前都考虑过,但一直未能决定该使用那
个。起码Velocity要在.net 4.0之后才会提供,虽然是原生态,但有些远水解不了近火。

      我想真正等到Velocity能堪当重任还要等上一段时间。于是我就开始将注意力转移到了Memcached,必定
有Facebook这只“超级小白鼠”使用它并且反响还不错。所以就开始尝试动手在产品中集成Memcached。

      其实在之前的那篇关于Discuz!NT缓存架构的文章中已提到过,使用了设计模式中的“策略模式”来构造。
所以为了与以往使用缓存的代码格式相兼容,所以这里采用新添加MemCachedStrategy(MemCached策略)
来构造一个缓存策略类以便于当管理后台开启“MemCached”时以“MemCached策略模式”来做为当前系统默认
的策略模式。

    其代码段如下(Discuz.Cache/MemCached.cs):
    
/// <summary>
/// MemCache缓存策略类
/// </summary>
public class MemCachedStrategy : Discuz.Cache.ICacheStrategy
{

    
/// <summary>
    
/// 添加指定ID的对象
    
/// </summary>
    
/// <param name="objId"></param>
    
/// <param name="o"></param>
    public void AddObject(string objId, object o)
    {
        RemoveObject(objId);
        
if (TimeOut > 0)
        {
            MemCachedManager.CacheClient.Set(objId, o, System.DateTime.Now.AddMinutes(TimeOut));
        }
        
else
        {
            MemCachedManager.CacheClient.Set(objId, o);
        }
    }

    
/// <summary>
    
/// 添加指定ID的对象(关联指定文件组)
    
/// </summary>
    
/// <param name="objId"></param>
    
/// <param name="o"></param>
    
/// <param name="files"></param>
    public void AddObjectWithFileChange(string objId, object o, string[] files)
    {
        ;
    }

    
/// <summary>
    
/// 添加指定ID的对象(关联指定键值组)
    
/// </summary>
    
/// <param name="objId"></param>
    
/// <param name="o"></param>
    
/// <param name="dependKey"></param>
    public void AddObjectWithDepend(string objId, object o, string[] dependKey)
    {
        ;
    }

    
/// <summary>
    
/// 移除指定ID的对象
    
/// </summary>
    
/// <param name="objId"></param>
    public void RemoveObject(string objId)
    {
        
if (MemCachedManager.CacheClient.KeyExists(objId))
            MemCachedManager.CacheClient.Delete(objId);
    }

    
/// <summary>
    
/// 返回指定ID的对象
    
/// </summary>
    
/// <param name="objId"></param>
    
/// <returns></returns>
    public object RetrieveObject(string objId)
    {
        
return MemCachedManager.CacheClient.Get(objId);
    }

    
/// <summary>
    
/// 到期时间
    
/// </summary>
    public int TimeOut { setget; }
}

    

    上面类实现的接口Discuz.Cache.ICacheStrategy定义如下:
    
 
/// <summary>
 
/// 公共缓存策略接口
 
/// </summary>
 public interface ICacheStrategy
 {
     
/// <summary>
     
/// 添加指定ID的对象
     
/// </summary>
     
/// <param name="objId"></param>
     
/// <param name="o"></param>
     void AddObject(string objId, object o);

     
/// <summary>
     
/// 添加指定ID的对象(关联指定文件组)
     
/// </summary>
     
/// <param name="objId"></param>
     
/// <param name="o"></param>
     
/// <param name="files"></param>
     void AddObjectWithFileChange(string objId, object o, string[] files);

     
/// <summary>
     
/// 添加指定ID的对象(关联指定键值组)
     
/// </summary>
     
/// <param name="objId"></param>
     
/// <param name="o"></param>
     
/// <param name="dependKey"></param>
     void AddObjectWithDepend(string objId, object o, string[] dependKey);

     
/// <summary>
     
/// 移除指定ID的对象
     
/// </summary>
     
/// <param name="objId"></param>
     void RemoveObject(string objId);

     
/// <summary>
     
/// 返回指定ID的对象
     
/// </summary>
     
/// <param name="objId"></param>
     
/// <returns></returns>
     object RetrieveObject(string objId);

     
/// <summary>
     
/// 到期时间
     
/// </summary>
     int TimeOut { set;get;}
}


     当然在MemCachedStrategy类中还有一个对象要加以说明,就是MemCachedManager,该类主要是对
Memcached一些常操作和相关初始化实例调用的“封装”,下面是是其变量定义和初始化构造方法的代码:

/// <summary>
/// MemCache管理操作类
/// </summary>
public sealed class MemCachedManager
{
    
#region 静态方法和属性
    
private static MemcachedClient mc = null;

    
private static SockIOPool pool = null;

    
private static MemCachedConfigInfo memCachedConfigInfo = MemCachedConfigs.GetConfig();

    
private static string [] serverList = null;

    
static MemCachedManager()
    {
        CreateManager();
    }

    
private static void CreateManager()
    {
        serverList 
= Utils.SplitString(memCachedConfigInfo.ServerList, ""r"n");

        pool 
= SockIOPool.GetInstance(memCachedConfigInfo.PoolName);
        pool.SetServers(serverList);
        pool.InitConnections 
= memCachedConfigInfo.IntConnections;//初始化链接数
        pool.MinConnections = memCachedConfigInfo.MinConnections;//最少链接数
        pool.MaxConnections = memCachedConfigInfo.MaxConnections;//最大连接数
        pool.SocketConnectTimeout = memCachedConfigInfo.SocketConnectTimeout;//Socket链接超时时间
        pool.SocketTimeout = memCachedConfigInfo.SocketTimeout;// Socket超时时间
        pool.MaintenanceSleep = memCachedConfigInfo.MaintenanceSleep;//维护线程休息时间
        pool.Failover = memCachedConfigInfo.FailOver; //失效转移(一种备份操作模式)
        pool.Nagle = memCachedConfigInfo.Nagle;//是否用nagle算法启动socket
        pool.HashingAlgorithm = HashingAlgorithm.NewCompatibleHash;
        pool.Initialize();
        

        mc 
= new MemcachedClient();
        mc.PoolName 
= memCachedConfigInfo.PoolName;
        mc.EnableCompression 
= false;
    }

    
/// <summary>
    
/// 缓存服务器地址列表
    
/// </summary>
    public static string[] ServerList
    {
        
set
        {
            
if (value != null)
                serverList 
= value;
        }
        
get { return serverList; }
    }

    
/// <summary>
    
/// 客户端缓存操作对象
    
/// </summary>
    public static MemcachedClient CacheClient
    {
        
get
        {
            
if (mc == null)
                CreateManager();

            
return mc;
        }
    }

    
public static void Dispose()
    {
        
if (pool != null)
            pool.Shutdown();
    }
    

    
    上面代码中构造方法会初始化一个池来管理执行Socket链接,并提供静态属性CacheClient以便MemCachedStrategy
来调用。

(责任编辑:admin)
织梦二维码生成器
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片