memcache实战之二 :客户端 Memcached Providers 1.2 for .net 2.0 的安装与调试以及实例,curr_items 和 total_items的区别
下载地址 http://memcachedproviders.codeplex.com/
要注意这个页面,提供了客户端 Memcached Providers 1.2 和 服务器端的4个版本的下载地址,我们在上一节,已经下载好了服务器端并安装好了,所以不用管服务器端,只要安装好客户端即可。下载的时候,有一个pdf格式的说明文档,是教我们如何来配置 web.config和如何使用 memcache来增删查改的,非常之简单
另外,Memcached Providers 1.2 也分为 .net 2.0 3.5 2个版本,这里是以 2.0 为例。 3.5应该不会有太大的区别.
然后我们打开看看
我们需要 Enyim.Caching.dll log4net.dll MemcachedProviders.dll 这3个dll文件,拷入到我们需要使用的项目中的bin文件夹,并在项目中引用这3个dll
然后配置我们的 web.config
<?xml version="1.0"?> <configuration> <!--Memcached Providers客户端的配置1 开始--> <configSections> <section name="cacheProvider" type="MemcachedProviders.Cache.CacheProviderSection, MemcachedProviders" allowDefinition="MachineToApplication" restartOnExternalChanges="true"/> <sectionGroup name="enyim.com"> <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" /> </sectionGroup> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--Memcached Providers客户端的配置1 结束--> <!--Memcached Providers客户端的配置2 开始--> <enyim.com> <memcached> <servers> <!-- put your own server(s) here--> <add address="127.0.0.1" port="11211" /> <!--<add address="127.0.0.1" port="11555" /> <add address="211.174.120.256" port="11211" /> <add address="202.96.147.122" port="11211" />--> </servers> <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" /> </memcached> </enyim.com> <!--Memcached Providers客户端的配置2 结束--> <!--Memcached Providers客户端的配置3 开始--> <cacheProvider defaultProvider="MemcachedCacheProvider"> <providers> <add name="MemcachedCacheProvider" type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders" keySuffix="_MySuffix_" defaultExpireTime="2000"/> </providers> </cacheProvider> <!--Memcached Providers客户端的配置3 结束--> <!--Memcached Providers客户端的配置4 开始--> <log4net> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}]- %message%newline" /> </layout> </appender> <root> <priority value="WARN"/> <appender-ref ref="ConsoleAppender"> <filter type="log4net.Filter.LevelRangeFilter"> <levelMin value="WARN"/> <levelMax value="FATAL"/> </filter> </appender-ref> </root> </log4net> <!--Memcached Providers客户端的配置4 结束 下面的 都是和 Memcached Providers 配置无关的--> <appSettings /> <connectionStrings /> <system.web> <compilation debug="true">
如果我们配置了多个Memcached的实例,可以想上面的注释部分那样在<servers>节点下添加多个Memcached的实例配置。
这里需要说明的是如果我们需要向Memcached中添加自定义数据类型时,我们需要将该数据类型添加上[Serializable]标记。因为服务器端数据都是byte型的数据组实现存在。
/// <summary>测试用的人类 /// /// </summary> [Serializable] public class Person { public string Id { set; get; } public string Username { set; get; } }
下面开始使用memcached 的API
1. 在项目中引入MemcachedProviders.Cache 命名空间
using MemcachedProviders.Cache;
2. 获取缓存
object objCache = DistCache.Get(cacheKey);
3. 增加到缓存
// 增加缓存(如果不带过期时间,Memcached将根据LRU来决定过期策略,而不是根据过期时间来执行)
DistCache.Add(cacheKey, cacheValue);
//增加缓存,根据过期时间来执行
DistCache.DefaultExpireTime = 3000; //缓存时间按照毫秒计算,这里是 3秒
//带过期时间的缓存,会根据过期时间来失效 DistCache.Add(per.Id, per, DistCache.DefaultExpireTime);
// 缓存60 秒
DistCache.Add(cacheKey, cacheValue, 60 * 1000);
//缓存至今天结束
DistCache.Add(cacheKey, cacheValue, DateTime.Today.AddDays(1) - DateTime.Now);
如果有多个DistCache.Add 并且都是用的同一个 cachekey,那么如果你保存的值有变化,他会替换掉以前的,相当于是做了一个 update更新一样,并且这个时候,curr_items 不变,total_items 会增加。(也就是说 当SET一个已有的ITEM时,total_items 会加1,curr_items 不会改变)
4. 移除Cache 项目
DistCache.Remove(cacheKey);
5. 移除所有Cache 项目
DistCache.RemoveAll();
我发现个很奇怪的现象, 就算是 DistCache.RemoveAll 或者是直接在 dos界面下 flush_all 都不会对 curr_items 和 total_items 有影响,例如本来我已经缓存了6个键值对,键的名字分别是1,2,3,4,5,6 然后我清空了,但是这里还是显示6个。然后我试着增加我之前增加过的键值对的名字,例如,1,2,3之类的,curr_items都不会增加。除非我再输入一个和以前的名字都不一样的名字,例如增加缓存名字为7的键值对,他的个数就变成7了,而total_items 则是你每次清空后,只要是有增加缓存的,他都会再次添加个数,不管你会不会和以前重复。
我举个例子
键值对 1 joey1
2 joey2
3 joey3
那么,再我清空之后,curr_items还是3,我再添加一个 ( 2 随便什么值 ) 这样的一个键值对,那么curr_items的个数 还是3,但是total_items的个数会变成4个
也就是说,如果 清空后,或者是失效后,再次增加的键值对的名字,和以前的一样,curr_items 就不会增加,哪怕是修改的时候,键值对的值已经改变了,他也不会增加 但是total_items 则不同,只要你有清空或者是失效或者是修改,那么就会增加.
telnet 192.168.1.2 11211
stats
----------------------------------------
STAT pid 3932 --进程ID
STAT uptime 137
STAT time 1207723245
STAT version 1.2.1 --版本号
STAT pointer_size 32
STAT curr_items 999999 --当前ITEM 激活中的缓存的数量。
STAT total_items 999999 --从服务器开机以来的总的ITEM数量
STAT bytes 51888843
STAT curr_connections 5 --当前连接数
STAT total_connections 6 --总连接数
STAT connection_structures 6
STAT cmd_get 0 --进行GET的次数
STAT cmd_set 999999 --进行SET的次数
STAT get_hits 0 --命中数
STAT get_misses 0 --命中失败数
STAT bytes_read 24888902
STAT bytes_written 8000378
STAT limit_maxbytes 524288000 --分配的总内存空间
END
最后附加上网站结构和代码
前台界面
后台代码
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using MemcachedProviders.Cache;// 引用类库MemcachedProviders namespace My_MemcachedProviders { public partial class _Default : System.Web.UI.Page { List<Person> listp = new List<Person> { }; protected void Page_Load(object sender, EventArgs e) { //初始化几个人 for (int i = 0; i < 10; i++) { listp.Add(new Person() { Id = i.ToString(), Username = "随便什么值" + i }); } } //每次搜索的时候,判断缓存里面有没有这个人,有的话,直接读缓存,没有的话,就增加到缓存 protected void Search(object sender, EventArgs e) { string id = txtId.Text.Trim(); Person per = null; for (int i = 0; i < listp.Count; i++) { if (listp[i].Id == id) { per = listp[i]; DistCache.DefaultExpireTime = 3000; //3秒 //如果缓存不存在,我们就把person这个实体放进去 if (DistCache.Get(per.Id) == null) { //存值 --不带过期时间的存储,Memcached将根据LRU来决定过期策略 DistCache.Add(per.Id, per); //带过期时间的缓存,会根据过期时间来失效 //DistCache.Add(per.Id, per, DistCache.DefaultExpireTime); //如果这里2个都运行,那么第二行就相当于是对原来的数据的更新 litType.Text = "从数据库读,并增加到缓存"; litResult.Text = per.Username; } else { litType.Text = "从缓存来读"; Person temp = (Person)DistCache.Get(per.Id); litResult.Text = temp.Username; } } } } //清空缓存 protected void btnClear_Click(object sender, EventArgs e) { DistCache.RemoveAll(); litType.Text = ""; litResult.Text = "清除所有缓存"; } } }
代码下载地址
MemcachedProviders for .net 2.0 的客户端的实例 http://download.csdn.net/detail/lihuabajie/4690044
如果是需要 Enyim.Caching 客户端的,可以看看我下面的这个2个例子
1:我自己写的的例子 http://download.csdn.net/detail/lihuabajie/4689835 (我这个里面的Enyim.Caching 既可以支持.net 2.0也支持3.5)
2:我参考的实例 http://download.csdn.net/detail/lihuabajie/4690399
PS:有看到其他的程序员提到说, Memcached Provider 不支持中文 Cache Key 的问题 (是有其他人反应有这个情况,但是我自己测试是没有这个问题的,是可以支持中文的)
问题如下:
举个简单例子,假设我们有两个 Cache Key 分别为:
Poll_投票结果
Poll_题目资料
而实际储存到 memcached 中的 Cache Key 将会是 Poll_ 而已,由于遇到转型失败的缓存都会预设为 null,
因此可能会让你在执行时期也不会发生问题,只是缓存机制无法运作导致效能减低而已
解决方法:选用其他 KeyTransformer 即可正确处理 Cache Key 文字无法转换的问题
切换不同的 KeyTransformer 可以参考以下设定,只要修改 web.config 即可
<enyim.com> <memcached keyTransformer="Enyim.Caching.Memcached.SHA1KeyTransformer, Enyim.Caching"> <!--也就是这里多了一些--> <servers> <add address="127.0.0.1" port="11211" /> </servers> <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" /> </memcached> </enyim.com>