Scut:Redis 资源管理器
核心文件是:RedisConnectionPool.cs
对象池类的通用泛型封装:ObjectPoolWithExpire<T>
1. 主要变量
private static ICacheSerializer _serializer; //redis 存储内容的序列化器
private static RedisPoolSetting _setting; //redus 他、应遵循的配置
private static ConcurrentDictionary<string, ObjectPoolWithExpire<RedisClient>> _poolCache; //字典结构:每个 key 对应一个 pool 的集合
private static RedisInfo _currRedisInfo;
2. 初始化
public static void Initialize(RedisPoolSetting setting, ICacheSerializer serializer)
{
_setting = setting; //RedisPoolSetting 按默认配置加载的配置
_serializer = serializer; //采取的序列化器
//init pool
string key = GenratePoolKey(setting.Host, setting.DbIndex); //127.0.0.1:6379#0 是首个管理 redisclient-pool 的 key
var pool = GenrateObjectPool(setting); //建立对象池,主要是为泛型类注入 factory 方法,以及池深度、对象生命周期参数
private static ObjectPoolWithExpire<RedisClient> GenrateObjectPool(RedisPoolSetting setting)
{
return new ObjectPoolWithExpire<RedisClient>(() => CreateRedisClient(setting), true, setting.PoolTimeOut, setting.MaxWritePoolSize / );
}
for (int i = ; i < pool.MinPoolSize; i++)
{
pool.Put();
}
_poolCache[key] = pool;
InitRedisInfo();
}
3. RedisClient 获取、读、写操作
句柄获取:
public static RedisClient GetClient()
{
return GetOrAddPool(_setting);
public static RedisClient GetOrAddPool(RedisPoolSetting setting)
{
var key = GenratePoolKey(setting.Host, setting.DbIndex);
var lazy = new Lazy<ObjectPoolWithExpire<RedisClient>>(() => GenrateObjectPool(setting)); //根据配置找到pool的key,使用key检索到pool
ObjectPoolWithExpire<RedisClient> pool = _poolCache.GetOrAdd(key, k => lazy.Value); //在目标pool 获取一个 redisclient
return pool.Get();
}
}
读取:
先来看下应用层是如何加载数据的:
public static object[] GetAllEntity(string personalId, params Type[] entityTypes)
{
//todo: trace GetAllEntity
var watch = RunTimeWatch.StartNew("Get redis data of persionalId:" + personalId);
if (entityTypes.Length == ) return null; byte[] keytBytes = ToByteKey(personalId); //将私有ID转化成二进制流
var redisKeys = new List<string>();
foreach (var type in entityTypes) //遍历所有要获取数据的类型
{
redisKeys.Add(GetRedisEntityKeyName(type));
}
try
{
byte[][] valueBytes = null;
ProcessReadOnly(client =>
{
var values = new List<byte[]>();
using (var p = client.CreatePipeline())
{
foreach (var key in redisKeys) //使用redis管道,一次性执行多条读取命令
{
string k = key;
p.QueueCommand(cli => ((RedisNativeClient)cli).HGet(k, keytBytes), values.Add); //将类型与私有ID组合成rediskey,将值获取到value中
}
p.Flush();
}
valueBytes = values.ToArray();
//valueBytes = client.Eval(script, redisKeys.Count, redisKeys.ToArray());
});
watch.Check("redis get");
if (valueBytes != null)
{
var result = new object[entityTypes.Length];
for (int i = ; i < entityTypes.Length; i++) //遍历每个类型,将二进制流反序列化成对象
{
var type = entityTypes[i];
var val = i < valueBytes.Length ? valueBytes[i] : null;
result[i] = val == null || val.Length ==
? null
: _serializer.Deserialize(val, type);
}
return result; //得到对象数组后返回,从应用层来看,该API可用于一次性获取一个personalkey的多种多类型数据
}
}
catch (Exception ex)
{
TraceLog.WriteError("Get redis data of persionalId:{0} error:{1}", personalId, ex);
}
finally
{
watch.Flush(true, );
}
return null;
}
写入:
这里只看一个最常用的事务写入,对一个hashid下的多个key事务性地写入数据。
//该API的命名是更新,更新则包含写入与删除两个操作
private static void TransUpdateEntity(IRedisTransaction trans, string hashId, byte[][] keys, byte[][] values, byte[][] removeKeys)
{
if (keys.Length > )
{
trans.QueueCommand(c =>
{
var cli = (RedisClient)c;
cli.HMSet(hashId, keys, values);
});
}
if (removeKeys.Length > )
{
trans.QueueCommand(c =>
{
var cli = (RedisClient)c;
cli.HDel(hashId, removeKeys);
});
}
}
在看 RedisConnectionPool.cs 的过程中,发现了大量 SchemaSet 与 Cache 的使用,下个阶段重点分析 Scut 的这两个部分。
Scut:Redis 资源管理器的更多相关文章
- 360安全卫士造成Sharepoint文档库”使用资源管理器打开“异常
备注:企业用户还是少用360为妙 有客户反馈:部门里的XP SP2环境客户机全部异常,使用资源管理器打开Sharepoint文档库,看到的界面样式很老土,跟本地文件夹不一样 ...
- Windows 7 在资源管理器中显示软件快捷方式
该方法是利用资源管理器中储存网络位置的文件夹实现的, 不需要修改注册表. 效果如图: 操作方法: 在资源管理器中打开路径 "%appdata%\Microsoft\Windows\Netwo ...
- 修复 Windows7 资源管理器左侧收藏夹无法展开问题
相信大家在网上搜多到的解决办法大多数都是修改注册表,但是这个办法多数是无效的 1.运行regedit 2.展开到HKEY_CLASSES_ROOT\lnkfile 3.添加一个字符串值:IsShort ...
- [No00009C]Visual Studio在 解决方案资源管理器 里同步定位打开的文件
标题的意思就是在使用VS的时候,需要我们打开编辑的文件跟解决方案的资源管理器同步显示,这样方便定位到我们在修改哪个文件. 设置如下: 工具——选项——项目和解决方案——在解决方案资源管理器中跟踪活动项 ...
- 怎样在Windows资源管理器中添加右键菜单以及修改右键菜单顺序
有时,我们需要在Windows资源管理器的右键菜单中添加一些项,以方便使用某些功能或程序. 比如我的电脑上有一个免安装版的Notepad++,我想在所有文件的右键菜单中添加一项用Notepad++打开 ...
- VS2013.3 & VS2014 任务资源管理器
Web 开发,特别是前端 Web 开发,正迅速变得像传统的后端开发一样复杂和精密.前端生成过程,可以囊括SASS 和LESS扩展.CSS/JS的压缩包.JSHint 或 JSLint的运行时 .或者更 ...
- Sql Server系列:Microsoft SQL Server Management Studio模板资源管理器
模板资源管理器是Microsoft SQL Server Management Studio的一个组件,可以用来SQL代码模板,使用模板提供的代码,省去每次都要输入基本代码的工作. 使用模板资源管理器 ...
- Mac Pro 资源管理器 Double Commander“个性化设置” 备份
操作系统自带的资源管理器,总是有些别扭的地方,在 Windows 系统下,我一般用 Total Commander(破解版)来作为替代品.现在换为 Mac 系统,自带的 Finer 也不怎么好用,连最 ...
- win7使用自带资源管理器来登陆FTP
使用windows自带的资源管理器登陆FTP,其实很简单,打开计算机,在地址栏直接输入ftp://ftp.hostname即可. 但是这种方式需要每次输入ip地址,还要输入用户名和密码,比较麻烦.可能 ...
随机推荐
- openStack 云平台管理节点管理网口流量非常大 出现丢包严重 终端总是时常中断问题调试及当前测试较有效方案
tuning for Data Transfer hosts connected at speeds of 1Gbps or higher <一.本次OpenStack系统调试简单过程简单记录& ...
- Spring 报错:Error creating bean with name
org.springframework.beans.factory.BeanCreationException: 原因是在autowire时,找不到相应的类,上述问题是因为XXXXX的实现类中没有加相 ...
- 怎样在loop中处理异常
怎样在loop中处理异常,而不跳出 出现符号“exception”在需要下下列之一时的解决办法; 如果sql中发生异常,我们可以用 exception when others then d ...
- SetupFactory +添加frm2.0工具
网盘链接: http://pan.baidu.com/s/1c1DFRJM 带单独的添加frm2.0工具 原setupfactory文件下载地址:http://www.pc0359.cn/downin ...
- 小菜学习Lucene.Net(更新3.0.3版本使用)
花了两天的时间研究了下Lucene.Net 发现确实挺好玩.... 最新版本是3.0.3 (最后更新时间2012-10) 可惜3.0.3版本的Lucene.net无法和盘古分词 (最新版为2.3.1. ...
- Android Scroller类的详细分析
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/7321910 Scroller这个类理解起来有一定的困难,刚开始接触Scrol ...
- Android Fragment动态添加 FragmentTransaction FragmentManager
Fragment常用的三个类:android.app.Fragment 主要用于定义Fragmentandroid.app.FragmentManager 主要用于在Activity中操作Fragme ...
- 我的搜索优化记录(一):中文分词优化IK Analyzer
搜索绝对不仅仅是搭起框架,跑出结果就完成的工作,之后分词.排序等等的优化才是重头戏. 先交代下背景:这个搜索是我一个人负责搭建并优化的项目,主要索引对象为歌曲.歌手MV等等. 使用技术:Lucene. ...
- [转] C++虚函数与虚函数表
http://www.cnblogs.com/Ripper-Y/archive/2012/05/15/2501930.html http://blog.csdn.net/haoel/article/d ...
- ZOJ 3822 Domination(概率dp)
一个n行m列的棋盘,每天可以放一个棋子,问要使得棋盘的每行每列都至少有一个棋子 需要的放棋子天数的期望. dp[i][j][k]表示用了k天棋子共能占领棋盘的i行j列的概率. 他的放置策略是,每放一次 ...