Redis 使用队列进行批量处理

需求

某个请求会有时候突然很大的访问,这些访问如果都是一个个处理,会导致很高的 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。非推荐,只是作为简化的可选方案。

参考

Redis 参考:https://www.runoob.com/redis/redis-lists.html

你可能感兴趣的:(Redis 使用队列进行批量处理)