Redis被称为key/value应用中的瑞士军刀,除了其丰富的数据结构支持,更重要的是高效的内存使用,分析源码可以发现作者使用每一个byte都精打细算。在hashtable实现中,Redis引入了zipmap数据结构,保证在hashtable刚创建以及元素较少时,用更少的内存来存储,同时对查询的效率也不会受太大的影响。下面就以源码和例子结合的方式来分析一下zipmap的内存布局。
先来看一下zipmap提供的和存储相关的3个API:
zipmapNew:创建一个zipmap字符串。zipmap创建时只有2个字节,后面会随着set和delete操作动态扩展和收缩。
zipmapSet: 加入新的key/value或者修改zipmap中已有key对应的value。
zipmapDel:从zipmap中删除key/value。
下面给出一段伪代码并分析其内存布局的变化,如下图:
zipmapNew(); zipmapSet(key1,value1); zipmapSet(key2,value2); zipmapSet(key1,value3); zipmapDel(key2); zipmapSet(key1,value4); |
1. zipmapNew();
创建一个zipmap结构体,包含两个字节,第一个字节(zmlen)是长度为1个字节的无符号整数,用来保存zipmap当前元素个数(而非字符串长度)。当zipmap的元素个数大于等于254时,zmlen将不再起作用,zipmap需要遍历整个字符串来获取当前元素个数。最后一个字节为255,表示zipmap的结束。
2. zipmapSet(key1, value1)
一个元素(key/value)在zipmap中有5部分组成:
3. zipmapSet(key2, value2)
调用zipmapSet加入新的key/value时,zipmap将根据key2/value2的长度调用zipmapResize扩展空间,并将key2/value2插入到新分配的空间。同时将zipmap元素的个数加1(如果
4. zipmapSet(key1,value3)
调用zipmapSet对已有的key修改其value,且新的value值大于现有value占用的空间时(加free的空间),zipmap将再次调用zipmapResize扩展空间,并调用memmove将key1/vaule1之后的字符串向后顺移。这里只调用一次memmove,不会对性能有太大影响。
5. zipmapDel(key2)
调用zipmapDel删除key2/value2时,zipmap将把key2/value2之后的字符串前移,并调用zipmapResize收缩占用的内存空间。同时将zipmap元素个数减1。
6. zipmapSet(key1, value4)
调用zipmapSet对已有的key1修改其value,且新的value值小于现有value占用的空间时,zipmap不会马上去调用zipmapResize做内存空间收缩,而是将空闲字节数存入free中,用于后面对这个key再次修改value时,避免调用zipmapResize(要根据新value的长度而定)。当然free的空间也不能太多,否则会造出空间的浪费。zipmap在free字节数大于等于ZIPMAP_VALUE_MAX_FREE(代码中定义为4)时,就对free的空间进行收缩。
以上就是zipmap内存布局和扩展收缩的过程,你可能会问zipmapGet岂不是O(n)的吗?没错,但因为key和value都是确定长度的字符串,所以这个n是zipmap中元素的个数,而不是zipmap整个串的长度。只要在使用zipmap时保证元素个数不是很多,就可以在时间复杂度和空间复杂度两方面找到很好的平衡点。redis.conf中默认配置hash-max-zipmap-entries为512。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
OpenWorld18大会:Ellison宣布数据库的搜寻和破坏任务
在旧金山举行的甲骨文OpenWorld 2018大会中,甲骨文首席技术官(CTO)兼创始人Larry Elli […]
-
ObjectRocket着力发展Azure MongoDB服务
MongoDB吸引了微软公司的注意力,微软公司计划针对运行于该公司2017年发布的Azure Cosmos D […]
-
2017年1月数据库流行度排行榜 新年新气象
新年新气象,数据库知识网站DB-engines最近更新了2017年1月份数据库流行度榜单。TechTarget数据库网站将与您分享1月份的榜单排名情况,让我们拭目以待。
-
创建NoSQL数据建模符号 企业架构师亲自上阵
新兴的NoSQL数据风格促使创新的应用程序快速发展,但NoSQL同时也带来了挑战。NoSQL系统能够快速投入生产,有时甚至根本不用创建任何的前期模式。