4

我想在 Redis 上的 MySQL 中加载 4 列和 80 万行的数据,这样我就可以减少获取延迟。

但是,当我尝试加载所有数据时,它会变大 5 倍。

原始数据为 3gb(导出为 csv 格式时),但当我将它们加载到 Redis 上时,需要 15GB ......这对于我们的系统来说太大了。

我还尝试了不同的数据类型 -

1) 'table_name:row_number:column_name' -> 字符串 2) 'table_name:row_number' -> 哈希

但他们都需要太多。

我错过了什么吗?

添加)

我的数据有 4 列 - (用户 ID(pk)、计数、创建时间和日期)

4

2 回答 2

8

最节省内存的方法是将值存储为 json 数组,并拆分您的密钥,以便您可以使用 ziplist 编码的哈希存储它们。

  1. 使用说 json 数组对数据进行编码,因此您有 key=value 对,例如user:1234567 -> [21,'25-05-2012','14-06-2010'].
  2. 将您的密钥分成两部分,这样第二部分就有大约 100 种可能性。例如,user:1234567
  3. 将此组合键存储在这样的哈希中hset user:12345 67 <json>
  4. 要检索用户 ID 9876523 的用户详细信息,只需执行hget user:98765 23并解析 json 数组
  5. 确保调整设置hash-max-ziplist-entries 和 hash-max-ziplist-value

Instagram 写了一篇很棒的博客文章来解释这项技术,所以我将跳过解释为什么这是内存效率高的原因。

相反,我可以告诉你这种技术的缺点。

  1. 您无法访问或更新用户的单个属性;你必须重写整个记录。
  2. 即使您只关心某些字段,您也必须始终获取整个 json 对象。
  3. 最后,你必须在拆分键上编写这个逻辑,这是添加维护。

与往常一样,这是一种权衡。确定您的访问模式,看看这样的结构是否有意义。如果没有,您将不得不购买更多内存。

于 2012-05-25T02:36:53.817 回答
0

+1 在这种情况下可能会释放一些内存的想法 - 基于 crumbs 字典的密钥压缩和用于存储整数的 base62 编码,

它将 user:12345 60 缩小为 'u:3d7' 'Y',存储密钥所需的内存减少了两倍。

并且通过数据的自定义压缩,不是数组而是一个loooong int(可以将[21,'25-05-2012','14-06-2010']转换为这样的int:212505201214062010,最后两个部分已修复长度然后很明显如何打包/重新打包这样的值)

因此,整个键/值的大小现在减少了 1.75 倍。

如果您的代码库是基于 ruby​​ 的,我可能会建议 me-redis gem,它可以无缝地实现来自 Sripathi 答案 + 给定的所有想法。

于 2018-05-28T09:37:56.393 回答