Redis大幅性能提升之Batch批量读写
Redis大幅性能提升之Batch批量读写
提示:本文针对的是StackExchange.Redis
一、问题呈现
前段时间在开发的时候,遇到了redis批量读的问题,由于在StackExchange.Redis里面我确实没有找到PipeLine命令,找到的是Batch命令,因此对其用法进行了探究一下。
下面的代码是我之前写的:
public List<StudentEntity> Get(List<int> ids)
{
List<StudentEntity> result = new List<StudentEntity>();
try
{
var db = RedisCluster.conn.GetDatabase();
foreach (int id in ids.Keys)
{
string key = KeyManager.GetKey(id);
var dic = db.HashGetAll(key).ToDictionary(k => k.Name, v => v.Value);
StudentEntity se = new StudentEntity();
if (dic.Keys.Contains(StudentEntityRedisHashKey.id.ToString()))
{
pe.id = FormatUtils.ConvertToInt32(dic[StudentEntityRedisHashKey.id.ToString()], -);
}
if (dic.Keys.Contains(StudentEntityRedisHashKey.name.ToString()))
{
pe.name= dic[StudentEntityRedisHashKey.name.ToString()];
}
result.Add(se);
}
catch (Exception ex)
{
}
return result;
}
从上面的代码中可以看出,并不是批量读,经过性能测试,性能确实是要远远低于用Batch操作,因为HashGetAll方法被执行了多次。
下面给出批量方法:
二、解决问题方法
具体的用法是:
var batch = db.CreateBatch();
...//这里写具体批量操作的方法
batch.Execute();
2.1批量写:
具体代码:
public bool InsertBatch(List<StudentEntity> seList)
{
bool result = false;
try
{
var db = RedisCluster.conn.GetDatabase();
var batch = db.CreateBatch();
foreach (var se in seList)
{
string key = KeyManager.GetKey(se.id);
batch.HashSetAsync(key, StudentEntityRedisHashKey.id.ToString(), te.id);
batch.HashSetAsync(key, StudentEntityRedisHashKey.name.ToString(), te.name);
}
batch.Execute();
result = true;
}
catch (Exception ex)
{
}
return result;
}
这个方法里执行的是批量插入学生实体数据,这里只是针对Hash,其它的也一样操作。
2.2批量读:
具体代码:
public List<StudentEntity> GetBatch(List<int> ids)
{
List<StudentEntity> result = new List<StudentEntity>();
List<Task<StackExchange.Redis.HashEntry[]>> valueList = new List<Task<StackExchange.Redis.HashEntry[]>>();
try
{
var db = RedisCluster.conn.GetDatabase();
var batch = db.CreateBatch();
foreach(int id in ids)
{
string key = KeyManager.GetKey(id);
Task<StackExchange.Redis.HashEntry[]> tres = batch.HashGetAllAsync(key);
valueList.Add(tres);
}
batch.Execute(); foreach(var hashEntry in valueList)
{
var dic = hashEntry.Result.ToDictionary(k => k.Name, v => v.Value);
StudentEntity se= new StudentEntity();
if (dic.Keys.Contains(StudentEntityRedisHashKey.id.ToString()))
{
se.id= FormatUtils.ConvertToInt32(dic[StudentEntityRedisHashKey.id.ToString()], -);
}
if (dic.Keys.Contains(StudentEntityRedisHashKey.name.ToString()))
{
se.name= dic[StudentEntityRedisHashKey.name.ToString()];
}
result.Add(se);
}
}
catch (Exception ex)
{
}
return result;
}
这个方法是批量读取学生实体数据,批量拿到实体数据后,将其转化成我们需要的数据。下面给出性能对比。
2.3性能对比:
10条数据,约4-5倍差距:
1000条数据,约28倍的差距:
随着数据了增多,差距将越来越大。
三、源码测试案例
上面是批量读写实体数据,下面给出StackExchange.Redis源码测试案例里的批量读写写法:
public void TestBatchSent()
{
using (var muxer = Config.GetUnsecuredConnection())
{
var conn = muxer.GetDatabase();
conn.KeyDeleteAsync("batch");
conn.StringSetAsync("batch", "batch-sent");
var tasks = new List<Task>();
var batch = conn.CreateBatch();
tasks.Add(batch.KeyDeleteAsync("batch"));
tasks.Add(batch.SetAddAsync("batch", "a"));
tasks.Add(batch.SetAddAsync("batch", "b"));
tasks.Add(batch.SetAddAsync("batch", "c"));
batch.Execute(); var result = conn.SetMembersAsync("batch");
tasks.Add(result);
Task.WhenAll(tasks.ToArray()); var arr = result.Result;
Array.Sort(arr, (x, y) => string.Compare(x, y));
...
}
}
这个方法里也给出了批量写和读的操作。
好了,先说到这里了。
查看原文:http://www.cnblogs.com/zhangtingzu/
下面给出一些相关的参考文档:
1.http://www.cnblogs.com/huangxincheng/p/6212406.html
2.http://blog.csdn.net/ma_jiang/article/details/57085586
Redis大幅性能提升之Batch批量读写的更多相关文章
- redis大幅性能提升之使用管道(PipeLine)和批量(Batch)操作
前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value 就是具体的customerid集合, ...
- Spring Boot 2.2 正式发布,大幅性能提升 + Java 13 支持
之前 Spring Boot 2.2没能按时发布,是由于 Spring Framework 5.2 的发布受阻而推迟.这次随着 Spring Framework 5.2.0 成功发布之后,Spring ...
- Java Redis的Pipeline管道,批量操作,节省大量网络往返时间 & Redis批量读写(hmset&hgetall) 使用Pipeline
一般情况下,大家使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接:这种模式是 请求-响应,请求-响应 这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为r ...
- memcache 与 redis 为web app 带来的性能提升
memcache 与 redis 为web app 带来的性能提升 参考: 1. http://www.cnblogs.com/ToDoToTry/p/3513688.html
- spring batch批量处理框架
spring batch精选,一文吃透spring batch批量处理框架 前言碎语 批处理是企业级业务系统不可或缺的一部分,spring batch是一个轻量级的综合性批处理框架,可用于开发企业信息 ...
- TOP100summit:【分享实录-华为】微服务场景下的性能提升最佳实践
本篇文章内容来自2016年TOP100summit华为架构部资深架构师王启军的案例分享.编辑:Cynthia 王启军:华为架构部资深架构师.负责华为的云化.微服务架构推进落地,前后参与了华为手机祥云4 ...
- 重构、插件化、性能提升 20 倍,Apache DolphinScheduler 2.0 alpha 发布亮点太多!
点击上方 蓝字关注我们 社区的小伙伴们,好消息!经过 100 多位社区贡献者近 10 个月的共同努力,我们很高兴地宣布 Apache DolphinScheduler 2.0 alpha 发布.这是 ...
- paip.cache 缓存架构以及性能提升总结
paip.cache 缓存架构以及性能提升总结 1 缓存架构以及性能(贯穿读出式(LookThrough) 旁路读出式(LookAside) 写穿式(WriteThrough) 回写式 ...
- VNF网络性能提升解决方案及实践
VNF网络性能提升解决方案及实践 2016年7月 作者: 王智民 贡献者: 创建时间: 2016-7-20 稳定程度: 初稿 修改历史 版本 日期 修订人 说明 1.0 20 ...
随机推荐
- ArrayList,LinkedList的对比
ArrayList,LinkedList都是Collection接口的通用实现方式,两者采用了不用的存储策略,用来适应不同场合的需要. 实现方式 ArrayList的内部采用集合的方式存储数据 唯一需 ...
- for xml path 如何将字段转换为xml的属性
for xml path 如何将字段作为xml的属性: 可在查询时 别名用 as '@..' 如'@value' 如下实例: SELECT A.GiftSetGUID AS '@value',A.Gi ...
- Linux - PCB之task_struct结构体
task_struct结构描述 1. 进程状态(State) 进程执行时,它会根据具体情况改变状态 .进程状态是调度和对换的依据.Linux中的进程主要有如下状态,如表4.1所示. 内核表示 含义 ...
- 读书笔记之JavaScript中的数据类型(1)
JavaScript严格意义上分为ECMAScript.DOM.BOM.ECMAScript是一门真正意义上的语言,独立于浏览器,浏览器只是它的一个宿主环境.DOM(文档对象模型),为ECMAScri ...
- callLater
UIComponent的方法,该方法在每次更新屏幕之前,Flash Player 或 AIR 都会调用为更新预定的函数集.有时,应在下次更新时调用函数,以执行为当前更新预定的其余代码.部分功能(如效果 ...
- 【整理】hash算法原理及常见函数
简介 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值. 散列表 ...
- 关于div+css布局值得注意的地方
注意项 我们知道,如果想要两个 div(即块级元素)挨着一起排列,可以将其设置为inline-block(行内-块元素). 不过要注意两个div内的内容的对齐方式将是垂直中间对齐,所以这时候就需要使用 ...
- 《Thinking in Java》 And 《Effective Java》啃起来
前言 今天从京东入手了两本书,<Thinking in Java>(第四版) 和 <Effective Java>(第二版).都可以称得上是硬书,需要慢慢啃的,预定计划是在今年 ...
- IOS的Application以及IOS目录的介绍
1.UIApplication介绍 .UIApplication对象是应用程序的象征 .每一个应用都有自己的UIApplication对象,而且是单例的 .通过[UIApplication share ...
- JavaScript利用闭包循环绑定事件
我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用. 1.首先我们举一个简单的例子. html部分: <a href=& ...