【问题标题】:Storing 13 Million floats and integer in redis在 redis 中存储 1300 万个浮点数和整数
【发布时间】:2019-06-26 22:04:54
【问题描述】:

我有一个包含 1300 万个浮点数的文件,每个浮点数都有一个相关的整数索引。文件的原始大小为 80MB。

我们要传递多个索引来获取浮点数据。唯一的原因,我需要 hashmap 字段和值,因为 List 不支持传递多个索引来获取。

将它们作为hashmap存储在redis中,索引为字段,浮点为值。在检查内存使用情况时,它大约是 970MB。

存储 1300 万作为列表使用 280MB。

有什么我可以使用的优化吗?

提前致谢

在弹性缓存上运行

【问题讨论】:

    标签: redis


    【解决方案1】:

    您可以通过创建索引与浮点值的存储桶来进行真正的优化。 哈希在内部进行了非常内存优化。 因此,假设您在原始文件中的数据如下所示:

    index, float_value
    
    2,3.44
    5,6.55
    6,7.33
    8,34.55
    

    并且您当前已将它们存储在哈希或列表中的一个索引到一个浮点值。 您可以对值进行分桶优化:

    哈希键为索引%1000,子键为索引,值为浮点值。

    还有更多详情here

    起初,我们决定以最简单的方式使用 Redis: 每个 ID,键是媒体 ID,值是 用户 ID:

    设置媒体:1155315 939 获取媒体:1155315

    939 然而,在对这个解决方案进行原型设计时,我们发现 Redis 需要大约 70 MB 来存储 1,000,000 个密钥。外推至 我们最终需要的 300,000,000,它正在寻找 21GB 的数据 — 已经大于 17GB 的实例类型 亚马逊 EC2。

    我们询问了 Redis 的核心成员之一,总是乐于助人的 Pieter Noordhuis 开发人员,作为输入,他建议我们使用 Redis 哈希。散列在 Redis 是可以在内存中编码的字典 有效率的; Redis 设置“hash-zipmap-max-entries”配置 哈希在仍然存在时可以拥有的最大条目数 有效编码。我们发现这个设置最好在 1000 左右;任何 更高,HSET 命令会导致明显的 CPU 活动。为了 更多详细信息,您可以查看 zipmap 源文件。

    为了利用散列类型,我们将所有媒体 ID 存储到 1000 个桶(我们只取 ID,除以 1000 并丢弃 余)。这决定了我们落入哪个键;接下来,在 存在于该键的哈希,媒体 ID 是查找键 哈希,用户 ID 是值。一个例子,给定一个媒体 ID 1155315,这意味着它落入桶 1155 (1155315 / 1000 = 第1155章:

    HSET "mediabucket:1155" "1155315" "939" HGET "mediabucket:1155" "1155315"

    "939" 大小差异非常明显;使用我们的 1,000,000 个密钥原型(编码为 1,000 个哈希,每个哈希包含 1,000 个子密钥), Redis 只需要 16MB 来存储信息。扩展至 300 万把钥匙,总共不到 5GB —— 其实也很合适 在亚马逊上便宜得多的 m1.large 实例类型中,大约 1/3 否则我们需要的更大实例的成本。最好的 总而言之,在哈希中查找仍然是 O(1),因此非常快。

    如果您有兴趣尝试这些组合,我们的脚本 用于运行这些测试的 Gist 可以在 GitHub 上获得(我们也 将 Memcached 包含在脚本中,以供比较 — 大约需要 52MB 百万键)

    【讨论】:

    • 谢谢,您是否建议我们将 100,00,00 个键值对分解为 1000 个散列键,每个散列键具有 1000 个键值对 HAShKey-0-999 将持有 0 - 999 的键值对 HAShKey- 1000-1999 将持有 1000 - 1999 的键值对
    • 是的。创建 100 万个键值对,创建 1000 个散列,每个散列有 1000 个子键值。您可以使用存储桶大小,即 1000 或 500 或 2500 来达到最佳的整体大小,但我想 1000 就足够了。了解 Redis 的“hash-max-ziplist-entries”配置以进行更多调整也很好。
    • 谢谢,将 hash-max-zipmap-entries 设置为 1000,现在创建 500 个批次,将大小减少了 5 倍。我会继续玩。随时通知您。
    • 很高兴听到这个消息,也分享更多结果!
    • 谢谢,继续测试。确定存储桶大小为 400。这将内存占用从 980MB 减少到 358MB。还是太大了。 400 的桶大小创建了 34300 个不同的哈希键。现在获取所有 1300 万个索引需要 22 秒。在没有桶分区的情况下,我得到了 4-5 秒。看起来我必须在存储或读取方面做出妥协。两者都不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-17
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-04
    • 1970-01-01
    相关资源
    最近更新 更多