美文网首页
(三分钟系列)详解Redis字符串内部结构

(三分钟系列)详解Redis字符串内部结构

作者: spacedong | 来源:发表于2018-09-10 11:24 被阅读65次

可以关注我的个人博客和公众号,第一时间发布最新的干货文章

个人博客网站:www.spacedong.top
微信公众号:spacedong

前言

Redis 中有五种数据类型,分别是 Str (字符串)、 Hash (哈希)、 List (列表)、 Set (集合)、 Zset (有序集合)。
这五种数据类型的实际运用与底层实现和其他语言中的数据结构的实现有所不同,底层实现是由Redis基于C语言的基础上来完成的。接下来我们会结合源码来讨论 Redis
字符串中的实际运用与底层原理。

运用范例

redis 127.0.0.1:6379> SET name "spacedong"
OK
redis 127.0.0.1:6379> GET name
"spacedong"
  • 一个String键能够存储512M的数据。
  • String类型是二进制安全的,可以存储的数据是任何形式的,比如序列化的对象,图片等。
  • 范例中的键值对中的 name 这个键是一个 SDS 字符串,"spacedong"也是一个 SDS 字符串。

特性详解

  • <font size=4 >String 的字符串底层是由动态字符串(simple dynamic string ,SDS)来实现的。</font>
struct sdshdr {

    // 记录 buf 数组中已使用字节的数量
    // 等于 SDS 所保存字符串的长度
    int len;

    // 记录 buf 数组中未使用字节的数量
    int free;

    // 字节数组,用于保存字符串
    char buf[];

};
  • SDS 字符串中的结构

[图片上传失败...(image-bf986-1536549852592)]

  • free 是指在 SDS 中未使用的空闲字符空间,如图为 5
  • len 是在 SDS 中实际使用的长度,如图为 5
  • 在 SDS 中是会额外申请一个空字符来保存结尾的字符,这个和C语言中的字符串是一样。
  • 获取 SDS 的字符串长度

在 SDS 中获取实际保存字符串的长度方法(源码如下)

/*
 * 
 * 返回 sds 实际保存的字符串的长度
 *
 * T = O(1)
 */
static inline size_t sdslen(const sds s) {
    struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
    return sh->len;
}

** 在 SDS 中获取未使用空间的方法源码如下**)

/*
 * 返回 sds 可用空间的长度
 *
 * T = O(1)
 */
static inline size_t sdsavail(const sds s) {
    struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
    return sh->free;
}
  • SDS 中防止缓冲区溢出的策略

C语言中的字符串在扩容的时候,已经假设为该字符串分配了足够的内存空间了。如果没有分配的话,当有需要扩容的字符串时会产生缓冲区溢出,则是在每次扩容的时候先进行判断,是否有足够的空间来存储传进来的字符串,如果没有,则是扩容到相对应的长度,同时对 free 属性分配相对应的长度。

例如一开始的使用长度为 5 ,需要扩容的长度为 5 ,那么free分配的长度就为10。这个是与 SDS 的空间分配策略有关。

- SDS 修改字符串时策略及好处

在字符串进行修改的时候,会涉及到内存的重分配,这是一个复杂的操作,有可能涉及到系统的调用,SDS 在修改字符串的时候的策略可以为减少内存重分配的次数。

1. 空间预分配策略

具体的策略是在字符串扩容时,会在扩容后为 free 属性分配一个合适的长度,这样的目的是为下次的字符串扩容的时候提前分配好了一定的内存。

这里的合适长度是指:如果 SDS 字符串的长度为小于1M,那么分配和实际使用长度相同的内存,如修改后的字符串长度为13个字符,那么为 free 分配 13 个字符的内存,如果修改后的 SDS 长度大于 30M,那么为 free 分配的长度为 1M 的内存。

2. 惰性空间策略

如果 SDS 字符串的长度在修改后变短的话,那么空余出来的长度分配给 free ,为的是下次的字符串的使用。

3. 好处

可以让内存分配的次数从一定为 N 次变为最多是 N 次。同时也可以满足 redis 中的对数据频繁修改的要求。

- 二进制的安全数据

在 SDS 中存的是二进制的数据格式,这种格式的数据存进来是什么样的,取出来的时候也是怎么样的,同时也是满足存储多种数据格式的数据的要求,如存储图片,文本数据等。

想要获得更多的优质技术文章,可以关注下方的微信公众号 spacedong

为优质的文章而赞赏,这是为作者能持续输出的最大肯定!


相关文章

  • redis数据结构总结

    string redis的字符串是动态字符串,内部结构实现类似于java的arraylist 其次,redis采用...

  • (三分钟系列)详解Redis字符串内部结构

    可以关注我的个人博客和公众号,第一时间发布最新的干货文章 个人博客网站:www.spacedong.top 微信公...

  • redis 基础数据类型

    redis 基础数据类型 Sting类型 : Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上...

  • Redis-数据结构

    Redis有5种基本数据类型 string(字符串) 键值对 计数 扩容: 【字符串】内部结构 list(列表) ...

  • 彻底了解Redis基础数据结构

    String 字符串 Redis字符串是简单动态的字符串,是可以修改的字符串,内部结构上实现了类似于Java的Ar...

  • Redis数据结构(非常全面详细)

    redis常用数据结构 redis字符串详解[https://www.jianshu.com/p/b269b22f...

  • redis

    String 在Redis中String是可以修改的,称为动态字符串。说是字符串但它的内部结构更像是一个 Arra...

  • Redis详解1.安装及使用

    章节目录Redis详解1.安装及使用Redis详解2.数据结构Redis详解3.发布订阅Redis详解4.事务Re...

  • Redis详解5.数据持久化

    章节目录Redis详解1.安装及使用Redis详解2.数据结构Redis详解3.发布订阅Redis详解4.事务Re...

  • Redis详解4.事务

    章节目录Redis详解1.安装及使用Redis详解2.数据结构Redis详解3.发布订阅Redis详解4.事务Re...

网友评论

      本文标题:(三分钟系列)详解Redis字符串内部结构

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