一批大量的 redis 请求都过来, 怎么优化(批处理优化问题)


面试问到一千条 redis 命令来到,怎么进行优化,来减少处理时间。

之前没了解过,然后想的一些方案并不是这么有效,所以下来自己总结一下。

单机模式下

暂时先讲单机模式下的批处理优化。

通信携带命令条数不同导致效率不同

  1. 如果一次客户端到 redis 服务端的通信中只携带一条 redis 指令,那大概的总耗时就是:1 个来回时间 + 1 个 redis 处理命令时间。N 次就是 N 个来回时间 + N 条命令处理时间。

画个图吧:

  1. 一次通信携带多条指令,减少总的通信次数。

这样的 N 条命令的总耗时就为:N/M 个来回时间,N 个处理时间。(M 代指每次携带的命令条数)。

图就不画了,应该能想象出来,不是重点。

  1. 总之:通信时间在 Redis 的使用过程中占大头,所以减少通信次数就是批处理优化的一个主要攻克点

Redis 中怎么操作

我当时想到了列表 List 数据类型,但是列表好像并不算是一个批处理命令,然后就扯其他的了。

现在才醒悟,对啊,mset hmset。就是专门用来做批处理的命令,怎么没想到类比 Mysql 分批插入大量数据呢。也就是一次把多个 redis 命令封装在一起作为一次通信发给 Redis 客户端。

语法

mset key1 value1 [ key2 value2]

hmset key field1 value1 [field2 value2]

代码示例

如上,可以通过数组传递需要设置的批量 redis 命令,设置 String 类型的。并且 key 可以不变。而对于 hash 数据类型,其批量插入只能指定一个键。Set 类型的批量插入命令(SADD)也是有局限的(只能指定一个 set 的键)。

MSET 命令,数组批量插入示例:
|500

PipeLine 优化批处理执行

PipeLine 不管是 Jedis 还是 Redis 都提供的有,这个主要是用来把各种不同的 Redis 命令都装在一起,然后统一发送到 Redis 服务端。

与批处理命令不同的是,这个可以装”不同的命令”,也就是说可以解决 HMSET 和 SADD 中批量插入时只能指定一个 Key 的问题。你只要把多个 SADD 命令和 HMSET 命令装进来就行了。

示例:

  1. 模拟 MSET

PipeLine 的 sync() 命令就是发起一次通信请求到 Redis 服务端。

但是命令到达之后可能就会进入队列中等待,执行的顺序是有先后的,所以呢速度可能会比 mset 慢一些,但是好在对更多的数据类型都支持。

集群模式下

在集群模式下,如果批处理命令没有分配到同一个槽位(也就是同一个 Redis 节点),就会导致执行失败。所以在集群部署下做批处理就需要其他工具了。

TODO


文章作者: KTpro
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 KTpro !
评论
  目录