• 「Redis数据结构」字符串对象String


    Redis数据结构」字符串对象String

    一、概述

    字符串数据类型是Redis里最常用的类型,它的键和值都是字符串,使用起来非常的方便。虽然字符串数据类型的值都统称为字符串了,但是在实际存储时会根据值的不同自动选择合适的编码。字符串对象的编码一共有三种:int、raw、embstr


    二、编码分类

    int

    如果以字符串对象保存的是一个整数值,且这个整数值可以用long类型来表示,那么字符串对象会将整数值保存在ptr属性里面(void* 转为long*),并将字符串对象的编码设置为REDIS_ENCODING_INT

    redis> SET number 10086
    OK
    
    redis> OBJECT ENCODING number
    "int"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image-20221205151558746

    // 只对长度小于或等于 21 字节,并且可以被解释为整数的字符串进行编码
    if (len <= 21 && string2l(s,len,&value)) {
        if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS) {
            decrRefCount(o);
            incrRefCount(shared.integers[value]);
            return shared.integers[value];  // 这里value < REDIS_SHARED_INTEGERS,直接使用共享的字符串对象。
        } else {  
            if (o->encoding == REDIS_ENCODING_RAW) 
                sdsfree(o->ptr);
            o->encoding = REDIS_ENCODING_INT;
            o->ptr = (void*)value;
            return o;
        }
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    embstr

    如果字符串对象保存的是一个字符串值,并且这个字符串值长度小于等于39字节(redis3.2前)。那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为 embstr

    image-20221205151815596

    redis> SET msg "hello"
    OK
    
    redis> OBJECT ENCODING msg
    "embstr"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    embstr 编码专门用于保存短字符串的一种优化编码方式, 这种编码和 raw 编码一样, 都使用 redisObject 结构和 sdshdr 结构来表示字符串对象, 但 raw 编码会调用两次内存分配函数来分别创建 redisObject 结构和 sdshdr 结构, 而 embstr 编码则通过调用一次内存分配函数来分配一块连续的空间, 空间中依次包含 redisObjectsdshdr 两个结构。

    image-20221205202318529

    • embstr 编码将创建字符串对象所需的内存分配次数raw 编码的两次降低为一次
    • 释放 embstr 编码的字符串对象只需要调用一次内存释放函数, 而释放 raw 编码的字符串对象需要调用两次内存释放函数。
    • 因为 embstr 编码的字符串对象的所有数据都保存在一块连续的内存里面, 所以这种编码的字符串对象比起 raw 编码的字符串对象能够更好地利用缓存带来的优势。

    row

    如果字符串对象保存的是一个字符串值,并且这个字符串值长度大于39(redis3.2前)字节。那么字符串对象将使用一个简单动态字符串(SDS)来保存这个字符串值, 并将对象的编码设置为 raw

    redis> SET story "Long, long, long ago there lived a king ..."
    OK
    
    redis> STRLEN story
    (integer) 43
    
    redis> OBJECT ENCODING story
    "raw"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20221205152102178

    三、小结

    image-20221205152705074

    • embstr与raw都使用redisObject和sds保存数据
    • embstr只分配一次内存空间,因此redisObject和sds是连续的
    • raw需要分配两次内存空间,分别为redisObject和sds分配空间,不连续。
    • embstr好处:创建/删除时少分配/释放一次空间,对象的所有数据连续,查找方便
    • embstr坏处:当需要重新分配内存时,整个redisObject和sds都要重新分配空间,因此redis中的embstr实现为只读。

    四、参考

    Redis 字符串对象

    《Redis 设计与实现》

  • 相关阅读:
    Qt(day3)
    【Python零基础入门篇 · 38】:正则的高级用法
    vue中引入jquery解决跨域问题
    JavaScript的事件监听
    2.通信机制-话题通讯 一直发,一直接收(电台-收音机)
    基于SSM+SpringBoot+MySQL+Vue前后端分离的高校考试管理系统
    如何通过内网穿透+AnyTXT Searcher实现便捷在线办公搜索?
    2022蓝帽杯初赛wp
    设计模式-策略模式
    JAVA:实现Kruskal克鲁斯卡尔求连通网的最小生成树算法(附完整源码)
  • 原文地址:https://blog.csdn.net/u014571143/article/details/128196311