redis怎么修改数据_Redis的数据结构(内存具体怎么优化的)

 上一篇我们讲解了Redis中SDS的组成以及优势,这一篇我们讨论下Redis中的Hash数据类型是怎么构成的呢?

   Java中存在HashMap和HashTable的数据类型。而Hash的数据结构可以近似于HashTable,依据数组+链表的形式构成。

    在Redis中,Hash在元素对象个数较少的时候采用的是压缩链表的形式

(ziplist),压缩链表是一块连续的内存空间,元素之间紧紧的挨着,不存在任何的冗余空间。

压缩链表的内部结构图:

struct ziplist{    int32 zlbytes;  //压缩列表占用的字节数    int32 zltail_offset; //压缩列表最后一个元素到起始位置的偏移量    int16 zllength;  //元素的个数    T[] entries;   //元素列表    int8 zlend;   //压缩列表的末尾   常设置为0xFF} ;

  dbcb2f3c2f4245fc9718fc5a8fb80c96.png

然后让我们看一下entry的内部结构:

struct entry{   int<var> prevlen; //前一个entry字节长度   int<var> encoding;  //元素编码类型   optional byte[] content;   //元素内容}

  prelen存放的是上一个entry的字节长度,压缩列表倒着遍历的时候,需要这个字段快速的定位下一个元素的位置。其是一个变长的整数,小于254的时候用一个字节存放,大于254的时候用的是5个字节存放。

  encoding 代表的是压缩表的编码类型,其是根据encoding的前缀位进行区分的。(有兴趣的同事可以看一下redis的深度历险)

   当插入元素的时候,ziplist每次都需要进行内存的重新分配,所以不适合存储大元素或者过多的元素。

   于是存储过多的元素或者大元素的时候,hash也就自动转化为字典的方式进行存储。字典的方式可以根据hashtable的结构进行理解,数组+链表。数组存放的是链表的第一个元素的指针。

  提到hash,就不得不提渐进式rehash。

  当hashtable需要扩容的时候怎么办呢?Redis维护了两个Hashtable。需要扩容的时候就会将旧的字典所有的链表元素挂到新的链表下面。但是不是一次性立马转移完成,毕竟redis是单线程的,需要保证性能。

  渐进式 rehash式一个数组内容一个数组内容进行元素的转移。当查询触及到当前链表的时候,查询完成后会将链表的元素转移到新的字典链表下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值