我们在系统设计面试或者在实际工作中,免不了要进行一些估算。之前的文章里讲过一些技巧,今天来个实战。

这是我最近在做的一个工作,将内存中的一个超大的 map[int64]int64 写入到 redis,map 里的元素个数是千万级的。设计方案的时候,需要对 redis 的容量做一个估算。

如果不了解 redis 的话,可能你的答案是用元素个数直接乘以 16B(key 和 value 各占 8B)。我们假设元素个数是 5kw,那估算结果就是:5kw * 16B=50kk * 16B = 800MB。

答案是错的。

为了解决这个问题,需要深入地研究一下 redis 的数据结构。

整个 redis 数据库就是一个大的 map,它容纳了所有的 key,我们都知道 key 都是 string 类型,而 value 则有 string, list, set, hashmap, zset……等类型。

Redis 中的一个 k-v 对用一个 entry 项表示,其中每个 entry 包含 key、value、next 三个指针,共 24 字节。由于 redis 使用 jemalloc 分配内存,因此一个 entry 需要申请 32 字节的内存。这里的 key, value 指针分别指向一个 RedisObject:

redis entry
typedef struct redisObject {unsigned type:4;unsigned encoding:4;unsigned lru:LRU_BITS; int refcount;void *ptr;
} robj;

RedisObject 对应前面提到的各种数据类型,其中最简单的就是 redis 内部的字符串了。它有如下几种编码格式:

SDS 编码(图片来自极客时间-redis 专栏)

图中的元数据包括 type,encoding,lru, refcount,分别表示数据类型,编码类型,最近一次访问的时间戳,引用次数。

当字符串是一个整型时,直接放在 ptr 位置,不用再分配新的内存了,非常高效。

解析一下 44 字节的原因:元数据和 ptr 共占 16 字节,加上 44 字节,再加上字符串末尾的 '\0',共61 字节。因为字符串的长度只有 44,因此 len 和 alloc 各用 1 个字节就够了。再加上 1 个字节的 flags,刚好是 64 字节。超过了这个值,SDS 就需要单独再申请一块内存,导致访问的时候就多了一跳指针。

多提一句,redis 最大支持 512MB 大小的字符串。

回答本文的问题,恰好我们要写入 redis 的 map 中的 key 和 value 都是整数,因此直接将值写入 ptr 处即可。

于是 map 的一个 key 占用的内存大小为:32(entry)+16(key)+16(value)=64B。于是,5kw 个 key 占用的内存大小是 5kw*64B = 50 kk * 64B = 3200MB ≈ 3G

假如我们在 key 前面加上了前缀,那就会生成 SDS,占用的内存会变大,访问效率也会变差。

总之,我们根据要写入 redis 中的字符串的长度可以很方便地估算占用内存的总大小。如果 key 和 value 恰好都是 int64 类型的,那么尽量不要在 key 前加前缀,这样可以直接使用 key 的个数乘以 64B 就能算出占用内存的大小。

本文内容转载自公众号「码农桃花源」,号主会经常分享一些令人醍醐灌顶的设计思路和看问题的视角。

- END -

扫码关注公众号「网管叨bi叨」

给网管个星标,第一时间吸我的知识 

面试被问 Go 的map[int64]int64 在 redis 会占多少空间...相关推荐

  1. Redis面试常问3 如何实现分布式锁 记住Redis的原子性

    Redis面试常问3 如何实现分布式锁 上面的伪代码有问题 从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改: http://redisdoc.com/string ...

  2. 拿下阿里三面是后,面试官问我:你是怎么学习Redis的?

    你是怎么学Redis的? 随着面试官的这一句话,我的思绪回到了刚毕业的时候,面试官也是这么问的我; 记得刚毕业时,我是在B站看视频入门的,入个门应付平时的CRUD完全没问题,但当工作中碰到问题的时候, ...

  3. linux驱动工程面试必问知识点

    linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...

  4. Go map[int64]int64 写入 redis 占用多少内存

    我们在系统设计面试或者在实际工作中,免不了要进行一些估算.之前的文章里讲过一些技巧,今天来个实战. 这是我最近在做的一个工作,将内存中的一个超大的 map[int64]int64 写入到 redis, ...

  5. 线程安全的map_面试必问-几种线程安全的Map解析

    HashMap线程安全的吗? Java中平时用的最多的Map集合就是HashMap了,它是线程不安全的. 推荐阅读:我凭借这份pdf拿下了蚂蚁金服.字节跳动.小米等大厂的offer 看下面两个场景: ...

  6. 【020期】面试官问:Java 遍历 Map 集合有几种方式?效率如何?

    >>号外:关注"Java精选"公众号,回复"2021面试题",领取免费资料!"Java精选面试题"小程序,3000+ 道面试题在 ...

  7. 面试被问烂的 Spring IOC(求求你别再问了)

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! 作者:莫那·鲁道 链接:http://thinkinjava.cn 广义的 IOC IoC(Inv ...

  8. 后处理程序文件大小的变量_【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?...

    关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 2020,实「鼠」不易 2021,「牛」转乾坤 风劲潮涌当扬帆,任重道远须奋蹄! 一.前言 2020.12.23 立 ...

  9. 阿里面试这样问:Nacos配置中心交互模型是 push 还是 pull ?(原理+源码分析)...

    本文来源:公众号「 程序员内点事」 对于Nacos大家应该都不太陌生,出身阿里名声在外,能做动态服务发现.配置管理,非常好用的一个工具.然而这样的技术用的人越多面试被问的概率也就越大,如果只停留在使用 ...

最新文章

  1. ctypealpha php_php ctype函数中文翻译和示例
  2. 比较常用的几个正则表达式
  3. 孝敬父母 天经地义 |有人这么疑问?
  4. Mask RCNN笔记
  5. stl标准模板库_C ++标准模板库(STL)中的数组及其常用功能
  6. Job for slapd.service failed because the control process exited with error code. See systemctl stat
  7. 炸裂!微信支付的架构太牛了!(微信跨平台开发框架)
  8. html5 移动端 Android和iOS手机 video自动播放
  9. 人之间的尊重是相互的_人与人之间要学会相互尊重
  10. S32K144 S32K148 UDS诊断 BOOTLOADER开发 ISO14229 15765 软件定 基于UDS协议的CAN总线Bootloader设计 具体价格以咨询为主 UDS 诊断
  11. 由jar文件生成jad文件
  12. Ubuntu Qt 无法覆盖文件 错误解决方法
  13. Java中对象方法的调用过程动态绑定(Dynamic Binding)
  14. 生存分析-Cox回归模型
  15. openCV生成一张纯白图片
  16. Robust regression(稳健回归)
  17. spring-cloud-oauth2
  18. 企业邮箱申请流程有哪些?公司邮箱的优势有哪些?
  19. vue如何设置 网页标题 关键字 描述
  20. 本人亲自整理的极客时间设计模式之美的硬核笔记

热门文章

  1. 六大举措深耕光通信市场
  2. firfox 和 chrome 移动端Web开发页面调试
  3. 使用Bootstrap后,关于IE与Chrome显示字体的问题
  4. android视频录制(调用系统视频录制),生成缩略图
  5. XP SP3远程桌面无法连接Windows Server 2008/Vista
  6. Linux游戏开发包 ClanLib 2.1.0 发布
  7. 发送当前IP到我的手机
  8. Struts tiles入门(最最简单的例子)
  9. Facebook已经过时,蜂巢新网络崛起
  10. InfoQ观点:Java EE的未来