Redis性能大幅提升之Batch批量读写详解
程序员文章站
2022-06-17 18:55:15
前言
本文主要介绍的是关于redis性能提升之batch批量读写的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:
提示:本文针对的是stackexchange...
前言
本文主要介绍的是关于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()], -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(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()], -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<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)); ... } }
这个方法里也给出了批量写和读的操作。
总结
好了,先说到这里了。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。