Redis 使用队列进行批量处理
2020-11-19 本文已影响0人
paul_deng
需求
某个请求会有时候突然很大的访问,这些访问如果都是一个个处理,会导致很高的 DB 与 程序的 CPU 占用。
解决
通过 redis 队列存储进来的内容,然后批量进行处理。
备注:
使用 redis.rpop 主要是为了避免通过 ruby 的 loop 一直遍历读取 redis 的值,判断是否有更新。
WS_CHANNEL = 'ws_channel_1'
MESSAGE_BULK_SIZE = 20 # 批量处理的消息数量
# 读取队列顶部(最早)的信息(阻塞的,直到有信息才继续执行)
while (msg = redis.rpop(WS_CHANNEL))
messages = [msg[1]] # 消息格式如下:["ws_channel", "{:id=>4}"]
# sleep(0.5) # 如果有需要,可以加等待,等足够多的信息再进行处理,但影响实时性能
# 批量读取顶部的信息(假设突然间有多个信息进入到 redis, 使用 pile_lines 优化性能)
pipe_lines = redis.pipelined do
# 读取信息,并按时间的远到近排序
redis.lrange(WS_CHANNEL, 0, MESSAGE_BULK_SIZE)
# 清空
redis.ltrim(WS_CHANNEL, MESSAGE_BULK_SIZE + 1, -1)
end
ext_messages = pipe_lines[0]
# 按最早到最晚排序
messages += ext_messages.reverse if ext_messages.present?
# 输入内容
puts messages
end
其他用途
也可以参考上述代码,通过队列监听取代 pub/sub。非推荐,只是作为简化的可选方案。