redis内存碎片

内存碎片的产生与对数据进行的操作,数据的特点等有关,与使用的内存分配器也有关 。如果redis服务器的内存碎片很大,可以通过安全重启的方式减少内存碎片,重启后,redis重新从备份文件中读取数据,在内存中进行重排,为每个数据重新选择合适的内存单元,减少内存碎片
linux采用著名的伙伴系统buddy system算法来解决外碎片问题 。把所有的空闲页框分组为11个块链表,每个链表分别包含大小为1,2,4,8,16,32,64,128,256,512,1024连续的页框,对1024页框的最大请求对应着4MB大小的连续RAM(每页大小为4KB),每个块的第一个页框的物理地址是该块大小的整数倍,例如,大小为16个页框的块,其起始地址是16*2^12的倍数 。
我们通过一个例子来说明伙伴算法的工作原理,假设现在要请求一个256个页框的块(1MB),算法步骤如下:

  • 在256页框的链表中检查是否有一个空闲块,如果没有,查找下一个更大的块,如果有,请求满足 。
  • 在512页框的链表中检查是否有一个空闲块,如果有,把512个页框的空闲块分为两份,第一份用于满足请求,第二份链接到256个页框的链表中 。如果没有空闲块,继续寻找下一个更大的块 。
下图比较形象地描述了该过程 。
redis内存碎片

文章插图
 
以上过程的逆过程,就是页框块的释放过程,也是该算法名字的由来,内核试图把大小为B的一对空闲伙伴块合并为一个2B的单独块,满足以下条件的两个块称之为伙伴:
  • 两个块具有相同的大小
  • 他们的物理地址是连续的
  • 第一块的第一个页框的物理地址是2 * B * 2^12
【redis内存碎片】该算法是递归的,如果它成功合并了B,就会试图去合并2B,以再次试图形成更大的块 。




    推荐阅读