本文主要介绍了Redis缓存从构建到使用的相关知识,具有一定的参考价值。下面就跟着小编一起来看看吧。
让我们正式分享今天的文章:
。搭建Redis服务端,并用客户端连接
。封装缓存父类,定义Get,Set等常用方法
。定义RedisCache缓存类,执行Redis的Get,Set方法
。构造出缓存工厂调用方法
一步一步来分享吧:
。搭建Redis服务端,并用客户端连接
首先我们为什么不去这个地址下载安装文件https://github.com/dmajkic/redis/downloads?我这里的版本是:redis-2.4.5-win32-win64。里面有32位和64位的可执行文件,我的服务器是64位的。以下是一些程序的截图和使用说明:
现在,扎可以直接用鼠标双击的应用,从而打开redis服务窗体(也可以下载一个windows服务载体,在windows服务中运行redis服务,不用担心每次关闭redis服务的黑色窗体都无法访问redis)。它是这样工作的:
红色方框表示成功。这里redis服务监控的端口默认是6379。如果要修改端口或更多配置信息,请找到redis.conf配置文件。对于具体的配置信息,你可以来这里http://www.shouce.ren/api/view/a/6231.
然后,打开客户端连接服务器,退回到64位文件夹的目录。将鼠标移动到64位文件夹,安装Shift键。同时点击鼠标右键,选择‘在此打开命令窗口’快速进入文件夹的cmd命令窗口(当然不同的操作系统不一样,这里是windows操作的演示;还有其他方式进入,这里就不介绍了,因为我个人感觉这是最快的);然后,在命令窗口中,输入redis-cli.exe-h localhost-p6379,并输入以访问服务器。效果图如下:
我们来看看服务器表单的截图:
没错,这样客户端连接到服务器。您可以在客户机上简单地执行set,get命令:
如果客户机想要访问远程redis服务器,它只需要将localhost更改为一个可访问的ip。如果您需要更多的配置,如密码,请前往上述地址链接。
。封装缓存父类,定义Get,Set等常用方法
首先,父类的代码:
公共类BaseCache : IDisposable
{
受保护的字符串def_ip=string。空的;
protected int def _ port=0;
受保护的字符串def_password=string。空的;
公共BaseCache()
{
}
public virtual void init cache(string IP= ,int port=0,string password= )
{
}
public virtual bool set cachet(string key,T t,int timeOutMinute=10)其中T : class,new()
{
返回false
}
公共虚拟T GetCacheT(字符串键)其中T : class,new()
{
返回默认值(T);
}
公共虚拟bool移除(字符串键)
{
返回false
}
公共虚拟bool FlushAll()
{
返回false
}
public virtual bool Any(字符串键)
{
返回false
}
公共虚拟void Dispose(bool isfalse)
{
如果(isfalse)
{
}
}
//手动释放
公共void Dispose()
{
这个。Dispose(真);
//不会自动释放
GC。suppress finalize(this);
}
}
对于这里定义的方法没有太多的评论。我想通过查看方法名来了解更多的含义。这个父类主要实现IDisposable。实现的Dispose()主要用于释放资源,并定制了一个公共的虚拟void dispose (boolis false)方法。里面有一句话:GC。suppress finalize(this);按照官网的介绍,就是屏蔽,自动释放资源的意思。没有别的了。继续看下面。
。定义RedisCache缓存类,执行Redis的Get,Set方法
首先我们分别定义类RedisCache和MemcachedCache(这里还没有实现memcache的操作),继承BaseCache,重写集合。Get方法如下:
///摘要
///Redis缓存
////摘要
公共类RedisCache : BaseCache
{
public RedisClient redis=null
公共再缓存()
{
//到这里读取默认的配置文件数据
def _ IP= 172 . 0 . 0 . 1 ;
def _ port=6379
def _ password=“”;
}
#区域Redis缓存
公共覆盖void InitCache(字符串ip= ,int port=0,字符串password= )
{
if (redis==null)
{
ip=字符串。IsNullOrEmpty(ip)?def _ IP:IP;
port=port==0?def_port:端口;
密码=字符串isnullorempty(密码)?定义_密码:密码:
redis=新的rediscclient(IP,端口、密码):
}
}
public override bool set achet(string key,t,int timeOutMinute=10)
{
var isfalse=false
试试看
{
如果(字符串)。isnullorempty(key)){ return为false}
init cache();
isfalse=重复7(key、t、timespan)。从分钟(超时分钟));
}
接住(异常)
{
}
终于{此。排列();}
返回isfalse
}
公共重写t getcachet(字符串密钥)
{
var t=预设(t):
试试看
{
如果(字符串)。isnullorempty(key)){ return t;}
init cache();
t=重复. GetT(关键点):
}
接住(异常)
{
}
终于{此。排列();}
返回t;
}
公共覆盖布尔移除(字符串密钥)
{
var isfalse=false
试试看
{
如果(字符串)。isnullorempty(key)){ return为false}
init cache();
isfalse=重复。移除(关键点):
}
接住(异常)
{
}
终于{此。排列();}
返回isfalse
}
公共覆盖无效规定(布尔为假)
{
if (isfalse redis!=空)
{
再说一遍。排列();
redis=null
}
}
#结束区域
}
///摘要
///内存缓存缓存
///摘要
公众的类memcachedca:基本缓存
{
}
这里,用到的重定向客户端类是来自纽吉特包引用的,这里纽吉特包是:
然后,来看下重写的初始化缓存(初始缓存)方法,这里面有一些互联网协议(Internet Protocol的缩写)端口(端口),密码(密码)参数,这里直接写入在政务司司长(服务器)文件中没有从配置文件读取,大家可以扩展下;这些参数通过重定向客户端构造函数传递给底层插座(插座)访问需要的信息,下面简单展示下重定向客户端几个的构造函数:
公共redisclient():
公共重定向点配置:
公共再贴现银行(主机字符串):
公共重定向客户端(Uri):
公共再贴现银行(主机字符串、int端口):
公共再贴现银行(主机字符串、int端口、密码字符串=null、long db=0);
至于获取,设置方法最终都是使用重定向客户端对象访问的,个人觉得需要注意的是设置(设置)方法里面的过期时间参数,目前还没有试验这种情况的效果:
?通过这几种方法设置过期时间后,快到过期时间的时候如果此时有使用这个缓存关键点那么过期时间是否会往后自动增加过期时间有效期,这里暂时没有试验(这里是由于前面项目中的。净核心框架中的我的天啊缓存都有这种设置,想来再说一遍应该也有吧)
这里,需要重写下公共覆盖无效规定(布尔为假)方法,因为调用完重定向客户端后需要释放,我们通过有没有安排统一来手动释放,而不是直接在调用的时候使用使用()
。构造出缓存工厂调用方法
美元接下来,咋们需要定义一个缓存工厂,因为上面刚才定义了一个重新计票和模棱两可明显这里会有多个不同缓存的方法调用,所用咋们来定义个工厂模式来调用对应的缓存;这里的工厂模式没有使用直接显示创建new redistricka()、new memcachedcache()对象的方法,而是使用了反射的原理,创建对应的缓存对象;
先来,定义个枚举,枚举里面的声明的名字要和咋们缓存类的名称相同,代码如下:
公共枚举缓存类型公用列举快取类型
{
重新分配,
模棱两可
}
再来,定义个工厂来高速缓存存储库(缓存工厂),并且定义方法当前(当前)如下代码:
公共静态基本缓存当前值(cachetype cachetype=cachetype).重新扫描)
{
变量空间=类型(基本缓存):
变量全名=间隙全名。
var nowspace=fullName .子字符串(0,全名).LastIndexOf(。))1);
返回程序集getexecutingassembly().创建实例(nowspace cachetype).ToString()、true)作为基址缓存;
}
*:通过传递枚举参数,来确定反射CreateInstance()方法需要用到的键入名称参数,从而来定义需要访问的那个缓存对象,这里要注意的是加上了一个命名空间现在空间,因为缓存类可能和工厂类不是同一个命名空间,但是通常会和缓存基类是同命名空间所以在方法最开始的时候截取获取了缓存类需要的命名空间(这里看自身项目来定吧);
*:装配GetExecutingAssembly()这个是用来获取当前应用程序集的路径,这里就避免了咋们使用组装。负载()方法还需要传递程序集的路径地址了
好了满上上面要求后,咋们可以在测试页面调用代码如:缓存存储库.当前(缓存类型RedisCache).SetCacheMoFlightSearchResponse(关键数据,值);就如此简单,咋们使用redis-cli.exe客户端来看下缓存起来的数据:
怎么样,您们的是什么效果呢,下面给出整体代码
#区域缓存存储库缓存工厂(默认存储会议中)
///摘要
///缓存枚举
////摘要
公共枚举缓存类型
{
BaseCache,
再贴现,
memcachedccache
}
///摘要
///缓存工厂(默认存储会议中)
////摘要
公共类缓存存储库
{
///摘要
///缓存工厂(默认存储会议中,CacheKey=SeesionKey )
////摘要
///param name=cacheType 缓存类型/param
///返回/返回
公共静态基本缓存当前(缓存类型缓存类型=缓存类型.RedisCache)
{
var nspace=的类型(基本缓存);
var fullName=nspace .全名;
var nowspace=fullName .子字符串(0,全名LastIndexOf( . ) 1);
返回装配GetExecutingAssembly().创建实例(现在是空间高速缓存类型.ToString(),true)作为BaseCache
}
}
///摘要
///缓存基类(默认存储会议中)
////摘要
公共类BaseCache : IDisposable
{
受保护的字符串def_ip=string .空的;
protected int def _ port=0;
受保护的字符串def_password=string .空的;
受保护的字符串CacheKey= SeesionKey
公共BaseCache()
{
}
///摘要
///获取自定义SessionId值
////摘要
///param name=keykey:使用唯一的登陆账号/param
///返回shah值的会话id/退货
公共虚拟字符串GetSessionId(字符串键)
{
返回MD5扩展.getsid MD 5 hash(key);
}
公共虚拟void初始化缓存(bool isReadAndWriter=true,string ip= ,int port=0,string password= )
{
}
public virtual bool set cachet(string key,T t,int timeOutMinute=10,bool isSerilize=false)其中T : class,new()
{
var isfalse=false
尝试
{
钥匙=钥匙?缓存键
if(t==null){ return为false}
var session_json=JsonConvert .序列化对象(t);
HttpContext .当前。会话。超时=超时分钟;
HttpContext .当前。Session.Add(key,session _ JSON);
isfalse=true
}
接住(例外ex)
{
抛出新异常(例如。消息);
}
退货是假的
}
public virtual T get cachet(string key=null,bool isSerilize=false)其中T : class,new()
{
var T=default(T);
尝试
{
钥匙=钥匙?缓存键
var session=HttpContext .当前。会话[密钥];
if(session==null){ return t;}
t=JsonConvert .反序列化对象对象(会话ToString());
}
接住(例外ex)
{
抛出新异常(例如。消息);
}
return t;
}
公共虚拟bool Remove(字符串关键字=null)
{
var isfalse=false
尝试
{
钥匙=钥匙?缓存键
HttpContext .当前。会话。移除(键);
isfalse=true
}
接住(例外ex)
{
抛出新异常(例如。消息);
}
退货是假的
}
///摘要
///增加缓存时间
////摘要
///返回/返回
public virtual bool add expire(string key,int nTimeMinute=10)
{
返回真实的
}
公共虚拟bool FlushAll()
{
返回错误的
}
公共虚拟布尔Any(字符串键)
{
返回错误的
}
public virtual bool SetHashCacheT(string hashId,string key,T t,int nTimeMinute=10)其中T : class,new()
{
返回错误的
}
公共虚拟liststring get hashkeys(string hashId)
{
返回空
}
公共虚拟列表字符串GetHashValues(字符串哈希德)
{
返回空
}
公共虚拟T gethashvalueet(string hashId,string key)其中T : class,new()
{
var T=default(T);
return t;
}
public virtual bool remove hash by key(string hashId,string key)
{
返回错误的
}
公共虚拟void Dispose(bool isfalse)
{
如果(isfalse)
{
}
}
//手动释放
公共void Dispose()
{
这个处置(真);
//不自动释放
GC .抑制finalize(这个);
}
}
///摘要
///Redis缓存
////摘要
公共类RedisCache : BaseCache
{
public IRedisClient redis=null
公共再缓存()
{
//这里去读取默认配置文件数据
def _ IP= 127。0 .0 .1 ;
def _ port=6379
def _ password=
}
#区域雷迪斯缓存
公共静态object _ lock cache=new object();
公共覆盖void初始化缓存(bool isReadAndWriter=true,string ip= ,int port=0,string password= )
{
if (redis==null)
{
ip=字符串IsNullOrEmpty(ip)?def _ IP:IP;
port=port==0?定义端口:端口;
密码=字符串IsNullOrEmpty(密码)?定义_密码:密码;
//单个雷迪斯服务
//redis=new RedisClient(ip,port,password);
//集群服务如果密码,格式如:pwd@ip:port
var readAndWritePorts=new Liststring { sheniubushin 3 @ 127。0 .0 .1:6379 };
var onlyReadPorts=new Liststring {
神牛补3@127.0.0.1:6378 ,
神牛不散3 @ 127 .0 .0 .1:6377
};
var re spool=new PooledRedisClientManager(
读取和写入报告,
onlyReadPorts,
新RedisClientManagerConfig
{
AutoStart=true,
//最大读取链接
MaxReadPoolSize=20,
//最大写入链接
MaxWritePoolSize=10
})
{
//每个链接超时时间
ConnectTimeout=20,
//连接池超时时间
池超时=60
};
锁定(_lockCache)
{
redis=isReadAndWriter?重新泼水get client():re spool .get readonly client();
}
}
}
公共重写bool AddExpire(string key,int nTimeMinute=10)
{
var isfalse=false
尝试
{
如果(字符串IsNullOrEmpty(key)){ return为false}
init cache();
//isfalse=redis .使neryin(key,TimeSpan)过期.from分钟(ntime minute));
isfalse=redis .ExpireEntryAt(键,日期时间现在。添加分钟(ntime minute));
}
接住(例外ex)
{
}
最后{这个dispose();}
退货是假的
}
public override bool set cachet(string key,T t,int timeOutMinute=10,bool isSerilize=false)
{
var isfalse=false
尝试
{
如果(字符串IsNullOrEmpty(key)){ return为false}
init cache();
if (isSerilize)
{
var data=JsonConvert .序列化对象(t);
var bb=系统正文。Encoding.UTF8.GetBytes(数据);
isfalse=redis .Setbyte[](key,bb,TimeSpan .从分钟(超时分钟));
}
else { isfalse=redis .SetT(key,t,TimeSpan .从分钟(超时分钟));}
}
接住(例外ex)
{
}
最后{这个dispose();}
退货是假的
}
公共重写T GetCacheT(string key,bool isSerilize=false)
{
var T=default(T);
尝试
{
如果(字符串IsNullOrEmpty(key)){ return t;}
初始化缓存(false);
if (isSerilize)
{
var bb=redis .get byte[](key);
如果(bb .长度=0){ return t;}
定义变量数据=系统正文。编码。utf8。getstring(bb);
t=JsonConvert .反序列化对象(数据);
}
else { t=redis .GetT(key);}
}
接住(例外ex)
{
}
最后{这个dispose();}
return t;
}
公共覆盖布尔移除(字符串键)
{
var isfalse=false
尝试
{
如果(字符串IsNullOrEmpty(key)){ return为false}
init cache();
isfalse=redis .移除(键);
}
接住(例外ex)
{
}
最后{这个dispose();}
退货是假的
}
public override bool SetHashCacheT(string hashId,string key,T t,int nTimeMinute=10)
{
var isfalse=false
尝试
{
如果(字符串IsNullOrEmpty(hashId) || string .IsNullOrEmpty(key)| | t==null){ return为false}
init cache();
定义变量结果=JsonConvert .序列化对象(t);
如果(字符串IsNullOrEmpty(result)){ return为false}
isfalse=redis .SetEntryInHash(hashId,key,result);
if (isfalse) { AddExpire(key,nTimeMinute);}
}
接住(例外ex)
{
}
最后{这个dispose();}
返回isfalse
}
公共重写liststring gethashkeys(哈希字符串)
{
var hashkeys=new liststring();
试试看
{
如果(字符串)。isnullorempty(哈希)){返回hashkeys}
init cache();
hashKeys=redis .gethashkeys(哈希):
}
接住(异常)
{
}
终于{此。排列();}
返回hashkeys
}
公共重写列表字符串gethashvalues(哈希字符串)
{
var hash values=new liststring();
试试看
{
如果(字符串)。isnullorempty(哈希)){返回hashvalues}
init cache();
hashValues=redis .gethashvalues(哈希):
}
接住(异常)
{
}
终于{此。排列();}
返回哈希值
}
公共覆盖t gethashvalue(字符串哈希,字符串键)
{
var t=预设(t):
试试看
{
如果(字符串)。isnullorempty(哈希)| |字符串isnullorempty(key)){ return t;}
init cache();
var结果=redis .getvaluefromhash(哈希键):
如果(字符串)。isnullorempty(result)){ return t;}
t=jsonconvert .取消初始化对象(结果):
}
接住(异常)
{
}
终于{此。排列();}
返回t;
}
公共重写bool removehashbykey(哈希字符串字符串密钥)
{
var isfalse=false
试试看
{
如果(字符串)。isnullorempty(哈希)| |字符串isnullorempty(key)){ return为false}
init cache();
isfalse=重复removeentryfromhash(hashed,key):
}
接住(异常)
{
}
终于{此。排列();}
返回isfalse
}
公共覆盖无效规定(布尔为假)
{
if (isfalse redis!=空)
{
再说一遍。排列();
redis=null
}
}
#结束区域
}
///摘要
///内存缓存缓存
///摘要
公众的类memcachedca:基本缓存
{
}
#结束区域
这次分享的再说一遍缓存从搭建到使用希望给您们有帮助,还请多多支持点赞,谢谢。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!