Redis Redis 使用及源码的一些疑惑

night_7th · 2016年04月12日 · 最后由 night_7th 回复于 2016年04月15日 · 8190 次阅读

最近准备使用 sidekiq 做异步队列,sidekiq 又基于 Redis,我对于 Redis 并不是很熟悉,现在遇到一些问题想请教一下大家:

1.我们现在已经使用了一个 Redis 用于存储 session,以及同系统其他组件打交道,那 sidekiq 的 Redis 是需要一个新的 Redis 呢,还是使用已有的 Redis 呢,我担心会不会有一些冲突。

2.因为公司原因,我们需要使用公司内别的部门提供的 Redis 服务,当前我们申请的是一个分布式的 Redis,结果在本地调试连接这个分布式的 Redis 时 sidekiq 报错了,一处是调用了info方法,另外一处是调用了 Redis 的brpop方法,这两个方法分布式的 Redis 均不支持,而且一旦调用了,Redis 就自动把连接给断开了。

def retrieve_work
  # 这里调用了brpop
  work = Sidekiq.redis { |conn| conn.brpop(*queues_cmd) }
  UnitOfWork.new(*work) if work
end

这个地方我也有困惑,我查了下brpop,是一个阻塞型方法,是不是分布式的系统很难实现阻塞型方法呢?因为我看了下公司分布式 Redis 的文档,不支持的指令列表中好几个指令都是 b 开头的。

1.用同一个 Redis 是没问题的,只要注意 key 别冲突了就行 2.brpop 是对客户端阻塞的,我猜你们公司的分布式 Redis 是用了中间层代理吧,连到 Redis 上的是中间代理层,而客户端是连接到代理层的,所以不太好实现。其实要实现阻塞也是有办法的,比如为阻塞的命令建立特定的连接。

RedisStore 和 Sidekiq 都允许手动初始化 redis client, 设置 db. 条件允许的话还是把 db 分开比较好, 不然就要记住 sidekiq 用的哪些 key.

@numbcoder 对的,我从同事那了解到的是,是有一个代理层做业务转发,遇到不支持的命令,这个代理层就直接掐断连接了。

那这种情况下,sidekiq 有可能直接调用rpop么【我尝试修改了一下,没有报错了,但是 sidekiq 彻底不工作了】...

还有一种比较省事的办法,我申请一个单节点的 Redis,当时申请 Redis 的时候考虑到分布式的可能服务更稳定一些,单节点的万一服务挂了,就彻底挂了

@karloku 也就是说,一个 web server,可能会有多个 redis 服务器,这种算比较普遍的情况咯?

#4 楼 @night_7th redis 一般是单进程的,多开几个开销很小的

@nouse 现在主要考虑的是单节点 Redis 的可靠性,以及多个 Redis 方不方便后期的维护。

#4 楼 @night_7th 单 redis 实例 是可以支持多 db 的,但是你们用了中间层,不知道是否支持多 db。二楼的意思是你可以把 sidekiq 的 db 和 session 的 db 分开,这样可以避免 key 的冲突。

#3 楼 @night_7th rpop 是非阻塞命令,当然可以调用,但是对于 sidekiq 来说,把 brpop 改成 rpop 当然有问题,具体你可以看一下二者的区别

命名空间不一样也可以避免 key 的冲突

@rei @numbcoder @embbnux 3Q ALL,现在问题 1 的答案基本已经清晰了。

问题 2 的话,我估计只有两条路可以走了:

  1. 尝试修改 sidekiq 源码,将阻塞型操作替换成非阻塞型。
  2. 尝试用 Resque 或其他队列系统替换掉 sidekiq,前提是这些队列中也不会有阻塞型操作

除非能找到一些证据证明单节点的 Redis 也是能够提供可靠服务的。

更新一下进展: 问题 1. 经询问 sidekiq 的原作者,他表示 brpop 这个操作是必须的,建议我使用单节点的 Redis。 问题 2. Resque 倒是没有用 brpop,但是调用了一个 keys 方法,这个方法公司的 Redis 也不支持【还没有尝试,估计一样会掉线】...

又想了两条路: 1.绕开 Redis,找个不依赖于 Redis 的队列 2.老老实实用单节点的 Redis

已经吐血斗升,个人更倾向于使用单节点的 Redis 的... 如果大家有用 sidekiq,可以说说你们的 Redis 出过问题没...

sidekiq 只是把 redis 当做一个中间件来使用,就算你的后台任务是分布在 N 个服务器上面运行,也不会影响他们使用同一个中间件---redis 服务器,这个 redis 服务器运行在哪里不重要,只要它能够提供 sidekiq 需要使用的命令就可以了。

@uestc_bird

你说的是异步服务的可靠性,但是 Redis 的可靠性也需要考虑进来。现在就是希望一个分布式的 Redis,来保障 Redis 的高可用,然而分布式的 Redis 并不支持infobrpop之类的 sidekiq 需要使用的指令。

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