Redis性能大幅提升之Batch批量读写详解
Redis  /  管理员 发布于 5年前   1188
前言
本文主要介绍的是关于Redis性能提升之Batch批量读写的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:
提示:本文针对的是StackExchange.Redis
一、问题呈现
前段时间在开发的时候,遇到了redis批量读的问题,由于在StackExchange.Redis里面我确实没有找到PipeLine命令,找到的是Batch命令,因此对其用法进行了探究一下。
下面的代码是我之前写的:
public ListGet(Listids){
Listresult = new List();
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()], -1); } 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(ListseList){
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 ListGetBatch(Listids){
Listresult = new List();
List<Task> valueList = new List<Task>();
try {
var db = RedisCluster.conn.GetDatabase();
var batch = db.CreateBatch();
foreach(int id in ids) {
string key = KeyManager.GetKey(id);
Tasktres = 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()], -1);
}
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(0);
conn.KeyDeleteAsync("batch");
conn.StringSetAsync("batch", "batch-sent");
var tasks = new List();
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));
...
}
}这个方法里也给出了批量写和读的操作。
总结
好了,先说到这里了。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家的支持。
博主 2021-06-17 14:42:23 赞 (0)
@ Lucio
Thank you very much for your love. I am very happy. This site mainly displays the technical articles I use in my work. I will also write some tutorials on the Internet. Thank you again.
This is very interesting, You're a very skilled blogger. I've joined your feed and look forward to seeking more of your excellent post. Also, I have shared your website in my social networks! สมัคร Wm Casino
Lucio 2021-06-16 22:52:53 赞 (0)
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号
