美文网首页
redis-内存模型

redis-内存模型

作者: 水流不流 | 来源:发表于2019-04-22 15:27 被阅读0次

    简单描述

    c语言编写,K-V形式存储,K是String类型的,V支持5种不同的数据类型,分别是:string,list,hash,set,sorted set; 底层数据结构有:简单动态字符串(SDS),链表,字典,跳跃表,整数集合,压缩列表,对象。

    内存模型

    虽然有那么多种类型,但总的来说是K-V结构,所以所有的数据都是在一个hashtable中,详细的存储如下图

    来自https://www.cnblogs.com/kismetv/p/8654978.html


    执行set hello world时,所涉及到的数据模型,图片来源:https://searchdatabase.techtarget.com.cn/7-20218/

    这里之所以要2个dictht有一个很重要的原因就是为了rehash,bucket是一个数组,存放指向dictEntry结构的指针。
    value是redisObject类型:

    type :具体的类型
    encoding :对象的内部编码,redis支持的每种类型,都有至少两种内部编码
    lru:对象最后一次被命令程序访问的时间
    refcount:该对象被引用的次数,这里有个共享对象的概念。默认0-9999
    ptr:指向具体的数据的指针

    字符串—SDS结构(三个参数)
    buf :字节数组,用来存储字符串
    len :buf已使用的长度
    free:buf未使用的长度

    列表
    压缩列表(ziplist):列表中元素数量小于512个;列表中所有字符串对象都不足64字节。
    双端链表(linkedlist):不满足压缩列表时。

    哈希
    压缩列表(ziplist):哈希中元素数量小于512个;哈希中所有键值对的键和值字符串长度都小于64字节
    哈希表(hashtable):不满足压缩列表时。另外redis的最外层K-V哈希,只有这种结构。

    集合
    整数集合(intset):集合中元素数量小于512个;集合中所有元素都是整数值。
    哈希表(hashtable):不满足整数集合时。

    有序集合
    压缩列表(ziplist):有序集合中元素数量小于128个;有序集合中所有成员长度都不足64字节。
    跳跃表(skiplist):不满足压缩列表时。

    观察redis内存状态是否健康的几个参数

    输入info memory:
    used_memory :redis分配器分配的内存总量
    used_memory_rss :redis进程占据操作系统的内存
    mem_fragmentation_ratio:内存碎片比率,该值是used_memory_rss / used_memory的比值
    mem_allocator:Redis使用的内存分配器,在编译时指定,默认是jemalloc。

    内存碎片比率这个值一般大于1,且值越大表示内存碎片越多,redis还没怎么存入数据时例外,因为redis进程本身占用的内存不在used_memory里。如果该值比率小于1,表示redis使用了虚拟内存,这个时候内存已经不够用了。

    如何减少内存碎片?

    1.使用合理的内存分配器
    2.如果内存碎片已经很大,可以考虑安全重启的方式,因为重启之后,redis会重新从备份文件读取数据,在内存中重排。

    redis内存使用量评估

    不应该只考虑key,value的大小,其实分配的内存远远不止,参考redis内存结构,除了key,value占用的空间外,dictEntry,redisObject,SDS的非buf参数占用部分,bucket都会占用,而且还有一点得注意,sds由jemalloc分配的空间应该是2的部分倍数,比如key是7字节的时候,sds占用16个字节(其他参数共9字节),但key是8字节时,sds占用17个字节,这个时候jemalloc会分配32。同理bucket列表的长度是2的指数倍。

    所以基于上述,该如何优化呢?

    1.利用jemalloc特性进行优化。比如key 8个字节变 key 7个字节。
    2.尽量使用长整型/整型。
    3.利用共享对象,可根据需求调整REDIS_SHARED_INTEGERS参数提高共享对象的个数。
    4.关注内存碎片率。

    rehash

    跟hashmap rehash有什么不同?
    redis是渐进式迁移,按entry为单位顺序迁移,有字段记录了迁移进度。
    内部也是两个两张hash表,一张旧表,一张新表,迁移的时候旧表往新表迁移数据,当迁移完后,当前的新表又变成了旧表。

    与Memcached比较

    1. redis支持持久化,memecache 把数据全部存在内存之中,
    2. redis支持更多类型

    参考链接
    深入学习Redis(1):Redis内存模型

    相关文章

      网友评论

          本文标题:redis-内存模型

          本文链接:https://www.haomeiwen.com/subject/tocriqtx.html