为什么我的redis填满这么快?

时间:2015-11-15 05:45:56

标签: node.js heroku redis node-redis nosql

using redis to store bits to track hourly, daily, weekly, and monthly active users。每当我有一个具有唯一userhoureventType的事件时,就会存储一位。

我正在使用的redis命令(节点客户端)是 client.setbit(key, id, 1);

其中key类似login-mobile-2015-11-14-04id是六位整数(指用户)。

在短短几天内,我达到了heroku redis免费计划的25MB限制,但最大实际数据量(基于独特事件和用户的数量每天192000,这是waaay比25MB更少的字节。我怀疑我的密钥有点太长或有什么问题,但我真的不太了解redis,所以我想问一下。

1 个答案:

答案 0 :(得分:2)

答案在Redis字符串内部数据结构中。 Redus使用SDS字符串,有时它真正重要的是解决它的工作原理。最重要的是SDS中的内存分配策略。

实际上,当它小于SDS_MAX_PREALLOC(1MB)时,它只是将原始大小加倍。当内存不足时,这类似于C ++向量分配策略。这就是字符串追加操作不需要每次都分配内存的原因。

为什么这对你来说很重要。 SETBIT只使用字符串作为容器,因此使用六位整数作为userId(在最坏的情况下)999,999 / 8 = 125,000字节+ 8字节开销。但根据分配策略,每个密钥可能会有高达250,000 + 8字节的开销。

所以有些数学:

  • 每小时统计数据为250 kb * 24每天= 6mb
  • 每个,每周和每月每个柜台250kb(总共1mb)

因此,在最坏的情况下,您只需在4天内花费25 MB。但是在最好的情况下,那么125 kb是最大密钥存储器,你在7-8天内花费25 mb。

BITSET既快又好但消耗大量内存。如果您有大量在线用户,则使用BITSET获取每日,每周和每月数据看起来是正确的决定。 Bitset不是解析数据的最佳选择。

分析您的每小时数据 - 可能正在使用SET允许使用更少的内存 - 您的userId是整数(4个字节),因此128kb是每小时~32,000个用户。另外看看 redis memory optimization guide - 你可能会发现很多关于redis中实际内存使用的有趣内容。

关于SET解决方法 - 您的每小时在线时间少于~32,000个用户 - SET是您的选择。

您也可以使用redis命令DEBUG SDSLEN <key name>调试BITSET键 - 它显示为bitset数据下的SDS字符串分配的内存。