zoukankan      html  css  js  c++  java
  • Redis作为缓存服务器

      1、ICache的Redis实现没有放在'Framework.Cache/Logic'中。如果是以前,我会认为这样不好。我会这样做,'Framework.Cache'项目引用Redis项目或直接从Nuget安装Redis,

    把实现定义在‘Framework.Cache/Logic’中,这样结构看起来很顺眼,‘这算是高内聚么!!!’。不过自从接触了IOC后,现在这样的结构似乎也很合理,没什么违和感。

    这就好似把‘IRepository’和‘Repositories’,一个放在Domain,一个放在Infrastructure

      2、当前比较稳定的Redis客户端(开源的程序包)有ServiceStack.Redis 和 StackExchange.Redis。我都用了一下,ServiceStatck的

    比较好用,不过我感觉后者的性能应该会稍好点

      3、关于ServiceStack.Redis中的接口,IRedisClient,ICacheClient,IRedisTypedClient<T>,IEntityStore<T>,IEntityStore。

    这些“乱七八糟”的接口和CRUD都有关系,中的有些方法看似好像是重复的,后续希望能整理出一篇结合源码,理论点的文章

      

    一、Framework.Cache

    接口ICache,定义缓存操作开放的方法

     1     public interface ICache
     2     {
     3         /// <summary>
     4         /// Gets all entries in the cache
     5         /// </summary>
     6         IEnumerable<KeyValuePair<string, object>> Entries { get; }
     7 
     8         /// <summary>
     9         /// Gets a cache item associated with the specified key or adds the item
    10         /// if it doesn't exist in the cache.
    11         /// </summary>
    12         /// <typeparam name="T">The type of the item to get or add</typeparam>
    13         /// <param name="key">The cache item key</param>
    14         /// <param name="baseMethod">Func which returns value to be added to the cache</param>
    15         /// <returns>Cached item value</returns>
    16         T Get<T>(string key, Func<T> baseMethod);
    17 
    18         /// <summary>
    19         /// Gets a cache item associated with the specified key or adds the item
    20         /// if it doesn't exist in the cache.
    21         /// </summary>
    22         /// <typeparam name="T">The type of the item to get or add</typeparam>
    23         /// <param name="key">The cache item key</param>
    24         /// <param name="baseMethod">Func which returns value to be added to the cache</param>
    25         /// <param name="cacheTime">Expiration time in minutes</param>
    26         /// <returns>Cached item value</returns>
    27         T Get<T>(string key, Func<T> baseMethod, int cacheTime);
    28 
    29         /// <summary>
    30         /// Gets a value indicating whether an item associated with the specified key exists in the cache
    31         /// </summary>
    32         /// <param name="key">key</param>
    33         /// <returns>Result</returns>
    34         bool Contains(string key);
    35 
    36         /// <summary>
    37         /// Removes the value with the specified key from the cache
    38         /// </summary>
    39         /// <param name="key">/key</param>
    40         void Remove(string key);
    41     }

    二、基于‘ServiceStack.Redis’的缓存实现

     1 public class SSRedisCache : ICache
     2     {
     3         private const string REGION_NAME = "$#SSRedisCache#$";
     4         private const int _DefaultCacheTime = 30;
     5         private readonly static object s_lock = new object();
     6 
     7         private IRedisClient GetClient()
     8         {
     9             return RedisManager.GetClient();
    10         }
    11 
    12         private IRedisClient GetReadOnlyClient()
    13         {
    14             return RedisManager.GetReadOnlyClient();
    15         }
    16 
    17         public IEnumerable<KeyValuePair<string, object>> Entries
    18         {
    19             get { throw new NotImplementedException(); }
    20         }
    21 
    22         public T Get<T>(string key, Func<T> baseMethod)
    23         {
    24             return Get<T>(key, baseMethod, _DefaultCacheTime);
    25         }
    26 
    27         public T Get<T>(string key, Func<T> baseMethod, int cacheTime)
    28         {
    29             using (var redisClient = GetClient())
    30             {
    31                 key = BuildKey(key);
    32 
    33                 if (redisClient.ContainsKey(key))
    34                 {
    35                     return redisClient.Get<T>(key);
    36                 }
    37                 else
    38                 {
    39                     lock (s_lock)
    40                     {
    41                         if (!redisClient.ContainsKey(key))
    42                         {
    43                             var value = baseMethod();
    44                             if (value != null) //请区别null与String.Empty
    45                             {
    46                                 redisClient.Set<T>(key, value, TimeSpan.FromMinutes(cacheTime));
    47                                 //redisClient.Save();
    48                             }
    49                             return value;
    50                         }
    51                         return redisClient.Get<T>(key);
    52                     }
    53                 }
    54             }
    55         }
    56 
    57         public bool Contains(string key)
    58         {
    59             using (var redisClient = GetReadOnlyClient())
    60             {
    61                 return redisClient.ContainsKey(BuildKey(key));
    62             }
    63         }
    64 
    65         public void Remove(string key)
    66         {
    67             using (var redisClient = GetClient())
    68             {
    69                 redisClient.Remove(BuildKey(key));
    70             }
    71         }
    72 
    73         private string BuildKey(string key)
    74         {
    75             return string.IsNullOrEmpty(key) ? null : REGION_NAME + key;
    76         }
    77 
    78     }

    三、基于‘StackExchange.Redis’的缓存实现

    1 <?xml version="1.0" encoding="utf-8"?>
    2 <packages>
    3   <package id="MsgPack.Cli" version="0.6.8" targetFramework="net45" />
    4   <package id="StackExchange.Redis" version="1.0.488" targetFramework="net45" />
    5   <package id="StackExchange.Redis.Extensions.Core" version="1.3.2.0" targetFramework="net45" />
    6   <package id="StackExchange.Redis.Extensions.MsgPack" version="1.3.2.0" targetFramework="net45" />
    7 </packages>
     1 public class SERedisCache : ICache
     2     {
     3         private const string REGION_NAME = "$#SERedisCache#$";
     4         private const int _DefaultCacheTime = 30;
     5         private readonly static object s_lock = new object();
     6 
     7         private StackExchangeRedisCacheClient GetClient()
     8         {
     9             return new StackExchangeRedisCacheClient(RedisServer.Connection, new MsgPackObjectSerializer());
    10         }
    11 
    12         public IEnumerable<KeyValuePair<string, object>> Entries
    13         {
    14             get { throw new NotImplementedException(); }
    15         }
    16 
    17         public T Get<T>(string key, Func<T> baseMethod)
    18         {
    19             return Get(key, baseMethod, _DefaultCacheTime);
    20         }
    21 
    22         public T Get<T>(string key, Func<T> baseMethod, int cacheTime)
    23         {
    24             using (var cacheClient = GetClient())
    25             {
    26                 key = BuildKey(key);
    27 
    28                 if (cacheClient.Exists(key))
    29                 {
    30                     return cacheClient.Get<T>(key);
    31                 }
    32                 else
    33                 {
    34                     lock (s_lock)
    35                     {
    36                         if (!cacheClient.Exists(key))
    37                         {
    38                             var value = baseMethod();
    39                             if (value != null) //请区别null与String.Empty
    40                             {
    41                                 cacheClient.Add<T>(key, value, TimeSpan.FromMinutes(cacheTime));
    42                             }
    43                             return value;
    44                         }
    45                         return cacheClient.Get<T>(key);
    46                     }
    47                 }
    48             }
    49         }
    50 
    51         public bool Contains(string key)
    52         {
    53             using (var cacheClient = GetClient())
    54             {
    55                 return cacheClient.Exists(BuildKey(key));
    56             }
    57         }
    58 
    59         public void Remove(string key)
    60         {
    61             using (var cacheClient = GetClient())
    62             {
    63                 cacheClient.Remove(BuildKey(key));
    64             }
    65         }
    66 
    67         private string BuildKey(string key)
    68         {
    69             return string.IsNullOrEmpty(key) ? null : REGION_NAME + key;
    70         }
    71 
    72     }

    完整代码(稍后) 会在另一篇文章关于Web API中附上

  • 相关阅读:
    623. Add One Row to Tree 将一行添加到树中
    771. Jewels and Stones 珠宝和石头
    216. Combination Sum III 组合总数三
    384. Shuffle an Array 随机播放一个数组
    382. Linked List Random Node 链接列表随机节点
    向github项目push代码后,Jenkins实现其自动构建
    centos下安装Jenkins
    python提取批量文件内的指定内容
    批处理实现:批量为文件添加注释
    python抓取每期双色球中奖号码,用于分析
  • 原文地址:https://www.cnblogs.com/frozenzhang/p/5439940.html
Copyright © 2011-2022 走看看