欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Redis性能大幅提升之Batch批量读写详解

程序员文章站 2022-03-09 11:53:01
前言 本文主要介绍的是关于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倍差距:

Redis性能大幅提升之Batch批量读写详解   

1000条数据,约28倍的差距:

Redis性能大幅提升之Batch批量读写详解 

随着数据了增多,差距将越来越大。

三、源码测试案例 

上面是批量读写实体数据,下面给出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));
    ...
   }
  }

这个方法里也给出了批量写和读的操作。

总结

好了,先说到这里了。以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。