xuyaxiu 发表于 2015-11-19 07:52:44

ASP.NET使用中Memcached

现在一些。NET开发人员开始放弃ASP.NET内置的缓存机制,转而使用Memcached——一种分布式的内存缓存系统,其最初是由Danga Interactive公司为LiveJournal网站而开发。  缓存的一个基础性问题就是如何处理过时数据。当运行在单独的Web服务器上,你可以很容易地清除一个已经确认被改变了的缓存。可惜,ASP.NET没有一个很好的方法来支持多服务器。每个服务器上的缓存都对其他缓存的改变一无所知。
  ASP.NET允许通过基于文件系统和数据库表的触发器来作废一个缓存。然而,这也存在问题,比如数据库触发器需要使用昂贵的轮询,以及触发器本身冗长的编程。但是,我们还是有其他的选择的。
  不像ASP.NET内置的缓存机制,Memcached是一个分布式的缓存系统。任何Web服务器都能更新或删除一个缓存项,并且所有其他的服务器都能在下次访问这些缓存项的时候自动获取到更新的内容。这是通过把这些缓存项存储在一个或者多个缓存服务器上来实现的。每一个缓存项都根据它的关键字的哈希值来分配到一个服务器上。内容来自中国站长资讯网(www.chinahtml.com)
  表面看来,Memcached针对ASP.NET的API就像和内置的API一样。这让开发人员很容易地转换到Memcached上,仅仅通过在代码中查找和替换即可实现。
  然而仅仅只是让其运行起来还不够,如果要在大型Web Farms(译者注:大型站点)正确地使用还需要注意一些问题。Richard Jones写到:内容来自中国站长资讯网(www.chinahtml.com)
  当我们添加很多节点后,get_multi函数的有用性在降低——这可能是由于单独的页面,需要访问几乎所有的Memcached实例。我在某处读到 Facebook(译者注:现在很火的校园社交网站)把他们的Memcached集群进行分割以提高get_multi的性能(例如,所有用户的数据都放置在名为mc的子集节点上)。有人能告诉我这样做的效果吗?
  一个被推荐的解决方案是不根据缓存项的关键字来生成哈希键值。这将允许开发人员能够让一个给定页面中需要的所有缓存项,尽量存放在同一个服务器上。可惜,基于数据保存的地方而不是基于缓存项自身的关键字来生成哈希键,很容易产生错误,需要仔细来实现(这个算法)。         
  
ASP.NET中Memcached
  一,准备
      你需要有一下软件:
       VS.NET(05/08)
       SQLSERVER
       memcached服务器端以及客户端类库(开源软件,下载即可)
其中,客户端类库包括以下几个DLL:
       Memcached.ClientLibrary.dll
       ICSharpCode.SharpZipLib.dll
       log4net.dll
       二,安装memcached服务器端
       将memcached.exe复制到任意目录下,如 c:,在命令行输入:
memcached.exe -d install
memcached将作为一个服务常驻系统内存了
      三,建立ASP.NET工程
   创建一个ASP.NETWEB项目,命名为MMCWEB,添加以上提到的几个客户端类库的引用。
   四,配置
   memcached使用了log4net,所以我们先配置log4net
在web.config里找到configSections节点,添加以下内容
<section name=&quot;log4net&quot; type=&quot;log4net.Config.Log4NetConfigurationSectionHandler, log4net&quot; />

再在configSections节点之外,增加以下内容:
<log4net>
      <appender name=&quot;RollingLogFileAppender&quot; type=&quot;log4net.Appender.RollingFileAppender&quot;>
            <param name=&quot;File&quot; value=&quot;LogFiles/&quot;/>
            <param name=&quot;AppendToFile&quot; value=&quot;true&quot;/>
            <param name=&quot;MaxSizeRollBackups&quot; value=&quot;10&quot;/>
            <param name=&quot;StaticLogFileName&quot; value=&quot;false&quot;/>
            <param name=&quot;DatePattern&quot; value=&quot;yyyy-MM-dd&quot;.txt&quot;&quot;/>
            <param name=&quot;RollingStyle&quot; value=&quot;Date&quot;/>
            <layout type=&quot;log4net.Layout.PatternLayout&quot;>
                <param name=&quot;ConversionPattern&quot; value=&quot;%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %ndc - %message%newline&quot;/>
            </layout>
      </appender>
      <appender name=&quot;ConsoleAppender&quot; type=&quot;log4net.Appender.ConsoleAppender&quot;>
            <layout type=&quot;log4net.Layout.PatternLayout&quot;>
                <param name=&quot;ConversionPattern&quot; value=&quot;%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger %ndc - %message%newline&quot; />
            </layout>
      </appender>
      <root>
            <level value=&quot;ALL&quot; />
            <appender-ref ref=&quot;RollingLogFileAppender&quot; />
            <appender-ref ref=&quot;ConsoleAppender&quot; />
      </root>
      <logger name=&quot;Memcached.ClientLibrary&quot;>
            <level value=&quot;WARN&quot; />

      </logger>
    </log4net>
启动调试,若没出现配置的出错提示,并且在网站目录下有文件夹LogFiles,就说明log4net配置成功了。
  五,初始化SockIOPool
SockIOPool是什么东东?SockIOPool是Memcached客户端提供的一个套接字连接池,通俗讲,就是与Memcached服务器端交换数据的对象。SockIOPool在应用程序启动时初始化一次就可以了,我把这个工作放在 GLOBAL.ASAX.CS的Application_Start方法里
char[] separator = { ',' };
            string[] serverlist = ConfigurationManager.AppSettings[&quot;Memcached.ServerList&quot;].Split(separator);

            // initialize the pool for memcache servers
            try
            {
                SockIOPool pool = SockIOPool.GetInstance();
                pool.SetServers(serverlist);

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

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

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

                pool.Nagle = false;
                pool.Initialize();
            }
            catch (Exception err)
            {
                //这里就可以用Log4Net记录Error啦!
            }

注意AppSettings[&quot;Memcached.ServerList&quot;]是在WEB.CONFIG里设置的,所以WEB.CONFIG的appSettings的子节点里需要有以下一行
<add key=&quot;Memcached.ServerList&quot; value=&quot;127.0.0.1:11211&quot;/>
启动调试服务器,若没有出错的日志记录,说明IO连接池已经开辟成功。
      六,使用Memcached
       终于进入正题了,不过使用之前,我们还需要准备一些数据。
      创建一个实体类People,并加上Serializable属性!!!
      对应的数据库里,增加一张表,字段对应实体类,插入一些测试数据。持久层和业务层的设计就略过了,他们负责向提供一些数据,返回类型可自定,若ILIST,DATASET。
   Memcached使用起来就很简单了,比如后台检索出一组People类型的数据,放在一个叫peopleList的arraylist里,而且这个arraylist要频繁使用,只需要这样
MemcachedClient mc = new MemcachedClient();
mc.EnableCompression = true;
mc.Set(key, peopleList);   
         上面的key是用来访问这个arraylist的键,Memcached里的数据都是保存为键-值对的。
一旦mc.KeyExists(key)为TRUE,就用return mc.Get(key) as ArrayList提取数据,删除时,使用 return mc.Delete(key);等等。可以自己琢磨了。

         以上只是演示,其实数据缓存是一项复杂而繁琐的工作,不仅需要后台代码的分层优化,也需要数据库对大数据量访问的策略和调优。
  
  http://www.chinahtml.com/0707/asp-118489071915107.html
  .NET下实现分布式缓存系统Memcached :http://tech.it168.com/a2009/0907/675/000000675239.shtml
  使用Memcached提高.NET应用程序的性能(周公) :http://zhoufoxcn.blog.iyunv.com/792419/528212
页: [1]
查看完整版本: ASP.NET使用中Memcached