可以在 Redis 集群中使用管道吗?

uoh*_*ela 5 redis jedis redis-cluster

目前,我们的Redis设置涉及Jedis + 分片。向上和向下扩展涉及手动添加/删除分片,这是大量的操作工作。我们还严重依赖管道,因为我们每秒进行大量写入。

因此,我们正在研究 Redis 集群来自动化分片过程。然而,对我们来说,一个问题是 Jedis 不支持 Redis 集群的管道: https://groups.google.com/forum/#!msg /redis-db/4I0ELYnf3bk/Lrctk0ULm6AJ

我们知道Codis支持流水线+自动分片,但由于其对Zookeeper的依赖,需要大量的运维工作来维护。它也是 Redis 的一个分支,因此可能不会随上游更改而更新。如果没有好的解决方案将管道与官方 Redis 集群实现一起使用,我们很可能会使用它。

只是想知道官方 Redis 集群是否可以进行管道传输?也许以替代 Redis 客户端的形式?

Zuu*_* Dj 5

是的,您可以在集群模式下使用管道,只要密钥散列到相同的密钥槽(而不是节点)。

要实现密钥散列到同一槽,您可以使用散列标签。TLDR - 如果您的键 {} 中有大括号,哈希函数将仅应用于该部分https://redis.io/docs/reference/cluster-spec/#hash-tags

在我的特定情况下,我需要按 ID 将国家和城市放入 Redis 中,总共 15 万条记录。我就是这样做的(nodejs + ioredis):

if (countries.length && cities.length) {
  const pipelines = []
  for (let i = 0; i < 21; i++) {
    pipelines.push(redis.pipeline())
  }
  await Promise.all([
    Promise.map(countries, (country) => {
      const randomPipeline = pipelines[country.id % 21]
      randomPipeline.set(`country_${country.id}_{${country.id % 21}}`, JSON.stringify(country))
    }),
    Promise.map(cities, (city) => {
      const randomPipeline = pipelines[city.id % 21]
      randomPipeline.set(`city_${city.id}_{${city.id % 21}}`, JSON.stringify(city))
    })
    
])
  for (let i = 0; i < 21; i++) {
    await pipelines[i].exec()
  }
  console.log('Countries and cities in cache')
}
Run Code Online (Sandbox Code Playgroud)


Sol*_*olo 3

jedis 发布版本尚不支持集群管道,但现在有贡献等待合并,参考https://github.com/xetorthio/jedis/pull/1455

您也可以编写自己的实现,参考该实现,基本思想是捕获通过管道发送的所有命令,并重播它们以进行集群重定向,因为当所有键都属于同一个槽时,集群中的管道可以正常工作。