文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

浅析 Redis 中 String 数据类型及其底层编码

2024-11-30 14:07

关注

我们来看一下这个结构体中的成员变量分别代表什么:

我们注意到,在 Redis 中有 5 中数据结构(用户使用的),但在底层却有 11 种编码方式,Redis 会根据存储的数据类型、存储数据的大小,选择不同的编码方式,以获得最优的性能。一种数据结构会对应多种数据结构,如下表所示。

数据类型

编码方式

OBJ_STRING

int、embstr、raw

OBJ_LIST

LinkedList和ZipList(3.2以前)、QuickList(3.2以后)

OBJ_SET

intset、HT

OBJ_ZSET

ZipList、HT、SkipList

OBJ_HASH

ZipList、HT

下面,我们现在介绍以下 String 数据类型,及其底层的编码方式。

Redis 数据结构 -- String

String 类型的基本介绍和命令

String 类型,也就是字符串类型,是Redis中最简单的存储类型。它可以存储字符串、整数或浮点数。下面是一些 String 类型常用的命令

1.SET key value:设置指定 key 的值为指定的字符串或数字。

2.GET key:获取指定 key 的值。

3.本地虚拟机redis:0>set key01 value01 "OK" 本地虚拟机redis:0>get key01 "value01"

4.INCR key:将指定 key 的值加 1,如果该 key 不存在,则先将其设置为 0,再进行加 1 操作。

5.DECR key:将指定 key 的值减 1,如果该 key 不存在,则先将其设置为 0,再进行减 1 操作。

6.INCRBY key increment:将指定 key 的值增加指定的增量。

7.DECRBY key decrement:将指定 key 的值减少指定的减量。

8.APPEND key value:将指定的值追加到指定 key 的值的末尾。

9.STRLEN key:返回指定 key 的值的长度。

10.GETRANGE key start end:返回指定 key 的值的子字符串,根据起始位置和结束位置指定。

11.SETRANGE key offset value:将指定 key 的值从指定偏移位置开始,替换为指定的字符串。

12.MSET key1 value1 [key2 value2 ...]:同时设置多个 key 的值。(”[ ]” 中括号内表示可选)

13.MGET key1 [key2 ...]:获取多个 key 的值。

这里仅给出 SET、GET 命令,其他的请自行测试。这些命令只是 Redis String 类型命令的一小部分,Redis 还提供了其他更多的命令来处理 String 类型的数据。你可以参考 Redis 官方文档以获取完整的命令列表和详细的命令说明。

String 类型的底层实现

在 Redis 中,String 类型的数据结构并不是采用 C 语言中自带的字符串类型,C 语言中的数据结构存在很多问题,比如:

因此,String 在 Redis 中有其他三种编码方式: int、embstr、raw 。其中, raw 和 embstr 类型,都是基于动态字符串(SDS)实现的,下面我们先来看看动态字符串的结构是怎样的。

动态字符串(SDS)

动态字符串的结构体如下

这里解释一下结构体中各个成员变量的作用:

我们先来聊一下 flags 这个成员变量。在 redis 中其实定义了 5 个 SDS结构体(其中 hisdshdr5 已经弃用)如图所示。他们之间的主要区别在于 len 和 alloc 的长度不同。

在 redis 中,为了尽可能地节省内存空间,当字符串长度在不同的区间时,会选择不同的结构体,例如:

例如,一个包含字符串“name”的 sds 结构如下:

SDS之所以叫做动态字符串,是因为它具备动态扩容的能力,例如一个内容为 “hello” 的 SDS,假如我们要给这个 SDS 追加一段字符串 ”world” ,这里首先会申请新内存空间:

这种机制称为内存预分配。内存预分配可以减少进行内存重新分配的开销,减少内存碎片,使得 redis 的性能得到提高,空间利用率也得到提高。

String 的三种编码方式

RAW

EMBSTR

为什么是 44 字节?Redis 默认的内存分配器 jemalloc 分配内存大小的单位是 $2^n$ ,因此,如果分配的空间大小为 2、4 、8 … 字节等 $2^n$ 字节,就不会产生内存碎片。

而 redisObject 和 hisdshdr8 中 len alloc flags三个成员变量加起来刚刚好是 16 + 4 = 20 字节,如果 char[] (数据大小)的大小为 44 字节时,加起来刚刚好是 64 字节,也即 26 不会产生内存碎片。

INT

写在最后:在使用 string 类型时,尽可能让其长度小于 44 字节,或者使用整数表示,使其使用 EMBSTR 和 INT 编码

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯