安装Memcached及Memcached配置

时间:2022-02-13 20:38:43
一、安装Memcached及Memcached配置和状态查询 
          要想使用Memcached做缓存首先需要安装Memcached服务,安装方法如下:
      1. 下载Memcached:http://code.jellycan.com/memcached/ 现在的最新版本是1.2.6.注意下载正确的版本,windows 服务的话下载win32 binary。
      2.解压之后放在硬盘的目录下,如:D:\memcached. 然后在运行中输入cmd进入命令行,进入到Memcached.exe 所在的目录,例如:D:\memcached,然后输入:Memcached –d install,即可完成安装。
          Memcached还有其他的一些常用的命令如下:
      -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 显示帮助
          按照上面的安装步骤安装之后,使用memcached –m 200来调整最大内存占用之后会发现没有起作用,总是默认的64MB的内存,在网上搜了一下,原因是注册表中并没有写入信息,可以这样来修改。
         1. memcached –d shutdown 首先关闭memcached服务。
         2.进入注册表,找到HKEY_LOCAL_MA CHINE\SYSTEM\CurrentControlSet\Services\memcached Server, 在其中有一个ImagePath项,值为"d:\memcached\memcached.exe" -d runservice,在后面加上-l 127.0.0.1 -m 3000 -c 2048。
        3.memcached –d start 启动memcached服务,这样就将memcached的最大内存修改为了3000MB。
        对Memcached缓存服务的状态查询,可以先telnet连接上服务:telnet 127.0.0.1 11211 ,然后使用 stats命令查看缓存服务的状态,会返回如下的数据:    
        time:    1255537291                               服务器当前的unix时间戳 
        total_items:    54                                     从服务器启动以后存储的items总数量 
        connection_structures:    19                    服务器分配的连接构造数 
        version:    1.2.6                                        memcache版本 
        limit_maxbytes:    67108864                    分配给memcache的内存大小(字节) 
        cmd_get:    1645                                      get命令(获取)总请求次数 
        evictions:    0                                            为获取空闲内存而删除的items数(分配给memcache的空间用满后需 
                                                                         要删除旧的items来得到空间分配给新的items) 
        total_connections:    19                           从服务器启动以后曾经打开过的连接数 
        bytes:    248723                                      当前服务器存储items占用的字节数 
        threads:    1                                             当前线程数 
        get_misses:    82                                      总未命中次数 
        pointer_size:    32                                    当前操作系统的指针大小(32位系统一般是32bit) 
        bytes_read:    490982                              总读取字节数(请求字节数) 
        uptime:    161                                           服务器已经运行的秒数 
        curr_connections:    18                             当前打开着的连接数 
        pid:    2816                                               memcache服务器的进程ID 
        bytes_written:    16517259                     总发送字节数(结果字节数) 
        get_hits:    1563                                      总命中次数 
        cmd_set:    54                                          set命令(保存)总请求次数 
        curr_items:    28                                       服务器当前存储的items数量
      二、在Discuz NT 3.0中配置Memcached服务
        在Discuz NT 3.0中配置Memcached服务较为简单,找到论坛根目录下的config目录,找到Memcached.config,打开,进行如下配置:
<?xml version="1.0"?> 
<MemCachedConfigInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ApplyMemCached>(1)</ApplyMemCached> 
    <ServerList>(2)</ServerList> 
    <PoolName>DiscuzNT_MemCache</PoolName> 
    <IntConnections>3</IntConnections> 
    <MinConnections>3</MinConnections> 
    <MaxConnections>5</MaxConnections> 
    <SocketConnectTimeout>1000</SocketConnectTimeout> 
    <SocketTimeout>3000</SocketTimeout> 
    <MaintenanceSleep>30</MaintenanceSleep> 
    <FailOver>true</FailOver> 
    <Nagle>true</Nagle> 
</MemCachedConfigInfo>
      (1)处为"true”的时候表示Discuz NT打开Memcached缓存功能,为"false”的时候表示关闭Memcached缓存功能。
      (2)处填写Memcached服务器的IP地址+端口,例如:127.0.0.1:11211 
   三、二次开发监控Memcached状态
       Discuz NT的一个好处就是开源的,并且我们能够再上面很灵活的进行二次开发,这里,我们就以监控Memcached状态为例来做一个二次开发。具体的步骤是:
      1.下载Memcached的.Net的开发包,下载地址是:http://sourceforge.net/projects/memcacheddotnet/。
      2.在visual studio 2005或者2008中建立一个类库,例如命名为:MyBBS.BBS.Plugin.MemcachedStats,然后在项目点击右键,选择属性,将默认命名空间修改为:Discuz.Web,如图:
       
    3.将Memcached的.Net开发包解压,将将Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll 等放到bin目录,并且在项目中引用Memcached.ClientLibrary.dll.
    4.在项目中引用Discuz.Forum.
    5.在项目中增加类,命名为memcachedstats.cs.记得最好是小写,继承自Discuz.Forum.PageBase。然后在类中override showpage()函数,我们就可以在这里来写代码了,如下:
using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Data; 
using System.Collections; 
using M=Memcached.ClientLibrary; 
namespace Discuz.Web 
{ 
    public class memcachedstats:Discuz.Forum.PageBase 
    { 
        public string MemcachedStatsOutput = string.Empty; 
        protected override void ShowPage() 
        { 
            base.ShowPage(); 
            string[] servers = { "此处填写Memcachedf服务IP+端口" }; 
            M.SockIOPool pool = M.SockIOPool.GetInstance(); 
            pool.SetServers(servers); 
            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(); 
            this.pagetitle = "MemcachedStats"; 
            M.MemcachedClient mc = new Memcached.ClientLibrary.MemcachedClient(); 
            StringBuilder sb = new StringBuilder(); 
            Hashtable ht = mc.Stats(); 
            sb.AppendLine("Memcached Stats:<br>"); 
            sb.AppendLine("_______________________________________<br>"); 
            foreach (DictionaryEntry de in ht) 
            { 
                Hashtable info = (Hashtable)de.Value; 
                foreach (DictionaryEntry de2 in info) 
                { 
                    sb.AppendLine(de2.Key.ToString() + ":&nbsp;&nbsp;&nbsp;&nbsp;" + de2.Value.ToString() + "<br>"); 
                } 
            } 
            MemcachedStatsOutput = sb.ToString(); 
        } 
    } 
}
    这样我们就将代码完成了,我们将Memcached服务的状态信息保存到了MemcachedStatsOutput 这个字段中了,那么我们怎么在页面上显示出来呢?在进行下一步之前,编译输出MyBBS.BBS.Plugin.MemcachedStats.dll然后上传到论坛根目录的bin目录下。
    6.在论坛根目录下面的templete\default\中新建memcachedstats.htm,写入下面的代码:
<%template _header%> 
<div id="nav"> 
    <div class="wrap s_clear"> 
    <a href="{config.forumurl}" class="title">{config.forumtitle}</a> &raquo; <strong>Memcached Stats</strong> 
    </div> 
</div> 
<div class="wrap with_side s_clear help" id="wrap"> 
   <div class="side"> 
        <div class="sideinner"> 
        </div> 
        </div> 
        <div class="cpmain"> 
        <div class="cpcontent"> 
            <h3 class="lightlink">Memcached Stats</h3> 
            <hr class="solidline"/> 
            {MemcachedStatsOutput} 
        </div> 
        </div> 
</div> 
<%template _copyright%> 
<%template _footer%>
     这里我们重点注意红色的部分,我们就是在这里来把我们上面的类库里面的MemcachedStatsOutput字段在这里输出的。
     7.进入论坛后台管理系统,点击“界面风格”——“模板管理”——“default”,这时我们就可以看到出现了memcachedstats这个模板了,勾中前面的复选框,然后选择“按选择的模板文件生成页面”。
     8.上面的工作完成之后,我们在浏览器中输入:您的论坛地址\memcachedstats.aspx,就可以看到统计的Memcached服务的信息了,如图:
    
四、结束语与参考信息
      怎么样,还是很简单的吧,当然这里仅仅是做了最基本的开发了,不过相信这些弄清楚了,其它的开发就不是很复杂了,大家也都可以开发出自己更多丰富多彩的功能了。
     下面列出的是其他的一些参考资料,希望对大家有帮助:
     Discuz NT 界面模板的基本语法:http://nt.discuz.net/doc/default.aspx?cid=42
     Memcached的安装:http://www.cnblogs.com/zjneter/archive/2007/07/19/822780.html
     网友编写的用php代码展示Memcached状态的代码:http://code.sixapart.com/svn/memcached/trunk/server/scripts/memcached-tool
•    0 Comments 


memcached完全剖析–1. memcached的基础时间:2009-06-14 11:00:02来源:网络 作者:未知 点击:177次 
我是mixi株式会社开发部系统运营组的长野。日常负责程序的运营。从今天开始,将分几次针对最近在Web应用的可扩展性领域的热门话题memcached,与我公司开发部研究开发组的前坂一起,说明其内部结构和使用。
我是mixi株式会社开发部系统运营组的长野。日常负责程序的运营。从今天开始,将分几次针对最近在Web应用的可扩展性领域的热门话题memcached,与我公司开发部研究开发组的前坂一起,说明其内部结构和使用。

memcached是什么? 
memcached的特征 
协议简单 
基于libevent的事件处理 
内置内存存储方式 
memcached不互相通信的分布式 
安装memcached 
memcached的安装 
memcached的启动 
用客户端连接 
使用Cache::Memcached 
使用Cache::Memcached连接memcached 
保存数据 
获取数据 
删除数据 
增一和减一操作 
总结 
memcached是什么?
memcached是以LiveJournal旗下Danga Interactive公司的Brad Fitzpatric为首开发的一款软件。现在已成为mixi、hatena、Facebook、Vox、LiveJournal等众多服务中提高Web应用扩展性的重要因素。

许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。

这时就该memcached大显身手了。memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

 

图1 一般情况下memcached的用途

memcached的特征
memcached作为高速运行的分布式缓存服务器,具有以下的特点。

协议简单 
基于libevent的事件处理 
内置内存存储方式 
memcached不互相通信的分布式 
协议简单
memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。因此,通过telnet 也能在memcached上保存数据、取得数据。下面是例子。

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
set foo 0 0 3     (保存命令)
bar               (数据)
STORED            (结果)
get foo           (取得命令)
VALUE foo 0 3     (数据)
bar               (数据)协议文档位于memcached的源代码内,也可以参考以下的URL。

http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt 
基于libevent的事件处理
libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。 memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。关于事件处理这里就不再详细介绍,可以参考Dan Kegel的The C10K Problem。

libevent:http://www.monkey.org/~provos/libevent/ 
The C10K Problem:http://www.kegel.com/c10k.html 
内置内存存储方式
为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。 memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。关于内存存储的详细信息,本连载的第二讲以后前坂会进行介绍,请届时参考。

memcached不互相通信的分布式
memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。本连载也将介绍memcached的分布式。

 

图2 memcached的分布式

接下来简单介绍一下memcached的使用方法。

安装memcached
memcached的安装比较简单,这里稍加说明。

memcached支持许多平台。

Linux 
FreeBSD 
Solaris (memcached 1.2.5以上版本) 
Mac OS X 
另外也能安装在Windows上。这里使用Fedora Core 8进行说明。

memcached的安装
运行memcached需要本文开头介绍的libevent库。Fedora 8中有现成的rpm包,通过yum命令安装即可。

$ sudo yum install libevent libevent-develmemcached的源代码可以从memcached网站上下载。本文执笔时的最新版本为1.2.5。 Fedora 8虽然也包含了memcached的rpm,但版本比较老。因为源代码安装并不困难,这里就不使用rpm了。

下载memcached:http://www.danga.com/memcached/download.bml 
memcached安装与一般应用程序相同,configure、make、make install就行了。

$ wget http://www.danga.com/memcached/dist/memcached-1.2.5.tar.gz
$ tar zxf memcached-1.2.5.tar.gz
$ cd memcached-1.2.5
$ ./configure
$ make
$ sudo make install默认情况下memcached安装到/usr/local/bin下。

memcached的启动
从终端输入以下命令,启动memcached。

$ /usr/local/bin/memcached -p 11211 -m 64m -vv
slab class   1: chunk size     88 perslab 11915
slab class   2: chunk size    112 perslab  9362
slab class   3: chunk size    144 perslab  7281
中间省略
slab class  38: chunk size 391224 perslab     2
slab class  39: chunk size 489032 perslab     2
<23 server listening
<24 send buffer was 110592, now 268435456
<24 server listening (udp)
<24 server listening (udp)
<24 server listening (udp)
<24 server listening (udp)这里显示了调试信息。这样就在前台启动了memcached,监听TCP端口11211 最大内存使用量为64M。调试信息的内容大部分是关于存储的信息,下次连载时具体说明。

作为daemon后台启动时,只需

$ /usr/local/bin/memcached -p 11211 -m 64m -d这里使用的memcached启动选项的内容如下。

选项 说明 
-p 使用的TCP端口。默认为11211 
-m 最大内存大小。默认为64M 
-vv 用very vrebose模式启动,调试信息和错误输出到控制台 
-d 作为daemon在后台启动 

上面四个是常用的启动选项,其他还有很多,通过

$ /usr/local/bin/memcached -h命令可以显示。许多选项可以改变memcached的各种行为,推荐读一读。

用客户端连接
许多语言都实现了连接memcached的客户端,其中以Perl、PHP为主。仅仅memcached网站上列出的语言就有

Perl 
PHP 
Python 
Ruby 
C# 
C/C++ 
Lua 
等等。

memcached客户端API:http://www.danga.com/memcached/apis.bml 
这里介绍通过mixi正在使用的Perl库链接memcached的方法。

使用Cache::Memcached
Perl的memcached客户端有

Cache::Memcached 
Cache::Memcached::Fast 
Cache::Memcached::libmemcached 
等几个CPAN模块。这里介绍的Cache::Memcached是memcached的作者Brad Fitzpatric的作品,应该算是memcached的客户端中应用最为广泛的模块了。

Cache::Memcached - search.cpan.org:http://search.cpan.org/dist/Cache-Memcached/ 
使用Cache::Memcached连接memcached
下面的源代码为通过Cache::Memcached连接刚才启动的memcached的例子。

#!/usr/bin/perl

use strict;
use warnings;
use Cache::Memcached;

my $key = "foo";
my $value = "bar";
my $expires = 3600; # 1 hour
my $memcached = Cache::Memcached->new({
    servers => ["127.0.0.1:11211"],
    compress_threshold => 10_000
});

$memcached->add($key, $value, $expires);
my $ret = $memcached->get($key);
print "$ret\n";在这里,为Cache::Memcached指定了memcached服务器的IP地址和一个选项,以生成实例。 Cache::Memcached常用的选项如下所示。

选项 说明 
servers 用数组指定memcached服务器和端口 
compress_threshold 数据压缩时使用的值 
namespace 指定添加到键的前缀 

另外,Cache::Memcached通过Storable模块可以将Perl的复杂数据序列化之后再保存,因此散列、数组、对象等都可以直接保存到memcached中。

保存数据
向memcached保存数据的方法有

add 
replace 
set 它们的使用方法都相同: 
my $add = $memcached->add( '键', '值', '期限' );
my $replace = $memcached->replace( '键', '值', '期限' );
my $set = $memcached->set( '键', '值', '期限' );向memcached保存数据时可以指定期限(秒)。不指定期限时,memcached按照LRU算法保存数据。这三个方法的区别如下:

选项 说明 
add 仅当存储空间中不存在键相同的数据时才保存 
replace 仅当存储空间中存在键相同的数据时才保存 
set 与add和replace不同,无论何时都保存 

获取数据
获取数据可以使用get和get_multi方法。

my $val = $memcached->get('键');
my $val = $memcached->get_multi('键1', '键2', '键3', '键4', '键5');一次取得多条数据时使用get_multi。get_multi可以非同步地同时取得多个键值,其速度要比循环调用get快数十倍。

删除数据
删除数据使用delete方法,不过它有个独特的功能。

$memcached->delete('键', '阻塞时间(秒)');删除第一个参数指定的键的数据。第二个参数指定一个时间值,可以禁止使用同样的键保存新数据。此功能可以用于防止缓存数据的不完整。但是要注意,set函数忽视该阻塞,照常保存数据

增一和减一操作
可以将memcached上特定的键值作为计数器使用。

my $ret = $memcached->incr('键');
$memcached->add('键', 0) unless defined $ret;增一和减一是原子操作,但未设置初始值时,不会自动赋成0。因此,应当进行错误检查,必要时加入初始化操作。而且,服务器端也不会对超过2<sup>32</sup>时的行为进行检查。

总结
这次简单介绍了memcached,以及它的安装方法、Perl客户端Cache::Memcached的用法。只要知道,memcached的使用方法十分简单就足够了。

下次由前坂来说明memcached的内部结构。了解memcached的内部构造,就能知道如何使用memcached才能使Web应用的速度更上一层楼。欢迎继续阅读下一章。

 
本篇文章来源于:开发学院 http://edu.codepub.com   原文链接:http://edu.codepub.com/2009/0614/6129.php















































原创:.NET版分布式缓存Memcached测试实例
   下面测试下分布式缓存Memcached软件,一直在学习关注大访问量网站的缓存是如何实现,之前看过Memcached的资料,忙于没有时间来真正测试一下,本文测试分布式缓存Memcached的环境如下:(两台电脑作为服务器) 墨者资讯www.cnmoker.org 
第一台: 
CPU:Inter(R) Pentium(R) 4 CPU 2.8G 内容来自墨者资讯 
内存:1G 
系统:windows 7  
IIS: IIS 7 
IP:172.10.1.97  
环境:本地  
安装:memcached 1.2.1 for Win32 
第二台: 本文来自墨者资讯 
CPU:Inter(R) Pentium(R) 4 CPU 3.0G 
内存:2G 本文来自墨者资讯 
系统:windows Server 2003 
IIS: IIS 6 
IP:172.10.1.236  
环境:远程  
安装:memcached 1.2.1 for Win32 
测试程序部署到本地环境(172.10.1.97),开发工具VS2008 .NET3.5 
本文使用到memcached 1.2.1 for Win32下载地址:  
http://jehiah.cz/projects/memcached-win32/ 
更多memcached版本大全请进入  
http://www.xueit.com/html/2009-11-12/32-1550931594781.html 
好了,下面我们按步骤来测试: 
第一、首先到把下载好的memcached 1.2.1解压到C:\memcached目录,分别复制到两台服务器中。  
第二、安装memcached服务,在命令提示符输入CD c:\memcached进入到memcached目录,如下图:  
 本文来自墨者资讯 
之后输入memcached -h 回车,看帮助说明,接下来输入memcached -d install 回车即可自动安装memcached服务了,如下图: 
 
安装memcached服务图 copyright cnmoker.orrg 
安装好安装memcached服务后,输入memcached -d start 回车启动memcached服务,如下图: 本文来自墨者资讯 
 
启动memcached服务图 
在172.10.1.97与172.10.1.236两台电脑都按以上操作来安装启动memcached。 内容来自墨者资讯 
第三、下载.NET版memcached客户端API组件来写测试程序。 
本文使用memcacheddotnet,下载地址如下:  
http://sourceforge.net/projects/memcacheddotnet/ 
下载好之后把这些文件Commons.dll,ICSharpCode.SharpZipLib.dll,log4net.dll,Memcached.ClientLibrary.dll放到bin目录(少一个都不行),之后再到测试项目开发环境引用Memcached.ClientLibrary.dll,如下图 cnmoker.org 
 
引用Memcached.ClientLibrary.dll图  
第四、测试程序: 
以下为引用的内容:
using System;
using System.Collections;
using System.Text;

// 须引用Memcached
using Memcached.ClientLibrary;

namespace test
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Request["action"] == "clear") 
                    this.clear();
                else
                    this.test();
            }
        }

        /// <summary>
        /// 清空缓存 内容来自墨者资讯
        /// </summary>
        public void clear()
        {
           string[] servers = { "172.10.1.97:11211", "172.10.1.236:11211" };

            //初始化池
            SockIOPool pool = SockIOPool.GetInstance();
            pool.SetServers(servers); cnmoker.org 
            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 Memcached.ClientLibrary.MemcachedClient();
            mc.EnableCompression = false;
            mc.Delete("cache");
            mc.Delete("endCache");
            Response.Write("清空缓存成功"); 
        }

        /// <summary>
        /// 测试缓存
        /// </summary>
        public void test()
        {
            //分布Memcachedf服务IP 端口 cnmoker.org 
            string[] servers = { "172.10.1.97:11211","172.10.1.236:11211" };
            //初始化池
SockIOPool pool = SockIOPool.GetInstance();
            pool.SetServers(servers);
            pool.InitConnections = 3;
            pool.MinConnections = 3;
            pool.MaxConnections = 5; 墨者资讯www.cnmoker.org 
            pool.SocketConnectTimeout = 1000;
            pool.SocketTimeout = 3000;
            pool.MaintenanceSleep = 30;
            pool.Failover = true;
            pool.Nagle = false; copyright cnmoker.orrg 
            pool.Initialize();
            //客户端实例
            MemcachedClient mc = new Memcached.ClientLibrary.MemcachedClient();
            mc.EnableCompression = false;
            StringBuilder sb = new StringBuilder();
            //写入缓存
            sb.AppendLine("写入缓存测试:");
            sb.AppendLine("<br>_______________________________________<br>"); 
            if (mc.KeyExists("cache"))
            {
                sb.AppendLine("缓存cache已存在");
            }
            else
            {
                mc.Set("cache", "写入缓存时间:"  + DateTime.Now.ToString()); 
                sb.AppendLine("缓存已成功写入到cache");
            }
            sb.AppendLine("<br>_______________________________________<br>");
            sb.AppendLine("读取缓存内容如下:<br>");
            sb.AppendLine(mc.Get("cache").ToString());

            //测试缓存过期
            sb.AppendLine("<br>_______________________________________<br>"); 本文来自墨者资讯 
            if (mc.KeyExists("endCache"))
            {
                sb.AppendLine("缓存endCache已存在,过期时间为:"  + mc.Get("endCache").ToString());
            }
            else 
            {
                mc.Set("endCache", DateTime.Now.AddMinutes(1).ToString(),DateTime.Now.AddMinutes(1));
                sb.AppendLine("缓存已更新写入到endCache,写入时间:" + DateTime.Now.ToString() + " 过期时间:"   DateTime.Now.AddMinutes(1).ToString());
            }

            //分析缓存状态
            Hashtable ht = mc.Stats();
            sb.AppendLine("<br>_______________________________________<br>"); 
            sb.AppendLine("Memcached Stats:");
            sb.AppendLine("<br>_______________________________________<br>");
            foreach (DictionaryEntry de in ht)
            {
                Hashtable info = (Hashtable)de.Value; 本文来自墨者资讯 
                foreach (DictionaryEntry de2 in info)
                {
                    sb.AppendLine(de2.Key.ToString() +  ":&nbsp;&nbsp;&nbsp;&nbsp;"  + de2.Value.ToString()  + "<br>");
                }
            }
            Response.Write(sb.ToString());
        }
    } 
第五、 运行看效果: 本文来自墨者资讯 
 墨者资讯www.cnmoker.org 
缓存效果图我在本地172.10.1.97运行memcached -d  stop来停止memcached服务,运行上面程序,一样正确,说明缓存也同样保存到远程172.10.1.236这台服务器了。这样简单就可以实现分布式缓存,使用缓存又多了一个选择,不必使用.NET自带的Application与cache了,访问量大的网站实现分布式缓存有很多好处。有什么问题请指正,下期再出其它教程。转载请注明文章来源及原始链接,谢谢合作!原文:http://www.xueit.com/html/2009-11-12/21-932220455859.html 
本文来自墨者资讯
墨者资讯www.cnmoker.org 
来源:墨者资讯网-我们致力于做最全面的资讯信息资料库










































分布式缓存系统Memcached入门指导
http://database.51cto.com  2009-11-09 09:25  James G. Goodwill  IBMDW  我要评论()
•    摘要:这篇Memcached入门介绍涵盖的主题包括安装、配置、memcached 客户机命令和评估缓存效率,主要讨论与 memcached 服务器的直接交互,其目的是为您提供监控 memcahed 实例所需的工具。 
•    标签:Memcached入门 
•     
Oracle帮您准确洞察各个物流环节
首先介绍一下,memcached 是由 Danga Interactive 开发并使用 BSD 许可的一种通用的分布式内存缓存系统(题外话:最近,Memcached 项目将从 http://danga.com/memcached/ 正式转向 http://memcached.org/)。这篇Memcached入门文章可以帮助读者建立起对Memcached使用与性能的认识。
  
Memcached示意图(来自memcached.org)
Danga Interactive 开发 memcached 的目的是创建一个内存缓存系统来处理其网站 LiveJournal.com 的巨大流量。每天超过 2000 万的页面访问量给 LiveJournal 的数据库施加了巨大的压力,因此 Danga 的 Brad Fitzpatrick 便着手设计了 memcached。memcached 不仅减少了网站数据库的负载,还成为如今世界上大多数高流量网站所使用的缓存解决方案。
本文首先全面概述 memcached,然后指导您安装 memcached 以及在开发环境中构建它。我还将介绍 memcached 客户机命令(总共有 9 个)并展示如何在标准和高级 memcached 操作中使用它们。最后,我将提供一些使用 memcached 命令测量缓存的性能和效率的技巧。
如何将 memcached 融入到您的环境中?
在开始安装和使用 using memcached 之前,我们需要了解如何将 memcached 融入到您的环境中。虽然在任何地方都可以使用 memcached,但我发现需要在数据库层中执行几个经常性查询时,memcached 往往能发挥最大的效用。我经常会在数据库和应用服务器之间设置一系列 memcached 实例,并采用一种简单的模式来读取和写入这些服务器。图 1 可以帮助您了解如何设置应用程序体系结构:
图 1. 使用 memcached 的示例应用程序体系结构
 
体系结构相当容易理解。我建立了一个 Web 层,其中包括一些 Apache 实例。下一层是应用程序本身。这一层通常运行于 Apache Tomcat 或其他开源应用服务器之上。再下面一层是配置 memcached 实例的地方 — 即应用服务器与数据库服务器之间。在使用这种配置时,需要采用稍微不同的方式来执行数据库的读取和写入操作。
读取
我执行读取操作的顺序是从 Web 层获取请求(需要执行一次数据库查询)并检查之前在缓存中存储的查询结果。如果我找到所需的值,则返回它。如果未找到,则执行查询并将结果存储在缓存中,然后再将结果返回给 Web 层。
写入
将数据写入到数据库中时,首先需要执行数据库写入操作,然后将之前缓存的任何受此写入操作影响的结果设定为无效。此过程有助于防止缓存和数据库之间出现数据不一致性。
安装 memcached
memcached 支持一些操作系统,包括 Linux?、Windows?、Mac OS 和 Solaris。在本文中,我将详细介绍如何通过源文件构建和安装 memcached。采用这种方式的主要原因是我在遇到问题时可以查看源代码。
libevent
libevent 是安装 memcached 的唯一前提条件。它是 memcached 所依赖的异步事件通知库。您可以在 monkey.org 上找到关于 libevent 的源文件。接下来,找到其最新版本的源文件。对于本文,我们使用稳定的 1.4.11 版本。获取了归档文件之后,将它解压到一个方便的位置,然后执行清单 1 中的命令:
清单 1. 生成和安装 libevent
cd libevent-1.4.11-stable/

./configure

make

make install
memcached
从 Danga Interactive 获取 memcached 源文件,仍然选择最新的分发版。在撰写本文时,其最新版本是 1.4.0。将 tar.gz 解压到方便的位置,并执行清单 2 中的命令:
清单 2. 生成和安装 memcached
cd memcached-1.4.0/

./configure

make

make install
完成这些步骤之后,您应该安装了一个 memcached 工作副本,并且可以使用它了。让我们进行简单介绍,然后使用它。
使用 memcached
要开始使用 memcached,您首先需要启动 memcached 服务器,然后使用 telnet 客户机连接到它。
要启动 memcached,执行清单 3 中的命令:
清单 3. 启动 memcached
./memcached -d -m 2048 -l 10.0.0.40 -p 11211
这会以守护程序的形式启动 memcached(-d),为其分配 2GB 内存(-m 2048),并指定监听 localhost,即端口 11211。您可以根据需要修改这些值,但以上设置足以完成本文中的练习。接下来,您需要连接到 memcached。您将使用一个简单的 telnet 客户机连接到 memcached 服务器。
大多数操作系统都提供了内置的 telnet 客户机,但如果您使用的是基于 Windows 的操作系统,则需要下载第三方客户机。我推荐使用 PuTTy。
安装了 telnet 客户机之后,执行清单 4 中的命令:
清单 4. 连接到 memcached
telnet localhost 11211
如果一切正常,则应该得到一个 telnet 响应,它会指示 Connected to localhost(已经连接到 localhost)。如果未获得此响应,则应该返回之前的步骤并确保 libevent 和 memcached 的源文件都已成功生成。
您现现已经登录到 memcached 服务器。此后,您将能够通过一系列简单的命令来与 memcached 通信。9 个 memcached 客户端命令可以分为三类:
1.    基本 
2.    高级 
3.    管理
基本 memcached 客户机命令
您将使用五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
1.    set 
2.    add 
3.    replace 
4.    get 
5.    delete
前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令。它们都非常简单易用,且都使用清单 5 所示的语法:
清单 5. 修改命令语法
command    

表 1 定义了 memcached 修改命令的参数和用法。
表 1. memcached 修改命令参数
参数    用法
key    key 用于查找缓存值
flags    可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time    在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes    在缓存中存储的字节点
value    存储的值(始终位于第二行)
现在,我们来看看这些命令的实际使用。
set
set 命令用于向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。
注意以下交互,它使用了 set 命令:
set userId 0 0 5
12345
STORED
如果使用 set 命令正确设定了键值对,服务器将使用单词 STORED 进行响应。本示例向缓存中添加了一个键值对,其键为 userId,其值为 12345。并将过期时间设置为 0,这将向 memcached 通知您希望将此值存储在缓存中直到删除它为止。
add
仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。如果缓存中已经存在键,则之前的值将仍然保持相同,并且您将获得响应 NOT_STORED。
下面是使用 add 命令的标准交互:
set userId 0 0 5
12345
STORED

add userId 0 0 5
55555
NOT_STORED

add companyId 0 0 3
564
STORED
replace
仅当键已经存在时,replace 命令才会替换缓存中的键。如果缓存中不存在键,那么您将从 memcached 服务器接受到一条 NOT_STORED 响应。
下面是使用 replace 命令的标准交互:
replace accountId 0 0 5
67890
NOT_STORED

set accountId 0 0 5
67890
STORED

replace accountId 0 0 5
55555
STORED
最后两个基本命令是 get 和 delete。这些命令相当容易理解,并且使用了类似的语法,如下所示:
command 
接下来看这些命令的应用。
get
get 命令用于检索与之前添加的键值对相关的值。您将使用 get 执行大多数检索操作。
下面是使用 get 命令的典型交互:
set userId 0 0 5
12345
STORED

get userId
VALUE userId 0 5
12345
END

get bob
END
如您所见,get 命令相当简单。您使用一个键来调用 get,如果这个键存在于缓存中,则返回相应的值。如果不存在,则不返回任何内容。
delete
最后一个基本命令是 delete。delete 命令用于删除 memcached 中的任何现有值。您将使用一个键调用 delete,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条 NOT_FOUND 消息。
下面是使用 delete 命令的客户机服务器交互:
set userId 0 0 5
98765
STORED

delete bob
NOT_FOUND

delete userId
DELETED

get userId
END
高级 memcached 客户机命令
可以在 memcached 中使用的两个高级命令是 gets 和 cas。gets 和 cas 命令需要结合使用。您将使用这两个命令来确保不会将现有的名称/值对设置为新值(如果该值已经更新过)。我们来分别看看这些命令。
gets
gets 命令的功能类似于基本的 get 命令。两个命令之间的差异在于,gets 返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
下面是使用 gets 命令的客户机服务器交互:
set userId 0 0 5
12345
STORED

get userId
VALUE userId 0 5
12345
END

gets userId
VALUE userId 0 5 4
12345
END
考虑 get 和 gets 命令之间的差异。gets 命令将返回一个额外的值 — 在本例中是整型值 4,用于标识名称/值对。如果对此名称/值对执行另一个 set 命令,则 gets 返回的额外值将会发生更改,以表明名称/值对已经被更新。清单 6 显示了一个例子:
清单 6. set 更新版本指示符
set userId 0 0 5
33333
STORED

gets userId
VALUE userId 0 5 5
33333
END
您看到 gets 返回的值了吗?它已经更新为 5。您每次修改名称/值对时,该值都会发生更改。
cas
cas(check 和 set)是一个非常便捷的 memcached 命令,用于设置名称/值对的值(如果该名称/值对在您上次执行 gets 后没有更新过)。它使用与 set 命令相类似的语法,但包括一个额外的值:gets 返回的额外值。
注意以下使用 cas 命令的交互:
set userId 0 0 5
55555
STORED

gets userId
VALUE userId 0 5 6
55555
END

cas userId 0 0 5 6
33333
STORED
如您所见,我使用额外的整型值 6 来调用 gets 命令,并且操作运行非常顺序。现在,我们来看看清单 7 中的一系列命令:
清单 7. 使用旧版本指示符的 cas 命令
set userId 0 0 5
55555
STORED

gets userId
VALUE userId 0 5 8
55555
END

cas userId 0 0 5 6
33333
EXISTS
注意,我并未使用 gets 最近返回的整型值,并且 cas 命令返回 EXISTS 值以示失败。从本质上说,同时使用 gets 和 cas 命令可以防止您使用自上次读取后经过更新的名称/值对。
缓存管理命令
最后两个 memcached 命令用于监控和清理 memcached 实例。它们是 stats 和 flush_all 命令。
stats
stats 命令的功能正如其名:转储所连接的 memcached 实例的当前统计数据。在下例中,执行 stats 命令显示了关于当前 memcached 实例的信息:
stats
STAT pid 63
STAT uptime 101758
STAT time 1248643186
STAT version 1.4.11
STAT pointer_size 32
STAT rusage_user 1.177192
STAT rusage_system 2.365370
STAT curr_items 2
STAT total_items 8
STAT bytes 119
STAT curr_connections 6
STAT total_connections 7
STAT connection_structures 7
STAT cmd_get 12
STAT cmd_set 12
STAT get_hits 12
STAT get_misses 0
STAT evictions 0
STAT bytes_read 471
STAT bytes_written 535
STAT limit_maxbytes 67108864
STAT threads 4
END
此处的大多数输出都非常容易理解。稍后在讨论缓存性能时,我还将详细解释这些值的含义。至于目前,我们先来看看输出,然后再使用新的键来运行一些 set 命令,并再次运行 stats 命令,注意发生了哪些变化。
flush_all
flush_all 是最后一个要介绍的命令。这个最简单的命令仅用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all 能提供很大的用处。下面是一个使用 flush_all 的例子:
set userId 0 0 5
55555
STORED

get userId
VALUE userId 0 5
55555
END

flush_all
OK

get userId
END
缓存性能
在本文的最后,我将讨论如何使用高级 memcached 命令来确定缓存的性能。stats 命令用于调优缓存的使用。需要注意的两个最重要的统计数据是 et_hits 和 get_misses。这两个值分别指示找到名称/值对的次数(get_hits)和未找到名称/值对的次数(get_misses)。
结合这些值,我们可以确定缓存的利用率如何。初次启动缓存时,可以看到 get_misses 会自然地增加,但在经过一定的使用量之后,这些 get_misses 值应该会逐渐趋于平稳 — 这表示缓存主要用于常见的读取操作。如果您看到 get_misses 继续快速增加,而 get_hits 逐渐趋于平稳,则需要确定一下所缓存的内容是什么。您可能缓存了错误的内容。
确定缓存效率的另一种方法是查看缓存的命中率(hit ratio)。缓存命中率表示执行 get 的次数与错过 get 的次数的百分比。要确定这个百分比,需要再次运行 stats 命令,如清单 8 所示:
清单 8. 计算缓存命中率
stats
STAT pid 6825
STAT uptime 540692
STAT time 1249252262
STAT version 1.2.6
STAT pointer_size 32
STAT rusage_user 0.056003
STAT rusage_system 0.180011
STAT curr_items 595
STAT total_items 961
STAT bytes 4587415
STAT curr_connections 3
STAT total_connections 22
STAT connection_structures 4
STAT cmd_get 2688
STAT cmd_set 961
STAT get_hits 1908
STAT get_misses 780
STAT evictions 0
STAT bytes_read 5770762
STAT bytes_written 7421373
STAT limit_maxbytes 536870912
STAT threads 1
END
现在,用 get_hits 的数值除以 cmd_gets。在本例中,您的命中率大约是 71%。在理想情况下,您可能希望得到更高的百分比 — 比率越高越好。查看统计数据并不时测量它们可以很好地判定缓存策略的效率。
结束语
缓存是任何海量 Web 应用程序不可或缺的部分。我自己成功使用过它好几次。如果您选择使用 memcached 作为缓存解决方案,那么我敢保证您可以看到它的效率如何。










































•    .NET分布式缓存之Memcached执行速度检测
•    http://developer.51cto.com  2009-08-17 16:34  沙加  沙加的博客  我要评论() 
为了解决缓存同步的问题,有人想出了解决办法。本文介绍了.NET分布式缓存Memcached的执行速度,结论是从总体速度上来看Memcached并不慢,而且可使用的内存数量要多得多。
前不久,俺写了篇文章谈到了.Net下面的分布式缓存的一些问题,并结合DNT里面实现模式发表了一些自己的看法,近来通过学习相关的东西又有了一些新的体会, 写在这里作为分布式缓存列系文章的第二部分.
其实对于性的扩展无非是Scale Up(向上扩展)或者是Scale Out(向外扩展), 微软对此的看法是一个App的缓存最好是以它自己为物理边界进行读写,而不要放到别处去,这样带的问题可能有对象的序列化传送,反序列化,网络连接开销,跨进程的开销,对于高性能的站点来说都是不能忽视的问题.出于对这些因素的考虑微推荐的作法不是把多个应用放在一起在多台Server布署,而是将一个App划分成若干个小的应用布署到不同的服务器,下面的关系图展示了这种关系, 这样每种应用就可以独立管理自己的缓存数据,但是对于象用户数据这样的通用数据仍然会存在多处.
.NET分布式缓存:两种解决方案
为了解决缓存同步的问题,有人想出了解决办法, 可以参考这两个地方,这个是MS的,这里还有一个,先来看看Peter的这个吧, 主要思想就是把要放到缓存里面的东西加上一层包装CacheControlItem, 实现代码请去原文出处下载.
每台机器都维护一个WebFarm里面的成员服务器的列表,如果有新的服务器进来发现自己不在这个列表中则会通知其它的服务器把它加到这个名单里面。添加缓存的这程是这样, A服务器需要插入一个新的缓存值,它把这个项目插入到自己的缓存中,然后用它初始化一个CacheControlItem并指定它的缓存策略(优先级,缓存生存时间),设定它的动作,即添加,然后把这个结象序列化通过Web传送到每一个成员服务器,接受到这些数据的服务器跟据这个对象的Action指令,把反序列化后的对象加入到自己的缓存里面,这样一个同步的过程就完成了,移除缓存对象的过程与之类似,只不过不需要传送对象,只在包装类里面设定它的Action为删除就可以了. 当然,为了提高性能,可以实现一个异步的侦听线程专门用来响应缓存通知的请求. 总体上讲这处办法的效率比较低,在数据量较大的情况下可能会造成大量缓存数据的同步数据流。
我们再来看看M$是怎么做的,它的想法类似,只不过它不在WebFarm的成员服务器之间同步缓存,而只是保证每台机器不要读到已经失效的缓存数据,当缓存数据失效时(相关依赖数据被更新), 通过维护一个需要通知的服务器列表依次调用每台服务器上的WebService,如果当前服务器上存在这键值的缓存则使它失效. 
这两个老外写的东西似乎都比较啰索,不过对初学者来说比较友好,可以一步步地知道这件事情的来龙去脉,理解会清楚更刻一些。
.NET分布式缓存:Memcached到底有多快?
看了这些如果还不满意,那么您可以试试Memcached它可以运行在Win32平台下,在上篇文章中我们已经提到了这个东西,但是它在.Net的平台下面究竟表现如何?是否能象在PHP平台下面一样地优秀,我们现在来做一个简单的测试, 对比使用.Net自带的Cache和Memcached两种实现方式,看看差距究竟有多大,过程是这样,分别生成10000个字符串对象并分别设定键值插入到缓存中,然后再取出来,看看花费的总时间. 服务器端:memcached-1.2.1-win32, 客户端: memcacheddotnet_clientlib-1.1.5, 服务器端的使用也比较简单,解压文件之后在命令行下面输入: c:\memcached -d install 先安装服务, 接着 c:\memcached -d start就可以了,详细使用方法见说明文件 -h 是查看帮助, 测试环境如下:
Memcached服务器 : Win2003 sp1, Framework 2.0,P4 D 3.4G, 768MB 内存, 千兆网卡. 
Memcached客户机 : Win2003 sp1, Framework 2.0,T2060, 1G内存( 沙加的神舟笔记本;) ), 千兆网卡.
两台机器通过直连线相连.
.Net Cache单机测试 : P4 D 3.4G, 768MB 内存. 
测试结果, 存取10000个条目的时间: 
1.    Memcached  
2.    Set(秒)  1.48  1.37  1.48  1.37  1.46    
3.    Get(秒)  2.42 2.42  2.42  2.43  2.42    
4.     
5.    HttpRuntime.Cache  
6.    Set(秒)  0.015  0.015  0.015  0.015  0.015    
7.    Get(秒)  
8.     0.015 0.015  0.015  0.015  0.015    
.Net内建缓存测试代码
HttpRuntime.Cache
9.    protected void Page_Load(object sender, EventArgs e)  
10.    {  
11.            int start = 200;  
12.            int runs = 10000;  
13.     
14.            string keyBase = "testKey";  
15.            string obj = "This is a test of an object blah blah es, serialization does not seem to slow things down so much.  The gzip compression is horrible horrible performance, so we only use it for very large objects.  I have not done any heavy benchmarking recently";  
16.     
17.            long begin = DateTime.Now.Ticks;  
18.            for(int i = start; i < start+runs; i++)   
19.            {  
20.                HttpRuntime.Cache.Add(keyBase + i, obj,null,System.Web.Caching.Cache.NoAbsoluteExpiration,  
21.                    TimeSpan.FromMinutes(1),System.Web.Caching.CacheItemPriority.Normal,null);  
22.            }  
23.            long end = DateTime.Now.Ticks;  
24.            long time = end - begin;  
25.     
26.            Response.Write(runs + " sets: " + new TimeSpan(time).ToString() + "ms<br />");  
27.     
28.            begin = DateTime.Now.Ticks;  
29.            int hits = 0;  
30.            int misses = 0;  
31.            for(int i = start; i < start+runs; i++)   
32.            {  
33.                string str = (string) HttpRuntime.Cache.Get(keyBase + i);  
34.                if(str != null)  
35.                    ++hits;  
36.                else 
37.                    ++misses;  
38.            }  
39.            end = DateTime.Now.Ticks;  
40.            time = end - begin;  
41.     
42.            Response.Write(runs + " gets: " + new TimeSpan(time).ToString() + "ms");  
43.    }  
Memcached测试代码
Memcached
44.    namespace Memcached.MemcachedBench  
45.    {  
46.        using System;  
47.        using System.Collections;  
48.     
49.        using Memcached.ClientLibrary;  
50.     
51.        public class MemcachedBench   
52.        {  
53.            [STAThread]  
54.            public static void Main(String[] args)   
55.            {  
56.                int runs = 100;  
57.                int start = 200;  
58.                if(args.Length > 1)  
59.                {  
60.                    runs = int.Parse(args[0]);  
61.                    start = int.Parse(args[1]);  
62.                }  
63.     
64.                string[] serverlist = { "140.192.34.72:11211", "140.192.34.73:11211" };  
65.     
66.                // initialize the pool for memcache servers  
67.                SockIOPool pool = SockIOPool.GetInstance();  
68.                pool.SetServers(serverlist);  
69.     
70.                pool.InitConnections = 3;  
71.                pool.MinConnections = 3;  
72.                pool.MaxConnections = 5;  
73.     
74.                pool.SocketConnectTimeout = 1000;  
75.                pool.SocketTimeout = 3000;  
76.     
77.                pool.MaintenanceSleep = 30;  
78.                pool.Failover = true;  
79.     
80.                pool.Nagle = false;  
81.                pool.Initialize();  
82.     
83.                MemcachedClient mc = new MemcachedClient();  
84.                mc.EnableCompression = false;  
85.     
86.                string keyBase = "testKey";  
87.                string obj = "This is a test of an object blah blah es, serialization does not seem to slow things down so much.  The gzip compression is horrible horrible performance, so we only use it for very large objects.  I have not done any heavy benchmarking recently";  
88.     
89.                long begin = DateTime.Now.Ticks;  
90.                for(int i = start; i < start+runs; i++)   
91.                {  
92.                    mc.Set(keyBase + i, obj);  
93.                }  
94.                long end = DateTime.Now.Ticks;  
95.                long time = end - begin;  
96.     
97.                Console.WriteLine(runs + " sets: " + new TimeSpan(time).ToString() + "ms");  
98.     
99.                begin = DateTime.Now.Ticks;  
100.                int hits = 0;  
101.                int misses = 0;  
102.                for(int i = start; i < start+runs; i++)   
103.                {  
104.                    string str = (string) mc.Get(keyBase + i);  
105.                    if(str != null)  
106.                        ++hits;  
107.                    else 
108.                        ++misses;  
109.                }  
110.                end = DateTime.Now.Ticks;  
111.                time = end - begin;  
112.     
113.                Console.WriteLine(runs + " gets: " + new TimeSpan(time).ToString() + "ms");  
114.                Console.WriteLine("Cache hits: " + hits.ToString());  
115.                Console.WriteLine("Cache misses: " + misses.ToString());  
116.     
117.                IDictionary stats = mc.Stats();  
118.                foreach(string key1 in stats.Keys)  
119.                {  
120.                    Console.WriteLine(key1);  
121.                    Hashtable values = (Hashtable)stats[key1];  
122.                    foreach(string key2 in values.Keys)  
123.                    {  
124.                        Console.WriteLine(key2 + ":" + values[key2]);  
125.                    }  
126.                    Console.WriteLine();  
127.                }  
128.     
129.                SockIOPool.GetInstance().Shutdown();  
130.            }  
131.        }  
132.    }  
结论
通过这个对比测试我们可以看出内建的Cache比使用Memcached要快出约130倍,但是从总体速度上来看Memcached并不慢,这两种方式可以在项目中有选择性地结合使用可以产生很棒的效果.并且Memcached可使用的内存数量要多得多,同时也可以做集群避免单点问题. 
以上就介绍了.NET分布式缓存之Memcached的速度检测。本文来自沙加的博客:《.Net下的分布式缓存(2)--实现分布式缓存同步的手段》



















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="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />

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

        </logger>
    </log4net>
启动调试,若没出现配置的出错提示,并且在网站目录下有文件夹LogFiles,就说明log4net配置成功了。
 五,初始化SockIOPool
SockIOPool是什么东东?SockIOPool是Memcached客户端提供的一个套接字连接池,通俗讲,就是与Memcached服务器端交换数据的对象。SockIOPool在应用程序启动时初始化一次就可以了,我把这个工作放在 GLOBAL.ASAX.CS的Application_Start方法里
char[] separator = { ',' };
            string[] serverlist = ConfigurationManager.AppSettings["Memcached.ServerList"].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["Memcached.ServerList"]是在WEB.CONFIG里设置的,所以WEB.CONFIG的appSettings的子节点里需要有以下一行
<add key="Memcached.ServerList" value="127.0.0.1:11211"/>
启动调试服务器,若没有出错的日志记录,说明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);等等。可以自己琢磨了。

         以上只是演示,其实数据缓存是一项复杂而繁琐的工作,不仅需要后台代码的分层优化,也需要数据库对大数据量访问的策略和调优。