多个Redis数据库有什么意义?


159

因此,我来​​到了一个地方,我想将存储在Redis中的数据分段到单独的数据库中,因为有时我需要对一种特定类型的数据使用keys命令,并希望将其分开以使其更快。

如果我细分为多个数据库,那么所有内容仍然都是单线程的,而且我仍然只能使用一个内核。如果我只是在同一盒子上启动另一个Redis实例,那么我将使用一个额外的内核。最重要的是,我无法命名Redis数据库,也无法给它们提供任何更逻辑的标识符。因此,话虽这么说,为什么/何时我要使用多个Redis数据库,而不是仅仅为我想要的每个额外数据库分配一个Redis额外实例?与此相关的是,Redis为什么不尝试为我添加的每个额外数据库利用额外的内核?跨数据库单线程的优势是什么?


在您的Node.js应用中,执行---> module.exports = {“ 1”:“您的Redis数据库名称”,“ 2”:“您的Redis数据库2名称”,“ 3”:“您的redis db的名称三“}等,或根据需要切换键和值
Alexander Mills

1
在Redis 2.8.0及更高版本中,建议您使用SCAN而不是KEYS,因为它一次遍历少量元素(因此不会长时间阻塞服务器)。
TryHarder

Answers:


85

原则上,同一实例上的Redis数据库与RDBMS数据库实例中的架构没有区别。

因此,话虽这么说,为什么/何时我要使用多个Redis数据库,而不是仅仅为我想要的每个额外数据库分配一个Redis额外实例?

在同一redis实例中使用redis数据库有一个明显的优势,那就是管理。如果您为每个应用程序启动一个单独的实例,并且假设您有3个应用程序,则这是3个独立的Redis实例,每个实例在生产中可能都需要从属HA实例,因此总共有6个实例。从管理的角度来看,这很快就会变得混乱,因为您需要监视所有这些,进行升级/修补等。如果您不打算通过高I / O来重载Redis,那么具有从属的单个实例会更简单,并且只要满足您的SLA,就更易于管理。


25
始终使用多个Redis实例。期。对不同的数据运行并行查询。如果您的CICD管道没有为您创建缓存集群,请对其进行修复,而不要解决.....您明白了
Cmag

3
这不能解决OP的要点:(1)为什么Redis不尝试为每个额外的数据库利用额外的内核?(2)在数据库中使用单线程有什么优势?
ives

93

您不想在单个Redis实例中使用多个数据库。它已弃用,并且如您所述,多个实例使您可以利用多个核心。如果使用数据库选择,则升级时必须重构。监视和管理多个实例既不困难也不痛苦。

实际上,通过基于实例的隔离,您将在每个数据库上获得更好的指标。每个实例将具有反映该数据段的统计信息,这可以允许进行更好的调整以及更敏感和更准确的监视。使用最新版本并按实例分隔数据。

正如乔纳顿所说,不要使用keys命令。如果仅创建一个键索引,您将发现更好的性能。每当添加密钥时,请将密钥名称添加到集合中。一旦扩大规模,keys命令就不会非常有用,因为返回将花费大量时间。

让访问模式确定如何构造数据,而不是按照您认为的工作方式存储数据,然后解决如何访问数据并将其切碎。您将看到更好的性能,并且发现使用数据的代码通常更干净,更简单。

关于单线程,请考虑将redis设计用于速度和原子性。确定在一个数据库中修改数据的操作不必等待另一数据库,但是如果该操作保存到转储文件或在从属服务器上处理事务该怎么办?到那时,您开始涉足并发编程的杂草。

通过使用多个实例,您可以将多线程复杂度转换为更简单的消息传递样式系统。


57
不建议使用多个数据库?您能否为该声明提供参考。我知道Redis Cluster不支持多个数据库,但也不是任何复杂的多键命令,因此不建议使用它们。
ostergaard

27
来自Redis的“所有者”(根据Google Code)的一些(有力的)证据表明:“即使我过去曾声明过……数据库也不会被弃用。”
肯尼·埃维特

3
您将无法在redis-cluster上使用多个redis数据库。除此之外,多个数据库仍然是一件事情。
coredump

26
-1为已弃用的语句。可能不建议使用多个数据库,并且redis-cluster中不支持多个数据库,但是不建议使用它们。
AgDude 2015年

1
@ the-real-bill如何“创建密钥索引”?
Kees de Kooter

57

甚至Salvatore Sanfilippo(Redis的创建者)也认为在Redis中使用多个数据库是一个坏主意。在这里查看他的评论:

https://groups.google.com/d/topic/redis-db/vS5wX8X4Cjg/discussion

我知道这是有用的,但是不幸的是,我认为Redis多个数据库错误是我在Redis设计中最糟糕的决定...如果没有任何真正的收获,它会使内部结构变得更加复杂。现实情况是数据库由于多种原因无法很好地扩展,例如密钥和VM的有效期满。如果可以使用字符串执行数据库选择,那么我可以看到此功能被用作可伸缩的O(1)字典层,但事实并非如此。

使用数据库编号,默认情况下有几个数据库,我们可以更好地沟通此功能的含义以及如何使用。我希望在某个时候我们可以完全放弃对多个数据库的支持,但是我认为为时已晚,因为有很多人依靠此功能来工作。


4
等等,所以使用数据库选择实际上不如仅使用前缀有效?这句话在这里是什么意思(有人可以澄清一下)吗?“如果可以使用字符串执行数据库选择,那么我可以看到此功能被用作可伸缩的O(1)字典层,但事实并非如此。”
dvtan

8
  1. 我真的不知道在单个实例上拥有多个数据库有什么好处。我想如果多个服务使用相同的数据库服务器很有用,那么可以避免键冲突。

  2. 我不建议使用该KEYS命令来构建,因为它是O(n)且扩展性不佳。您将其用于其他目的的目的是什么?如果功能KEYS至关重要,那么redis可能不是您的最佳选择。

  3. 我认为他们在FAQ中提到了单线程服务器的好处,但是主要的是简单性-您不必以任何实际的方式来烦恼并发性。每个操作都处于阻塞状态,因此没有两件事可以同时更改数据库。理想情况下,每个服务器的每个核心将有一个(或多个)实例,并使用一致的哈希算法(或代理)在其中划分密钥。当然,您将失去一些功能-管道仅适用于同一台服务器上的事物,排序变得更困难等。


作为对2的响应,我仅在需要所有键时才使用keys命令。我以与使用hgetall相同的方式使用它。两者均为O(n)。如果您需要搜索一些正则表达式的大量键,则键是不好的,但是如果您需要对某些数据库中的所有键进行一些操作,则键会很好。针对3:我了解在一个数据库上单线程的好处。我对许多数据库都不了解,因为对一个数据库的操作永远不需要阻止对另一个数据库AFAIK的操作。
伊莱

3

我正在使用Redis实施电子邮件地址黑名单,并且对于不同级别的黑名单,我具有不同的TTL值,因此在同一实例上使用不同的数据库对我有很大帮助。


1
现在,我们面临着同样的问题-我们想为数据的不同部分定义不同的LRU策略。您能否分享一下您是如何实现的?
user2717436

@ user2717436我不确定我的工作是否与您的工作有关,但是我将不同的数据库用作不同的集合,请在插入密钥时始终设置密钥的TTL。就像redis.get(1)上有黑名单A一样,每当我在其中设置密钥时,我都将expire设置为5000。并且redis.get(2)上有一个黑名单B,每当我在其中设置密钥时,我设置的过期时间都为10000
kommradHomer

2

在极少数情况下,可以使用Redis数据库来部署应用程序的新版本,因为新版本需要与不同的实体一起使用。


1

在以下情况下,在单个实例中使用多个数据库可能会很有用:

可以使用实时数据将同一数据库的不同副本用于生产,开发或测试。人们可以使用副本克隆redis实例来达到相同的目的。但是,对于现有的运行程序来说,前一种方法更容易,只需选择正确的数据库即可切换到预期的模式。


1

我知道这个问题已有多年历史了,但是还有另一个原因可能是多个数据库有用。

如果您使用自己喜欢的云提供商提供的“ cloud Redis”,则可能具有最小的内存大小,并将为您分配的内存付费。但是,如果您的数据集小于该数据集,那么您将浪费一些分配,从而浪费了一些钱。

使用数据库,您可以使用相同的Redis云实例为(例如)开发,UAT和生产提供服务,或者为应用程序的多个实例提供服务,或者其他任何方式-这样会占用更多的已分配内存,因此成本更高一些-有效。

我正在查看的一个用例有一个应用程序的多个实例,每个实例使用200-300K,但在我的云提供程序上的最小分配为1M。我们可以将10个实例整合到一个Redis中,而不会在任何限制下造成任何损失,因此可以节省大约90%的Redis托管成本。我很欣赏这种方法的局限性和问题,但值得一提。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.