zoukankan      html  css  js  c++  java
  • memcache实战之二 :客户端 Memcached Providers 1.2 for .net 2.0 的安装与调试以及实例,curr_items 和 total_items的区别

    下载地址  http://memcachedproviders.codeplex.com/

    image

    要注意这个页面,提供了客户端   Memcached Providers 1.2   和 服务器端的4个版本的下载地址,我们在上一节,已经下载好了服务器端并安装好了,所以不用管服务器端,只要安装好客户端即可。下载的时候,有一个pdf格式的说明文档,是教我们如何来配置 web.config和如何使用 memcache来增删查改的,非常之简单

    另外,Memcached Providers 1.2  也分为 .net  2.0   3.5  2个版本,这里是以 2.0 为例。 3.5应该不会有太大的区别.

    image

    然后我们打开看看

    image 

    我们需要 Enyim.Caching.dll   log4net.dll  MemcachedProviders.dll  这3个dll文件,拷入到我们需要使用的项目中的bin文件夹,并在项目中引用这3个dll

    image

    然后配置我们的 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 则不同,只要你有清空或者是失效或者是修改,那么就会增加.

    image

    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

    最后附加上网站结构和代码

    image

    前台界面

    image

    后台代码

    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>
    
  • 相关阅读:
    用GUI完成了斗地主发牌
    地主发牌
    用三种循环完成了累加
    DataSet、DataTable、DataRow的数据复制方法
    C# Merge into的使用详解
    grid+report 怎么在项目中使用
    SQL Server 2008 R2:error 26 开启远程连接详解
    EF框架的优点是什么?
    Oracle中的case when then else end 应用
    SQL中的case when then else end用法
  • 原文地址:https://www.cnblogs.com/joeylee/p/2735974.html
Copyright © 2011-2022 走看看