多个 Redis 数据库的意义何在?
Posted
技术标签:
【中文标题】多个 Redis 数据库的意义何在?【英文标题】:What's the Point of Multiple Redis Databases? 【发布时间】:2013-04-19 17:59:39 【问题描述】:所以,我想将存储在 redis 中的数据分段到单独的数据库中,因为有时我需要对一种特定类型的数据使用 keys 命令,并希望将其分离为让它更快。
如果我分割成多个数据库,一切仍然是单线程的,我仍然只能使用一个核心。如果我只是在同一个盒子上启动另一个 Redis 实例,我就可以使用一个额外的核心。最重要的是,我不能命名 Redis 数据库,或者给它们任何更合乎逻辑的标识符。那么,综上所述,为什么/何时我想要使用多个 Redis 数据库,而不是为我想要的每个额外数据库启动一个额外的 Redis 实例?与此相关的是,为什么 Redis 不尝试为我添加的每个额外数据库使用一个额外的核心?跨数据库单线程有什么好处?
【问题讨论】:
在您的 Node.js 应用程序中,执行此操作 ---> module.exports = "1":"your name for redis db one","2":"your name for redis db two ","3":"your name for redis db three" 等,或者根据需要切换键和值 在 Redis 2.8.0 及更高版本中,建议您使用 SCAN 而不是 KEYS,因为它一次迭代少量元素(因此不会长时间阻塞服务器) . 【参考方案1】:原则上,同一实例上的 Redis 数据库与 RDBMS 数据库实例中的模式没有什么不同。
那么,说了这么多,我为什么/什么时候想使用多个 Redis 数据库,而不仅仅是启动一个额外的 Redis 实例 对于每个我想要的额外数据库?
在同一个 redis 实例中使用 redis 数据库有一个明显的优势,那就是管理。如果您为每个应用程序启动一个单独的实例,假设您有 3 个应用程序,那就是 3 个单独的 redis 实例,每个实例都可能需要一个从属服务器来实现生产中的 HA,所以总共有 6 个实例。从管理的角度来看,这很快就会变得一团糟,因为您需要监控所有这些,进行升级/补丁等。如果您不打算用高 I/O 重载 redis,那么带有从属的单个实例更简单,并且如果它符合您的 SLA,则更易于管理。
【讨论】:
多个 Redis 实例总是要走的路。时期。对不同的数据运行并行查询。如果您的 CICD 管道没有为您创建缓存集群,请修复它,而不是......您明白了 这并没有解决 OP 的问题:(1)为什么 Redis 不尝试为每个额外的数据库使用一个额外的核心? (2) 跨数据库单线程有什么好处? 如果Redis数据库和RDBMS中的schema一样,为什么在RDBMS中不常用DBx(不同于DB0)作为shcemas的使用?【参考方案2】:您不想在单个 redis 实例中使用多个数据库。正如您所指出的,多个实例可让您利用多个核心。如果您使用数据库选择,您将不得不在升级时进行重构。监控和管理多个实例并不困难也不痛苦。
确实,通过基于实例的隔离,您会在每个数据库上获得更好的指标。每个实例都有反映该数据段的统计信息,这可以实现更好的调整以及更灵敏和更准确的监控。使用最新版本并按实例分隔数据。
正如 Jonaton 所说,不要使用 keys 命令。如果您简单地创建一个键索引,您会发现性能要好得多。每当添加密钥时,将密钥名称添加到集合中。放大后,keys 命令并不是很有用,因为它需要很长时间才能返回。
让访问模式决定如何构建您的数据,而不是按照您认为可行的方式存储数据,然后再考虑如何在以后访问和压缩数据。您将看到更好的性能,并发现消耗数据的代码通常更干净、更简单。
关于单线程,考虑到 redis 是为速度和原子性而设计的。修改一个数据库中的数据的某些操作不需要等待另一个数据库,但是如果该操作正在保存到转储文件或处理从属上的事务怎么办?到那时,您就会开始涉足并发编程。
通过使用多个实例,您可以将多线程复杂性转变为更简单的消息传递样式系统。
【讨论】:
如果我需要某个数据库中的每个键,为什么要从一个集合中访问所有这些键然后迭代比键命令更快?两者都是 O(n),但是 set 方法需要最多两倍的空间,并且需要更多的来回和数据传输。 不推荐使用多个数据库?您能否为该声明提供参考。我知道 Redis 集群不支持多个数据库,但也不支持任何复杂的多键命令,并且它们没有被弃用。 Some (strong) evidence 来自 Redis 的“所有者”(根据 Google 代码),“......数据库不会被弃用,即使我过去说过它们会被弃用。” 您将无法在 redis-cluster 上使用多个 redis db。除此之外,多个数据库仍然是一回事。 -1 表示已弃用的语句。在 redis-cluster 中可能不鼓励和不支持多个数据库,但它们不会被弃用。【参考方案3】:即使是 Salvatore Sanfilippo(Redis 的创建者)也认为在 Redis 中使用多个数据库是个坏主意。在此处查看他的评论:
https://groups.google.com/d/topic/redis-db/vS5wX8X4Cjg/discussion
我知道这很有用,但不幸的是我认为 Redis 多个数据库错误是我在 Redis 设计中最糟糕的决定 所有...没有任何真正的收获,它使内部结构很多 更复杂。现实情况是数据库不能很好地扩展 原因的数量,例如密钥和 VM 的活动过期。如果数据库 可以使用字符串执行选择我可以看到此功能 用作可扩展的 O(1) 字典层,但事实并非如此。
有DB号,默认几个DB,我们是通信 我认为更好的是这个功能是什么以及如何使用。我希望 在某些时候我们可以完全放弃对多个数据库的支持,但我认为 可能为时已晚,因为有很多人依赖于此 他们工作的特色。
【讨论】:
等等,所以使用 DB 选择实际上比只使用前缀效率低?这就是这句话的意思吗(有人可以澄清一下)吗? “如果可以使用字符串执行 DB 选择,我可以看到此功能被用作可扩展的 O(1) 字典层,但事实并非如此。” 这实际上并不是说使用它们是一个坏主意。它说他一开始就包含这个选项是个坏主意。【参考方案4】:我真的不知道在一个实例上拥有多个数据库有什么好处。我想如果多个服务使用相同的数据库服务器会很有用,这样可以避免密钥冲突。
我不建议使用KEYS
命令进行构建,因为它是 O(n) 并且不能很好地扩展。你用它来做什么,你可以用另一种方式完成?如果KEYS
之类的功能至关重要,那么 redis 可能不是您的最佳选择。
我认为他们在其常见问题解答中提到了单线程服务器的好处,但主要的是简单性 - 您不必以任何实际方式为并发而烦恼。每个动作都是阻塞的,所以没有两件事可以同时改变数据库。理想情况下,每个服务器的每个核心都有一个(或多个)实例,并使用一致的散列算法(或代理)在它们之间划分密钥。当然,你会失去一些功能——管道只能用于同一服务器上的东西,排序变得更难等等。
【讨论】:
针对2:我只在需要所有键的时候才使用keys命令。我使用它的方式与使用 hgetall 的方式相同。两者都是 O(n)。如果您需要在大量键中搜索某些正则表达式,键是不好的,但如果您需要对某些数据库中的所有键进行一些操作,则非常好。回应3:我了解单线程在一个数据库上的好处。我不了解许多数据库,因为对一个数据库的操作永远不需要阻止对另一个数据库的操作 AFAIK。【参考方案5】:我正在使用 redis 来实现电子邮件地址的黑名单,并且对于不同级别的黑名单我有不同的 TTL 值,因此在同一实例上拥有不同的数据库对我有很大帮助。
【讨论】:
我们现在面临同样的问题——我们想为数据的不同部分定义不同的 LRU 策略。你能分享一下你是如何实现的吗? @user2717436 我不确定我所做的是否与您的相关,但我使用不同的数据库作为不同的集合,插入时总是设置键的 TTL。就像 redis.get(1) 上有黑名单 A 一样,每当我在那里设置密钥时,我都会将 expire 设置为 5000 。 redis.get(2) 上有黑名单 B,每当我在那里设置密钥时,我将 expire 设置为 10000【参考方案6】:Redis 数据库可用于部署新版本应用程序的极少数情况,其中新版本需要使用不同的实体。
【讨论】:
【参考方案7】:我知道这个问题已有多年历史了,但多个数据库可能有用还有另一个原因。
如果您使用您最喜欢的云提供商提供的“云 Redis”,您可能有一个最小内存大小,并且将为您分配的内容付费。但是,如果您的数据集小于此值,那么您将浪费一些分配,从而浪费一些钱。
使用数据库,您可以使用相同的 Redis 云实例为(例如)开发、UAT 和生产,或您的应用程序的多个实例或其他任何实例提供服务 - 从而使用更多分配的内存,因此有点更划算。
我正在查看的一个用例有几个应用程序实例,每个实例使用 200-300K,但我的云提供商上的最小分配是 1M。我们可以将 10 个实例整合到一个 Redis 上,而不会真正削弱任何限制,因此可以节省大约 90% 的 Redis 托管成本。我很欣赏这种方法存在局限性和问题,但认为值得一提。
【讨论】:
我认为在同一个 Redis 实例中组合 prod、dev 和 UAT 的用例忽略了允许 QA 和开发人员访问生产数据的安全隐患 同意 - 在任何“严重”环境中,对非产品和产品使用相同的 redis 服务器可能是一个糟糕的举动。在较小的商店中混合使用 dev/uat 可能是可能的,但您的观点是正确的。多个 Redis 数据库只允许这样做 - 这并不是一个好主意 ;-)【参考方案8】:在一个实例中使用多个数据库可能在以下场景中很有用:
同一数据库的不同副本可用于使用实时数据进行生产、开发或测试。人们可能会使用副本来克隆一个 redis 实例以达到相同的目的。但是,前一种方法更容易让现有的运行程序只需选择正确的数据库即可切换到预期的模式。
【讨论】:
那么切换数据库比切换实例更简单?在这两种情况下,您都需要更改一个数字:数据库 ID 或端口号... 切换数据库副本更简单,因为它们使用相同的登录密码,更快地将表从一个副本复制到另一个副本,更容易和更快的数据比较等。如果您切换实例,则需要更多内存对于 Redis 服务器,配置文件,各种操作延迟较长。以上是关于多个 Redis 数据库的意义何在?的主要内容,如果未能解决你的问题,请参考以下文章