使用 redis.rb 这个 gem 往 Redis 中大量地写,每秒钟数千个 request,发现在多线程环境下会遇到比较严重的性能问题。
比如,在方法 process_item
中有 1000 次 set,如果单线程执行这个方法,耗费 1s;当有 5 个线程并行执行这个方法时,这个方法会耗费 10~15s!
看了下 redis.rb 这个 gem 中:
class Redis
...
include MonitorMixin
def synchronize
mon_synchronize { yield(@client) }
end
def incr(key)
synchronize do |client|
client.call([:incr, key])
end
end
所有方法都有 synchronize
同步,根据 MonitorMixin 的文档:
at each point in time, at most one thread may be executing any of its methods.
怀疑就是多个线程在互相等解锁,造成每个线程执行 process_item
方法成倍增加。
尝试使用了 connection_pool 这个库,并不能解决问题,我认为这个 gem 对 Redis 根本没有作用,无法避免方法全局锁的限制。
有没有好的办法解决这样多线程并发地写 Redis 的问题呢?