redis底层数据结构

发布于:2022-12-11 ⋅ 阅读:(219) ⋅ 点赞:(0)

rehashindex,是否扩容,值为-1为不扩容

根据key的hash值,去取模sizemask,放到数组里面,如果下标一致的情况下,放入链表,采用头插法,头插法比较快,不用遍历,hashmap是尾插法,防止死链,redis由于是单线程的,不存在这个问题 。

redisObject是封装value的

1、什么时候进行扩容:

       1、当没有子进程进行持久化的时候(将数据同步到磁盘的时候),ht[0].used>=ht[0]

        2、有子进程持久化的时候,ht[0].userd>=ht[0].size*5

2、怎么扩容

        1、当触发扩容的时候,如果扩容的大小和ht[0].size一样,本次不扩容

        2、new 一个新的dict ht[1],大小为ht[0].used*2,是2的幂,如果需要查数据的时候,ht[0]和ht[1]都要查询

        3、数据进行渐进式迁移,rehashindex=0,代表数据可以迁移

        4、数据迁移完成的时候ht[0] =ht[1],ht[1]=null,rehashindex=-1

3、扩容后的数据迁移( 实行渐进式迁移)

        1、每次增删改查的时候,如果rehashindex=-1的时候都会迁移

        2、定时任务迁移(时间时间驱动servercorn),部分迁移(100个hash桶),默认100ms执行一次

数据类型

1、String 类型,value的底层是SDS

        缺点:浪费空间

        优点:查询长度速度快

                   减少修改字符长度带来的内存重分配问题(预分配,SDS长度小于1M会分配长度1M,如果大于1M,就加1M)

                如果截取,不马上释放空间,供下次使用

                二进制安全,根据len判断字符串是否结束

2、Hash类型,底层是ziplist(压缩列表),数据到达一定数据量用dictht hash表

        优点:节省空间,但是可能会拖慢性能

        缺点:会引起连锁更新问题,值都是根据偏移量排列好顺序,数据量越大越慢,适合数据量少的场景

3、List类型,底层是quickList

        相比较ziplist,有节省空间的同时一定程度上面解决了连锁更新问题,有分段为一个quicknode里面是一个ziplist,即使发生更新,也只是一个node进行重新排序

4、Set类型,底层是intset,如果不是整形就用dictht hash表,数组加链表,如果元素超过配置的512个,就用hashtable

5、Zset类型,底层是ziplist,元素大于128个,或者任意一个member大于64个字节的时候,使用skiplist跳表,最高32层,每次查找用二分查找法,由链表优化而来

 

        

        

       

        


网站公告

今日签到

点亮在社区的每一天
去签到