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地址,还要输入用户名和密码,比较麻烦.可能 ...
随机推荐
- 分页过滤SQL求总条数SQL正则
public static void main(String[] args) throws Exception { String queryForScanUsers_SQL = "selec ...
- [置顶] ruby变量详解(收集+整理)
ruby的变量有局部变量,全局变量,实例变量,类变量,常量. 1.局部变量 局部变量以一个小写字母开头或下划线开头 局部变量有局部作用域限制(比如一个block内),它的作用域起始于声明处,结束于该声 ...
- README 语法编写
推荐一个超棒的软件 haroopad Standard Markdown \ backslash ` backtick * asterisk _ underscore {} curly braces ...
- 字符串的encode与decode解决乱码问题
!/usr/bin/env python coding=utf-8 s="中文" if isinstance(s, unicode): s=u"中文" prin ...
- App抓包数据包之Paros的安装及使用
1.在应用程序开发过程中,会遇到很多网络访问问题,自己没有能力提供后台服务,这时就可以抓取网络上的数据包,获取数据接口,应用在程序中.下面介绍使用paros抓取网络数据包得步骤. 2.要使用paros ...
- poj 3171 Cleaning Shifts(区间的最小覆盖价值)
Cleaning Shifts Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2743 Accepted: 955 De ...
- Codeforces 544E Remembering Strings 状压dp
题目链接 题意: 给定n个长度均为m的字符串 以下n行给出字符串 以下n*m的矩阵表示把相应的字母改动成其它字母的花费. 问: 对于一个字符串,若它是easy to remembering 当 它存在 ...
- linux下显卡信息的查看
lspci | grep -i vga 这样就可以显示机器上的显卡信息,比如 [root@localhost conf]# lspci | grep -i vga01:00.0 VGA compat ...
- HTML中常见的各种位置距离以及dom中的坐标讨论
最近在学习JavaScript,特意买了一本犀牛角书来看看,尼玛一千多页,看的我头昏脑涨,翻到DOM这章节,突然记起平常在使用DOM时,碰到了好多的这个dom里面的各种宽度,高度,特意在此写一写,写的 ...
- yii 载入css or js
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . "/js/TableView.js&q ...