Redis缓存、MemCached和.Net内部缓存的切换使用

接口文件:

//IDataCache.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ypsuit.common
{
    public interface IDataCache
    {
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">缓存key</param>
        /// <returns></returns>
        T Get<T>(string key);
        T Get<T>(string key,string depFile);

        /// <summary>
        /// 写入缓存
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">缓存key</param>
        /// <param name="value">缓存值</param>
        /// <returns>返回值,表示:是否写入成功</returns>
        bool Set<T>(string key, T value);

        /// <summary>
        /// 写入缓存,设置过期时间点
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">缓存key</param>
        /// <param name="value">缓存值</param>
        /// <param name="expiresAt">过期时间点</param>
        /// <returns>返回值,表示:是否写入成功</returns>
        bool Set<T>(string key, T value, DateTime expiresAt);

        /// <summary>
        /// 写入缓存,设置过期秒数
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">缓存key</param>
        /// <param name="value">缓存值</param>
        /// <param name="expiresSecond">过期秒数</param>
        /// <returns>返回值,表示:是否写入成功</returns>
        bool Set<T>(string key, T value, int expiresSecond);

        bool Set<T>(string key, T value, string depFile);

        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key">缓存key</param>
        /// <returns></returns>
        int Delete(string key);

        /// <summary>
        /// 删除多个缓存
        /// </summary>
        /// <param name="keys">缓存key数组</param>
        /// <returns></returns>
        int Delete(string[] keys);
    }
}

//实现文件
//RedisCache.cs

using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace ypsuit.common
{
    /// <summary>
    /// Redis缓存服务器
    /// 服务器和客户端下载:
    ///  https://github.com/MSOpenTech/redis/releases
    ///  https://github.com/ServiceStack/ServiceStack.Redis
    /// </summary>
    public class RedisCache : IDataCache
    {
        private static RedisClient _redis = null;
        public static RedisClient redis
        {
            get
            {
                if (_redis == null) _redis = new RedisClient("192.168.9.128", 6379);//要开启服务器才能连接
                return _redis;
            }
        }

        ~RedisCache()
        {
            //if (_redis != null) _redis.Shutdown();
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">类型(对象必须可序列化,否则可以作为object类型取出再类型转换,不然会报错)</typeparam>
        /// <param name="key">缓存key</param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            return redis.Get<T>(key);
        }
        public T Get<T>(string key, string depFile)
        {
            string timeKey = key + "_time";
            if (redis.Exists(timeKey) > 0 && redis.Exists(key) > 0)
            {
                DateTime obj_time = Get<DateTime>(timeKey);
                T obj_cache = Get<T>(key);
                if (File.Exists(depFile))
                {
                    FileInfo fi = new FileInfo(depFile);
                    if (obj_time != fi.LastWriteTime)
                    {
                        Delete(key);
                        Delete(timeKey);
                        return default(T);
                    }
                    else return obj_cache;
                }
                else
                {
                    throw new Exception("文件(" + depFile + ")不存在!");
                }
            }
            else return default(T);

        }

        public bool Set<T>(string key, T value)
        {
            return redis.Set<T>(key, value);
        }
        public bool Set<T>(string key, T value, DateTime expiresAt)
        {
            return redis.Set<T>(key, value, expiresAt);
        }

        public bool Set<T>(string key, T value, int expiresSecond)
        {
            return redis.Set<T>(key, value, DateTime.Now.AddSeconds(expiresSecond));
        }

        public bool Set<T>(string key, T value, string depFile)
        {
            bool ret1 = redis.Set<T>(key, value);
            if (ret1 && File.Exists(depFile))
            {
                FileInfo fi = new FileInfo(depFile);
                DateTime lastWriteTime = fi.LastWriteTime;
                return redis.Set<DateTime>(key + "_time", lastWriteTime);
            }
            return false;
        }

        public int Delete(string key)
        {
            return redis.Del(key);
        }
        public int Delete(string[] keys)
        {
            return redis.Del(keys);
        }
        public void Dispose()
        {
            if (_redis != null) _redis.Shutdown();//调用Dispose释放memcached客户端连接
        }

    }
}

//实现文件

//MemcachedCache.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Memcached.ClientLibrary;
using System.IO;

namespace ypsuit.common
{
    public class MemcachedCache:IDataCache
    {
        private MemcachedClient _mc =null;
        protected MemcachedClient mc
        {
            get
            {
                if(_mc==null) _mc=new MemcachedClient();//初始化一个客户端
                return _mc;
            }
        }
        /// <summary>
        /// 如果默认不是本地服务,可以额外指定memcached服务器地址
        /// </summary>
        public static string[] serverList
        {
            get;
            set;
        }
        private static MemcachedCache _instance = null;
        /// <summary>
        /// 单例实例对象,外部只能通过MemcachedHelper.instance使用memcached
        /// </summary>
        public static MemcachedCache instance
        {
            get
            {
                if (_instance == null)
                {
                    if (serverList != null && serverList.Length > 0)
                        _instance = new MemcachedCache(serverList);
                    else _instance = new MemcachedCache();
                }

                return _instance;
            }
        }
        SockIOPool pool;
        private void start(params string[]servers)
        {
            string[] serverlist;
            if (servers == null || servers.Length < 1)
            {
                serverlist = new string[] { "127.0.0.1:11011" }; //服务器列表,可多个
            }
            else
            {
                serverlist=servers;
            }
            pool = SockIOPool.GetInstance();

            //根据实际情况修改下面参数
            pool.SetServers(serverlist);
            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(); // initialize the pool for memcache servers
        }
        public MemcachedCache(string[] servers)
        {
            start(servers);
        }
        public MemcachedCache()
        {
            start();
        }
        ~MemcachedCache()
        {
            //if (pool != null) pool.Shutdown();
        }

        public T Get<T>(string key)
        {
            object data = mc.Get(key);
            if (data is T) return (T)data;
            else return default(T);
        }
        public T Get<T>(string key, string depFile)
        {
            string timeKey = key + "_time";
            if (mc.KeyExists(timeKey) && mc.KeyExists(key))
            {
                DateTime obj_time = Get<DateTime>(timeKey);
                T obj_cache = Get<T>(key);
                if (File.Exists(depFile))
                {
                    FileInfo fi = new FileInfo(depFile);
                    if (obj_time != fi.LastWriteTime)
                    {
                        Delete(key);
                        Delete(timeKey);
                        return default(T);
                    }
                    else return obj_cache;
                }
                else
                {
                    throw new Exception("文件(" + depFile + ")不存在!");
                }
            }
            else return default(T);

        }
        public bool Set<T>(string key, T value)
        {
            return mc.Set(key, value);
        }
        public bool Set<T>(string key, T value, DateTime expiresAt)
        {
            return mc.Set(key, value, expiresAt);
        }

        public bool Set<T>(string key, T value, int expiresSecond)
        {
            return mc.Set(key, value, DateTime.Now.AddSeconds(expiresSecond));
        }

        public bool Set<T>(string key, T value, string depFile)
        {
            bool ret1 = mc.Set(key, value);
            if (ret1 && File.Exists(depFile))
            {
                FileInfo fi = new FileInfo(depFile);
                DateTime lastWriteTime = fi.LastWriteTime;
                return mc.Set(key + "_time", lastWriteTime);
            }
            return false;
        }

        public int Delete(string key)
        {
            return mc.Delete(key)?1:0;
        }
        public int Delete(string[] keys)
        {
            int i = 0;
            foreach (var key in keys)
            {
                mc.Delete(key);
                i++;
            }
            return i;
        }
        //在应用程序退出之前,调用Dispose释放memcached客户端连接
        public void Dispose()
        {
            if (pool != null) pool.Shutdown();
        }
    }
}

//实现文件

//RuntimeCache.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace ypsuit.common
{
    public class RuntimeCache : IDataCache
    {

        #region 删除缓存
        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="CacheKey">键</param>
        public int Delete(string CacheKey)
        {
            HttpRuntime.Cache.Remove(CacheKey);
            return 1;
        }
        public int Delete(string[] CacheKeys)
        {
            int i = 0;
            foreach (var key in CacheKeys)
            {
                HttpRuntime.Cache.Remove(key);
                i++;
            }
            return i;
        }
        #endregion

        #region 获取缓存,依赖时间
        /// <summary>
        /// 获取缓存,依赖时间
        /// </summary>
        /// <param name="CacheKey">键</param>
        /// <returns></returns>
        public T Get<T>(string CacheKey)
        {
            object obj_time = HttpRuntime.Cache[CacheKey + "_time"];
            object obj_cache = HttpRuntime.Cache[CacheKey];
            if (obj_time != null && obj_cache != null)
            {
                if (Convert.ToDateTime(obj_time) < DateTime.Now)
                {
                    Delete(CacheKey);
                    Delete(CacheKey + "_time");
                    return default(T);
                }
                else return (T)obj_cache;
            }
            else
            {
                Delete(CacheKey);
                Delete(CacheKey + "_time");
                return default(T);
            }
        }
        #endregion

        #region 获取缓存,依赖文件
        /// <summary>
        /// 获取缓存,依赖文件
        /// </summary>
        /// <param name="CacheKey">键</param>
        /// <param name="depFile">依赖的文件</param>
        /// <returns></returns>
        public T Get<T>(string CacheKey, string depFile)
        {
            object obj_time = HttpRuntime.Cache[CacheKey + "_time"];
            object obj_cache = HttpRuntime.Cache[CacheKey];
            if (File.Exists(depFile))
            {
                FileInfo fi = new FileInfo(depFile);

                if (obj_time != null && obj_cache != null)
                {
                    if (Convert.ToDateTime(obj_time) != fi.LastWriteTime)
                    {
                        Delete(CacheKey);
                        Delete(CacheKey + "_time");
                        return default(T);
                    }
                    else return (T)obj_cache;
                }
                else
                {
                    Delete(CacheKey);
                    Delete(CacheKey + "_time");
                    return default(T);
                }
            }
            else
            {
                throw new Exception("文件(" + depFile + ")不存在!");
            }
        }
        #endregion

        #region 简单的插入缓存
        /// <summary>
        /// 简单的插入缓存
        /// </summary>
        /// <param name="CacheKey">键</param>
        /// <param name="objObject">数据</param>
        public bool Set<T>(string CacheKey, T objObject)
        {
            HttpRuntime.Cache.Insert(CacheKey, objObject);
            return true;
        }
        #endregion

        #region 有过期时间的插入缓存数据
        public bool Set<T>(string CacheKey, T objObject, DateTime expiresAt)
        {
            HttpRuntime.Cache.Insert(CacheKey, objObject, null, expiresAt, Cache.NoSlidingExpiration);
            HttpRuntime.Cache.Insert(CacheKey + "_time", expiresAt, null, expiresAt, Cache.NoSlidingExpiration);//存储过期时间
            return true;
        }
        #endregion

        #region 插入缓存数据,指定缓存多少秒
        public bool Set<T>(string CacheKey, T objObject, int seconds)
        {
            DateTime expiresAt = DateTime.Now.AddSeconds(seconds);
            HttpRuntime.Cache.Insert(CacheKey, objObject, null, expiresAt, Cache.NoSlidingExpiration);
            HttpRuntime.Cache.Insert(CacheKey + "_time", expiresAt, null, expiresAt, Cache.NoSlidingExpiration);//存储过期时间
            return true;
        }
        #endregion

        #region 依赖文件的缓存,文件没改不会过期
        /// <summary>
        /// 依赖文件的缓存,文件没改不会过期
        /// </summary>
        /// <param name="CacheKey">键</param>
        /// <param name="objObject">数据</param>
        /// <param name="depfilename">依赖文件,可调用 DataCache 里的变量</param>
        public bool Set<T>(string CacheKey, T objObject, string depfilename)
        {
            //缓存依赖对象
            System.Web.Caching.CacheDependency dep = new System.Web.Caching.CacheDependency(depfilename);
            DateTime absoluteExpiration = System.Web.Caching.Cache.NoAbsoluteExpiration;
            TimeSpan slidingExpiration = System.Web.Caching.Cache.NoSlidingExpiration;
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            objCache.Insert(
                CacheKey,
                objObject,
                dep,
                absoluteExpiration, //从不过期
                slidingExpiration, //禁用可调过期
                System.Web.Caching.CacheItemPriority.Default,
                null);
            if (File.Exists(depfilename))
            {
                FileInfo fi = new FileInfo(depfilename);
                DateTime lastWriteTime = fi.LastWriteTime;
                HttpRuntime.Cache.Insert(CacheKey + "_time", lastWriteTime, null, absoluteExpiration, slidingExpiration);//存储文件最后修改时间
            }
            return true;
        }
        #endregion
    }
}

//缓存统一入口

    public partial class DataCache
    {
        private static IDataCache _instance = null;
        /// <summary>
        /// 静态实例,外部可直接调用
        /// </summary>
        public static IDataCache Instance
        {
            get
            {
                if (_instance == null) _instance = new RuntimeCache();//这里可以改变缓存类型
                return _instance;
            }
        }
    }
时间: 2024-10-31 12:53:19

Redis缓存、MemCached和.Net内部缓存的切换使用的相关文章

分布式缓存技术PK:选择Redis还是Memcached?

Memcached和Redis,作为近些年最常用的缓存服务器,相信大家对它们再熟悉不过了.为了对它们有更深入的了解,我曾经读过它们的主要源码,下面我将从个人角度简单对比一下它们的实现方式,有理解错误之处,欢迎指正. 文中使用的架构类的图片大多来自于网络,有部分图与最新实现有出入,文中已经指出.   一.综述  读一个软件的源码,首先要弄懂软件是用作干什么的,那Memcached和Redis是干啥的?众所周知,数据一般会放在数据库中,但是查询数据会相对比较慢,特别是用户很多时,频繁的查询,需要耗费

原创:.NET版分布式缓存Memcached测试实例

下面测试下分布式缓存Memcached软件,一直在学习关注大访问量网站的缓存是如何实现,之前看过Memcached的资料,忙于没有时间来真正测试一下,本文测试分布式缓存Memcached的环境如下:(两台电脑作为服务器) 第一台: 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) P

Memcached分布式内存对象缓存系统简单的使用过程分析

风信网(ithov.com)原创文章:Memcached是一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,进而提升系统性能.Memcached在很多时候都作为数据库的前端cache使用,因为它比数据库少了很多SQL解析.磁盘操作等开销,而且使用内存来管理数据,所以它可以提供比直接读取数据库更好的性能.另外,Memcached也经常作为服务器之间数据共享的存储媒介.学习完本章,相信读者能够对Memcached有一个全面的了解,使构建一套属于自己的分布式内存对象缓存系统变成很简单的事情.

CYQ.Data V5 分布式缓存MemCached应用开发介绍

前言 今天大伙还在热议关于.NET Core的东西,我只想说一句:在.NET 跨平台叫了这么多年间,其实人们期待的是一个知名的跨平台案例,而不是一堆能跨平台的消息. 好,回头说说框架:  在框架完成数据库读写分离的功能后,开始回想起2年前所构思的:关于框架集成分布式缓存MemCached的实现. 之前一直没动手,是因为思路比较飘,秉承着框架应该简单干净轻量引用无依赖和使用不复杂的思维: 看着MemCached的服务端协议,整天思考着自己用Socket写一个客户端. 后来可能是没激情,迟迟没动手.

PHP内存缓存Memcached类实例_php技巧

本文实例讲述了PHP内存缓存Memcached类.分享给大家供大家参考. 具体实现方法如下: 复制代码 代码如下: <?PHP class MemcacheModel { private $mc = null; /** * 构造方法,用于添加服务器并创建memcahced对象 */ function __construct(){ $params = func_get_args(); $mc = new Memcache; //如果有多个memcache服务器 if( count($params)

Memcached分布式内存对象缓存系统的性能监控

风信网(ithov.com)原创文章:本文将从三个方面向你介绍Memcached分布式内存对象缓存系统的管理与http://www.aliyun.com/zixun/aggregation/14216.html">性能监控,主要的内容涉如何管理Memcached,如何监控Memcached及随着Memcached应用不断衍生出来的各变种产品的介绍. 如何管理Memcached 1.通过Memcached的监听端口进行管理 Memcached的管理相对比较容易,通过命令行登录到Memcach

关于分布式缓存Memcached详解

关于分布式缓存memcached详解 libevent事件机制 memcached基于libevent事件处理,用相关资料上描述,libevent是个程序库,它将linux的epoll.bsd类操作系统的kqueue等事件处理功能封装成统一的接口.即使对服务器的连接数增加,也能发挥o(1)的性能. memcached服务器,缓存数据都是以key-value hash表的内存存储,最大key不超过250个字符,最大value项默认不超过1m,因此重启程序和服务器都会导致数据丢失,但它会消耗更低的c

Redis和Memcached的一些区别

我们都知道,把一些热数据存到缓存中可以极大的提高速度,那么问题来了,是用Redis好还是Memcached好呢,以下是它们两者之间一些简单的区别与比较: 1. Redis不仅支持简单的k/v类型的数据,同时还支持list.set.zset(sorted set).hash等数据结构的存储,使得它拥有更广阔的应用场景. 2. Redis最大的亮点是支持数据持久化,它在运行的时候可以将数据备份在磁盘中,断电或重启后,缓存数据可以再次加载到内存中,只要Redis配置的合理,基本上不会丢失数据. 3.

Redis和Memcached的区别详解_Redis

Redis的作者Salvatore Sanfilippo曾经对这两种基于内存的数据存储系统进行过比较: 1.Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去.这大大增加了网络IO的次数和数据体积.在Redis中,这些复杂的操作通常和一般的GET/SET一样高效.所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择. 2.内存使用效