常见Key-Value存储系统的内存管理策略解析

本文探讨了常见Key-Value存储系统如redis和memcached的内存管理策略。内容涉及Chunk块的设计,其对性能和内存利用率的影响,以及简单实现与复杂实现的权衡。简单的内存管理策略虽然易于实现,但可能导致内存碎片,增加系统调用开销。而复杂策略可能带来更高的内存利用率,但代码健壮性和Shm块链的管理成为挑战。
摘要由CSDN通过智能技术生成
        Key-Value存储作为NoSQL存储的一种常见方式,提供了比SQL数据库更好的可扩展性和 读写性能 。比如当前开源最热门的Memcached和Redis;淘宝的Tair、腾讯的Cmem、 Amazon的Dynamo等等,无论是做缓存还是持久存储,均使用内存作为主要存储介质,故内存管理策略就显得尤为重要了,是影响性能的重要因素。
        这里从源代码层面对Memcached、Redis和UDC(腾讯以前用的一套KV持久化存储系统)的内存管理策略进行分析,3者的内存管理策略各不相同,其他KV系统也和这3种方法大同小异了。最后对这3种策略进行了实际的性能测试分析,有出入的请使劲拍砖!

--------------------------------------------------------------------------

1 MemCached:Slab Allocation机制

3个 主要的 概念:
1 Chunk块:固定大小的数据块,数据存储的基本单位,1个Chunk 存1个数据,剩余空间不做其他用途
2 Slab页:固定大小的内存块(页),申请内存的基本单位,默认为1MB,每个SlabClass会把申请的Slab切分成相同大小Chunk来存数据
3 SlabClass:由Chunk的大小确定,是大小相同的所有Chunk块集合

如上图所示,Memcahed启动时, 会根据传入的-n(最小数据尺寸,默认48B),-f(增长因子,默认为1.25)启动选项初始化SlabClass。默认情况下,首个SlabClass的Chunk大小为80B(32B元数据头+48B最小数据尺寸),然后以1.25为比值生成等比数列,直到1MB(1个Slab页大小)为止。生成的SlabClass如下所示(perslab值为每个Slab页能分割出的Chunk个数):
$ memcached -vv
slab class 1: chunk size 80 perslab 13107
slab class 2: chunk size 104 perslab 10082
slab class 3: chunk size 136 perslab 7710
.....
slab class 41: chunk size 717184 perslab 1
slab class 42: chunk size 1048576 perslab 1

当用户发来请求时,Memcahed 会根 key+value 的值(能存放在1个Chunk内)来判断属于哪个SlabClass 。确定这个SlabClass 有无空闲的Chunk块,没有的话则先给这个SlabClass 申请一个Slab 页, 将该Slab页按 SlabClass Chunk 块大小进行切割,然后分配1个来存放用户数据。(这里还有LRU算法淘汰旧数据的逻辑,就不放在这里分析)。

这种策略的特点:
  • 实现较复杂
  • 参数的选择(最小数据尺寸,增长因子)直接影响性能及内存利用率
  • 每个数据存放于1个Chunk块,读写简单
相关源代码:主要由slab.h/c(SlabClass Slab 相关)、item.h/ c(Chunk块相关)这几个文件实现

SlabClass数据结构:



* 初始化 SlabClass(通过增长因子计算各个SlabClass的Chunk块大小等)



* 为SlabClass[i]申请一块新Slab内存页
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值