V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bccber
V2EX  ›  程序员

redis 中有 4 亿条记录会占多少内存?

  •  
  •   bccber · 2017-04-26 19:10:15 +08:00 · 12845 次点击
    这是一个创建于 2775 天前的主题,其中的信息可能已经有所发展或是发生改变。
    key:md5 16 字节
    value: int64 8 字节
    考虑到 redis 内部可能用到链表 多加一个 next 4 字节
    占用内存 400000000 * 28 /1073741824 GB

    实际上,我公司这个 redis 已经占到 40GB 的内存了
    13 条回复    2017-05-02 13:30:41 +08:00
    cheetah
        1
    cheetah  
       2017-04-26 19:17:34 +08:00
    so?
    zts1993
        2
    zts1993  
       2017-04-26 19:40:27 +08:00
    key:md5 16 字节 这个不对。
    value: int64 8 字节 这个也不对
    链表 这个也不对。。

    整个估算都不太对。。。。
    如果有疑问看一下 info 里面的内存碎片率:)
    Ouyangan
        3
    Ouyangan  
       2017-04-26 20:33:27 +08:00
    这是在当数据库在跑啊
    sagaxu
        4
    sagaxu  
       2017-04-26 20:45:40 +08:00
    ### What's the Redis memory footprint?
    To give you a few examples (all obtained using 64-bit instances):
    * An empty instance uses ~ 1MB of memory.
    * 1 Million small Keys -> String Value pairs use ~ 100MB of memory.
    * 1 Million Keys -> Hash value, representing an object with 5 fields, use ~ 200 MB of memory.

    4 亿约等于 0.4G ,按照 100 字节一条, 100*0.4 刚好是 40G ,官方 Faq 还是蛮准的
    bccber
        5
    bccber  
    OP
       2017-04-26 21:05:48 +08:00
    @sagaxu 问题是我的内容没有 100 字节啊
    额外的字节占这么多啊?
    sagaxu
        6
    sagaxu  
       2017-04-26 21:35:03 +08:00
    @bccber
    MD5 是 16 字节,但是你序列化成了 ASCII 字符是 32 个字符,就是 32 字节了,
    Value 不可能只存 Value 本身,至少还要存类型和长度, 64 位机器,指针是 8 字节。
    Redis 还有超时机制需要额外的字节数,分配内存时也往往会对齐到 64 字节或者 128 字节等等。
    数据结构如 hash 本身也有一定的闲置浪费,再算上内存碎片产生的浪费, 100 字节一点儿都不算多。
    v2orz
        7
    v2orz  
       2017-04-26 21:36:14 +08:00
    key value 不是只存你的数据就完了,还有些为了性能上优化而设置的字段
    如果是简单字符串结构,当字符数组存的数据从一个较长的串被修改为较小的串的时候,不是马上就回收空间的
    同样是哈希对象,存的时候看你使用情景,没准还有用 ziplist 实现的,这还省了一部分内存
    xmbaozi
        8
    xmbaozi  
       2017-04-27 00:30:18 +08:00
    xiezefan
        9
    xiezefan  
       2017-04-27 11:09:17 +08:00
    你可以尝试一些 Redis 内存压缩,Google Keyword:Redis 内存压缩 Redis Ziplist

    关于内存预估,你可以本地存 100W 数据,然后横向对比 4Y 数据,就可以估算大概的内存消耗了。
    内存消耗不好直接给出的原因在于,单位数据使用的内存,与你当前 Redis 版本有关(他们使用了不同的内存分配器)。

    一般来讲,用 ZipList,只要方案合理,能节省 70%左右的内存。
    fancy20
        10
    fancy20  
       2017-04-27 13:54:25 +08:00
    我们的 redis 存的 kv 都比较长,几千万的时候占到 20+G 了,于是换成了 ssdb,感觉仅 kv 的话还不错,原先数据全放进去跑只几百兆内存(可以根据情况配置),性能下降的也不是很多
    stackpop
        11
    stackpop  
       2017-04-27 15:59:20 +08:00
    use hash + ziplist to reduce memory cost
    soulmine
        12
    soulmine  
       2017-04-27 17:31:51 +08:00
    1 到 1 亿的 crc32 彩虹表 10 个 G
    luw2007
        13
    luw2007  
       2017-05-02 13:30:41 +08:00
    存储思路:
    使用 hash 存储,将 16 位 md5 分割成 2 部分,一部分做 hash 的 key,一部分总 hash 的 field。
    由此可以节省大量内存

    伪代码:
    keys = [md5(str(i)).digest() for i in range(100000000)]
    for i, key in enumerate(keys):
    r.hset(key[:3], key[3:], i)

    结果:
    hash 存储 1 亿 md5 占用 3.43G,4 亿 预计不到 14G

    127.0.0.1:6379>info
    used_memory:3680560224
    used_memory_human:3.43G
    ...
    db0:keys=16733694,expires=0,avg_ttl=0

    127.0.0.1:6379> hgetall "\xcd\x05b"
    1) "\x0e\x1e\xef\xde\x93\xa7\xbd\x19\x1bd=\xcb\xd8"
    2) "7098931"
    3) "\xd2\xb6B^\xebs\xba\xdcb\x17\xa6\xe0\xec"
    4) "9063155"
    5) "R\xd0\xb1R\xe2\t\x0f}\x8b^\xfb\x82C"
    6) "47193476"
    7) "\xf4\xcb\xd1_/\x89\xb9\xc4\xc2\xe0mF\xf5"
    8) "70502533"
    9) "Wd4\xee\xf0\xbc\xec\xa6\xfb\x01\rD5"
    10) "83701386"

    缺陷:
    hash 做 key 选取的长度一旦固定,无法控制 hash 的 field 个数。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2573 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 04:16 · PVG 12:16 · LAX 20:16 · JFK 23:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.