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地址,还要输入用户名和密码,比较麻烦.可能 ...
随机推荐
- UVALive 5983 MAGRID
题意:在一个n*m的网格上,从(0,0)走到(n-1,m-1),每次只能向右或者向下走一格.一个人最初有一个生命值x,走到每一个格生命值会变为x + s[i][j],(s[i][j]可为负,0,正), ...
- Count the string - HDU 3336(next+dp)
题目大意:给你一个串求出来这个串所有的前缀串并且与前缀串相等的数量,比如: ababa 前缀串{"a", "ab", "aba", &quo ...
- [置顶] VC++界面编程之--使用分层窗口实现界面皮肤
使用分层界面来实现界面皮肤的好处是:可以保证图片边缘处理不失真,且能用于异形窗口上,如一些不规则的窗口,你很难用SetWindowRgn来达到理想效果. 在很多情况下,界面的漂亮与否,取决于PS的制作 ...
- python-用户登录小程序
算是第一篇博客吧~哈哈哈 虽然说是为了完成作业,不过以后估计会常来分享.首先说一下下边这个程序的基本功能.毕竟是第一次写python程序还是有点小激动和满满的成就感的,下边这个程序: 1.输入不存在的 ...
- php 二维数组转换成树状数组(转)
<?php/** * @param array $list 要转换的结果集 * @param string $pid parent标记字段 * @param string $level leve ...
- Web站点架构设计考虑的因素
转自http://blog.csdn.net/moshengtan/article/details/8990052 1 Web负载均衡 1.1 - 使用商业硬件实现 最经常使用的F5 与citr ...
- Adapter优化方案的探索
概要:使用Adapter的注意事项与优化方案本文的例子都可以在结尾处的示例代码连接中看到并下载,如果喜欢请star,如果觉得有纰漏请提交issue,如果你有更好的点子可以提交pull request. ...
- Linux防火墙配置
防火墙命令 service iptables stop --停止 service iptables start --启动文件 /etc/sysconfig/iptables # Firewall c ...
- android EditText设置光标、边框和图标
控制边框形状,先在drawable中建一个xml文件:shape.xml <?xml version="1.0" encoding="utf-8"?> ...
- 2015 Multi-University Training Contest 1 题解 BY FZUw
题目链接:5288-5299 HDU5288 题解原文链接:我是链接