【问题标题】:How can I enumerate all keys in our Redis database?如何枚举 Redis 数据库中的所有键?
【发布时间】:2013-07-23 20:06:09
【问题描述】:

我们有一个庞大的 Redis 数据库,其中包含大约 1 亿个键,它将电话号码映射到数据的哈希值。

有时需要汇总所有这些数据并将其保存到 SQL 数据库中。在聚合期间,我们需要遍历所有存储的键,并查看这些数组。

使用Redis.keys 不是一个好选择,因为它会检索整个键列表并将其存储在内存中,并且需要很长时间才能完成。我们需要一些能够返回一个可用于迭代所有键的枚举器的东西,如下所示:

redis.keys_each { |k| agg(k, redis.hgetall(k)) }

Redis 甚至可以做到这一点吗?

这将阻止 Ruby 在内存中构造一个包含 1 亿个元素的数组,并且可能会更快。 Profiling 向我们展示了使用Redis.keys 命令使 Ruby 以 100% 的速度占用 CPU,但 Redis 进程似乎处于空闲状态。

我知道不鼓励使用键从键构建集合,但即使我们从键构建集合并使用 smembers 检索它,我们也会遇到同样的问题。

【问题讨论】:

  • 听起来您需要一个用于临时存储 Redis 数据存储的后端数据库表。我会尝试定期扫描 Redis 数据库以查找不在表中的记录并将它们复制过来。然后我会点击该表以将数据聚合并拉入主数据库。这将使 Redis 方面的任务降至最低,并允许您利用 SQL 数据库的迭代/聚合功能。

标签: ruby database redis


【解决方案1】:

当前 Redis 版本无法增量枚举所有键。

您可以直接转储数据库 (bgsave) 并将生成的转储文件转换为 json 文件,以便使用所需的任何 Ruby 工具进行处理,而不是尝试提取实时 Redis 实例的所有密钥。

https://github.com/sripathikrishnan/redis-rdb-tools

或者,您可以使用 redis-rdb-tools API 直接在 Python 中编写解析器并提取所需的数据(无需生成 json 文件)。

【讨论】:

  • 从一个文件中读取 1 亿条 JSON 记录将把一个大文件塞进内存中,只是为了进行解析,这将导致同样的问题,只是在不同的阶段。将数据输出到 CSV 将允许增量读取记录。
  • 使用流式 API 读取 JSON 文件,或使用 Python 中的 redis-rdb-tools 编写解析器并输出 CSV 或您喜欢的数据格式。
  • 有关 Ruby 的 JSON 流 API 示例,请参阅github.com/brianmario/yajl-ruby
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 2017-04-03
相关资源
最近更新 更多