redis || 批处理优化

大量数据导入的方式

单个命令的执行流程

一次命令的响应时间 = 1次往返的网络传输耗时 + 1次Redis执行命令耗时

N条命令依次执行

N次命令的响应时间 = N次往返的网络传输耗时 + N次Redis执行命令耗时

N条命令批量执行

N次命令的响应时间 = 1次往返的网络传输耗时 + N次Redis执行命令耗时

Redis提供了很多Mxxx这样的命令,可以实现批量插入数据,例如:

mset

hmset

利用mset批量插入10万条数据:

127.0.0.1:6379> help MSET

  MSET key value [key value ...]
  summary: Set multiple keys to multiple values
  since: 1.0.1
  group: string

127.0.0.1:6379> 
@Test
void testMxx() {    
  String[] arr = new String[2000];    
  int j;    
  for (int i = 1; i <= 100000; i++) {        
    j = (i % 1000) << 1;        
    arr[j] = "test:key_" + i;         
    arr[j + 1] = "value_" + i;        
    if (j == 0) {            
      jedis.mset(arr);        
    }    
  }
}

注意:不要在一次批处理中传输太多命令,否则单次命令占用带宽过多,会导致网络阻塞。

Pipeline

MSET虽然可以批处理,但是却只能操作部分数据类型,因此如果有对复杂数据类型的批处理需要,建议使用Pipeline功能:

@Test
void testPipeline() {    
  // 创建管道    
  Pipeline pipeline = jedis.pipelined();    
  for (int i = 1; i <= 100000; i++) {        
    // 放入命令到管道        
    pipeline.set("test:key_" + i, "value_" + i);        
    if (i % 1000 == 0) {             
    // 每放入1000条命令,批量执行            
      pipeline.sync();        
    }    
  }
}

批量处理的方案:

-- 原生的M操作

-- Pipeline批处理

注意事项:

-- 批处理时不建议一次携带太多命令

-- Pipeline的多个命令之间不具备原子性

集群下的批处理

如MSET或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如果Redis是一个集群,那批处理命令的多个key必须落在一个插槽中,否则就会导致执行失败。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韩未零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值