专栏首页Java患者Redis中String数据类型原理实现

Redis中String数据类型原理实现

微信公众号:Java患者 专注Java领域技术分享

String 数据模型

首先Redis是KV数据结构,跟JDK中的Map是一样的,Redis是通过hashtable实现的,我们把这个叫做外层的哈希,那么每一个KY就是一个entry,在Redis的源码中,是定义为一个dictEntry。

typedef struct dictEntry {
    void *key;
    union {
        void *val;
        uint64_t u64;
        int64_t s64;
        double d;
    } v;
    struct dictEntry *next;
} dictEntry;

通过源码 定义了dictEntry对象,对象中存储了一个key,跟一个value,并且还有一个指向了下一个键值对节点的对象。

接着了解key-value的原理,key是一个字符串,在C语言中(Redis是用C语言开发的),是没有字符串这个数据类型的,只有字符类型,而key并没有直接使用了C语言中的字符数组char[]来实现,而是存储在了一个自定义的数据类型-SDS。

value并没有存在SDS中,也不是作为字符串存储,而是存储中一个redisObject中,事实上,redis的五大数据类型的value都是存储在redisObject中。、

SDS

什么是SDS?Redis中字符串的实现,SDS有多种结构:sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64,用于存储不同长度的字符串,分别代表的是2^5byte、2^8byte、2^16byte、2^32byte、2^64byte。

typedef char *sds;
......
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len;  /* 当前字符数据的长度 */
    uint8_t alloc; /* 当前字符数组总共配的内存大小 */
    unsigned char flags; /* 当前字符数据的属性 (sdshdr5、sdshdr8、sdshdr16、......) */
    char buf[]; /* 字符串真正的值 */
};
......

为什么要使用SDS来实现字符串呢?

  • 首先C语言中并没有字符串类型,要实现的话只能使用char[]来实现,但是使用字符数组必须先给变量分配足够的空间,否则会溢出,分配多了又可能造成浪费
  • 如果要获取字符串的长度,就需要遍历字符数组,时间复杂度高O(n)
  • 字符串的长度更改会对字符数组的内存进行重新分配
  • C语言的 \0 是字符串的标志结束位,如果存储图片音频等多媒体文件的时候,存在二进制安全问题

SDS的特点

  • 无需担心内存溢出的问题,如果需要就对SDS进行扩容
  • 定义了len属性,获取字符串长度时间复杂度O(1)
  • 通过“空间预分配” 和“惰性空间释放”,防止多次重分配内存
  • 判断字符串是否结束是len属性

redisObject

typedef struct redisObject {
    unsigned type:4; /* 对象的数据类型 (OBJ_STRING、OBJ_LIST、OBJ_HASH、OBJ_SET、OBJ_ZSET)*/
    unsigned encoding:4; /* 具体的数据结构 */
    unsigned lru:LRU_BITS; /* 对象最后一次被命令访问的时间 与内存回收有关 */
    int refcount;  /* 引用计数 当该变量值为0时,表示该对象不被任何其他对象引用,可以进行垃圾回收了 */
    void *ptr; /* 指针指向对象实际的数据结构 */
} robj;

数据模型图

本文分享自微信公众号 - Java患者(gh_3a16ffdedb6a),作者:Zero

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-10-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Redis数据类型之String类型

    Redis数据类型之String类型

    人生不设限为梦想时刻准备着
  • Redis详解(五)------ redis的五大数据类型实现原理

      前面两篇博客,第一篇介绍了五大数据类型的基本用法,第二篇介绍了Redis底层的六种数据结构。在Redis中,并没有直接使用这些数据结构来实现键值对数据库,而...

    IT可乐
  • 【数据存储】【Redis】第三章: Redis五大数据类型实现原理

    学完本章中,读者需要回答: 1.Redis底层数据结构如何实现? 2.Redis是如何回收内存? Redis的一个键值对,有两个对象,一个是键对象,一个是...

    java_wxid
  • 【Redis数据结构 String类型】String类型生产中的应用 缓存、计数器、限速器的实现

    本文依旧会对学习内容进行拆分,建议阅读时间基本保持10分钟内,想学习之前章节内容点击《你不了解的Redis》阅读所有章节内容。

    不太灵光的程序员
  • Redis数据类型之String字符串类型

    二进制安全是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改、破译等,如果被攻击,能够及时检测出来

    兮动人
  • Redis底层原理--03. Redis 数据类型

    由于 redis 需要对每一个 key 产生不同的操作,所以Redis 必须让每个键都带有类型信息,使得程序可以检查键的类型,并为它选择合适的处理方式

    付威
  • Redis 数据结构之String数据类型

    字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息...

    Devops海洋的渔夫
  • Redis基础数据类型(string、hash、list)

    为了解决高并发、高可用、高可扩展,大数据存储等一系列问题而产生的数据库解决方案,就是NoSql。 NoSql,叫非关系型数据库,它的全名Not only sql...

    陌无崖
  • Redis中string、list的底层数据结构原理

    Redis 有一个比较突出的特点就是数据结构更丰富, 「string、hash、list、set、zset、Redis5.0 新数据结构-stream」

    用户2781897
  • Redis的各种数据类型实践--String字符串

    Redis作为一款NoSQL内存数据库,其丰富的数据类型、简单易用的命令、单机可达10万的高并发(官方数据),从面世以来就深受广大用户的喜爱。Redis的五种数...

    用户4464623
  • 《闲扯Redis一》五种数据类型之String型

    String是Redis的最基本的数据类型,可以理解为与 Memcached 一模一样的类型,即Key-Value型的数据,String类型是二进制安全的,另...

    大道七哥
  • 《闲扯Redis一》五种数据类型之String型

    String是Redis的最基本的数据类型,可以理解为与 Memcached 一模一样的类型,即Key-Value型的数据,String类型是二进制安全的,另...

    大道七哥
  • Redis学习笔记(三)Redis数据存储类型之String

    ​ (1)存入多个值mset key1 value1 key2 value2 …

    萌萌哒的瓤瓤
  • .NET中可空值类型实现原理

    为了让.Net中的值类型可以赋值为null,微软特地添加了Nullable<T>类型,也可简写为T?。但是Nullable<T>自身是结构体,也是值类型,那么它...

    雪飞鸿
  • 《闲扯Redis二》String数据类型之底层解析

    疑问:embstr 是什么意思,动态字符串又是什么意思?字符串对象到底什么结构?三种实现方式有什么区别呢?

    大道七哥
  • Redis Sentinel原理与实现 (中)

    在启动Redis时可以传入“--sentinel”参数来启动Sentinel,在main()函数中可以看到处理Sentinel的逻辑,如下:

    用户7686797
  • Redis 设计与实现: redisObject 数据结构,以及 Redis 的数据类型

    redisObject 是 Redis 类型系统的核心, 数据库中的每个键、值,以及 Redis 本身处理的参数, 都表示为这种数据类型。

    一个会写诗的程序员
  • Redis 实战篇:巧用数据类型实现亿级数据统计

    在移动应用的业务场景中,我们需要保存这样的信息:一个 key 关联了一个数据集合,同时还要对集合中的数据进行统计排序。

    码哥字节
  • python 基本数据类型及底层实现原理 略知

    底层由线性表实现,列表中元素 保存的不是具体的数据的内存地址,而是 指针(就是指向元素的内存地址的指针)

    不学就是不会

扫码关注云+社区

领取腾讯云代金券