新手问题 Rails 中 redis 与 mysql 不同配置方式引发的疑问

dudu_zzzz · 2016年02月19日 · 最后由 pathbox 回复于 2016年02月21日 · 2165 次阅读

在用 redis.rb 配置 redis 的时候 大概都会有这么一句

$redis = Redis.new(:host => 'localhost', :port => 6379, :db => 10)

之后所有需要使用 redis 的地方,只要用这个 $redis 就可以了。

我理解成,操作 redis 反反复复都只用了 $redis 这一个连接,而对于一般关系型数据库往往使用连接池。

为什么 redis 只需要使用这一个连接呢?是因为 redis 单线程的关系吗?

关系型数据库使用连接池是为了多线程 server (如 puma) 的情况。 如果使用的 redis-rb 这个 client 话,只用 $redis 一个连接也是能保证线程安全性的,因为 redis-rb 内部每一个命令都是有锁的。 这和 redis 是单线程并没有关系,redis 是可以同时处理多个 client 链接的。 redis 也可以用线程池

连接池是为了解决并发连接的问题。redis 的单线程以及它的内部策略 使得它在并发情况下也是线程安全的。看了下 redis-rb 源码的命令,没看见加锁的代码,用了

synchronize 

,也就是

mon_synchronize { yield(@client) } 

根据 MonitorMixin 的文档: at each point in time, at most one thread may be executing any of its methods. 。然后在调用 redis 的命令,所有的 call 调用,都封装在同步方法中。不太同意上层所说每个 redis-rb 内部每一个命令都是有锁的,和 redis 单线程没有关系。相反觉得和 redis 的单线程是有关系,并且不是 redis-rb 的每个命令都是有锁的。(因为没看见锁在哪,除非 synchronize 是锁操作)仅是自己的观点和学习讨论 #1 楼 @nowherekai

#2 楼 @pathbox MonitorMixin 的实现用了锁。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册