服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Redis - Redis字符串原理的深入理解

Redis字符串原理的深入理解

2019-11-24 18:58YangSir Redis

这篇文章主要给大家介绍了关于Redis字符串原理的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

来掘进都有两年多了一直当个小透明,今天终于发一次文章了.

最近在看 Redis,感觉收获很多,写篇博客记录一下.

Redis 有五种基础数据结构:string,list,set,zset,hash.其中 string是最最最简单的也是最常用的.这个数据类型虽然简单但是内部的结构设计却很是精致.

基本介绍

相比于 Java,在 Redis 中 string 是可以修改的,是动态字符串(Simple Dynamic String 简称 SDS)他的内部结构更像是一个 ArrayList,维护一个字节数组并预分配冗余空间以减少内存的频繁分配.当字符串的长度小于 1MB时,每次扩容都是加倍现有的空间,如果字符串长度超过 1MB 时,每次扩容时只会扩展 1MB 的空间.

ps:字符串长度为最大长度 512MB.

?
1
2
3
4
5
6
7
8
9
10
11
> set name test
OK
> get name
"test"
> mset name1 test1 name2 test2
OK
> mget name1 name2
1) "test1"
2) "test2"
> del name
(integer) 1

上面是字符串的基本操作 命令mset 和 mget 可以对多个字符串读写 节省网络开销

不仅如此redis 的字符串还可以用来储存整数(更不像Java 的字符串了),并且可以自增操作.字符串保存整数类型的的范围在 至
如果保存的数大于这个取值范围就会变成普通字符类型 无法自增操作.这将由字符串编码格式决定.

字符串由多个字节组成,每个字节有 8bit.这样的数据结构还可以当做 bitmap 去使用.

?
1
2
3
4
5
6
7
8
> set foo 1
OK
> get foo
"1"
> incr foo
(integer) 2
> get foo
"2"

内部原理

基本实现

Redis字符串原理的深入理解

上图所示为字符串的基本结构,其中 content 里面保存的是字符串内容,和 c 一样用 0x\0作为结束字符.这个结束字符不会被计算len 中.代码如下:

?
1
2
3
4
5
6
struct SDS{
  T capacity;       //数组容量
  T len;            //实际长度
  byte flages;  //标志位,低三位表示类型
  byte[] content;   //数组内容
}

可以看到 capacity和len 都是泛型,为什么不直接使用 int 呢?因为 Redis 内部做了很多优化,为了减少内存的使用不同长度的字符串会使用不同的数据类型去表示.并且在创建字符串的时候 len 会和 capacity 一样大,没有冗余的空间,因为修改字符串的场景很少.(Redis 真的将内存优化到了极致)

编码格式

Redis 字符串编码格式有这么几种:int 编码、embstr编码和raw 编码 下面就详细介绍下这几种编码的区别.

在这之前先要说说RedisObject. Redis 的对象头,所有的 Redis 对象都有下面这个头部结构.

?
1
2
3
4
5
6
7
8
struct RedisObject{
  int4 type;        //数据类型 5 种
  int4 encoding;    //键值内部编码格式 int 或 embstr 等等
  int24 lru;        // 当内存超限时采用LRU算法清除内存中的对象
  
  int32 refcount;   //改键值被引用的数量
  void *ptr;        //对象内容
}

int 编码

当储存的值是64 位有符号整数类型的时候将会采用 int  编码,这时可以使用键值自增操作.Redis 在启动时会建立1w 个redisObject共享对象下文会讲到,值在[0,1000)之间.如果存入整数的值在[0,1000)中Redis将不会创建新的对象,而是直接指向共享对象,键值不额外占用空间.

使用 object encoding命令可以查看编码格式 使用 debug object命令可以查看更多信息

?
1
2
3
4
5
6
7
8
9
10
> set foo 1
OK
> object encoding foo
"int"
> set foo2 1
OK
> debug object foo
Value at:0x7f44b020aca0 refcount:2147483647 encoding:int serializedlength:2 lru:14691591 lru_seconds_idle:72588
> debug object foo2
Value at:0x7f44b020aca0 refcount:2147483647 encoding:int serializedlength:2 lru:14691591 lru_seconds_idle:72594

可以看到 foo 和 foo2  都在0x7f44b020aca0这里指向的是同一个对象

embstr 编码

当存储的字符串长度较短时(len<=44 字节),Redis将会采用 embstr 编码.embstr 即embedded string 嵌入式的字符串.将SDS结构体嵌入RedisObject对象中, 使用 malloc 方法一次分配内存地址是连续的.

如图所示:

Redis字符串原理的深入理解

raw 编码

当存储的字符串长度较长时(len>44 字节),Redis 将会采用 raw 编码,和 embstr 最大的区别就是 RedisObject 和 SDS 不在一起了,内存地址不再连续了.

如图所示:

Redis字符串原理的深入理解

思考

为什么字符串会有两种格式 embstr 和格式和 raw分界线是 44 个字节?

Redis 默认的内存分配器jemalloc分配内存大小的单位是次方,为了容纳一个完整的 embstr 对象,最少会分配 32 字节的空间,再长些就是 64 字节,再之后就认为这是一个大字符串不适合用 embstr 存储,而改用 raw 编码了.

那么问题来了,64 字节的空间字符串长度是多少呢?答案就是 44 字节.

下图中 content 的长度为 45 字节减去结尾的 0x\0,就剩下 44 字节了.

Redis字符串原理的深入理解

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对服务器之家的支持。

原文链接:https://juejin.im/post/5cf29c1f51882556174dd493

延伸 · 阅读

精彩推荐
  • Redis如何使用Redis锁处理并发问题详解

    如何使用Redis锁处理并发问题详解

    这篇文章主要给大家介绍了关于如何使用Redis锁处理并发问题的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习...

    haofly4522019-11-26
  • RedisRedis 6.X Cluster 集群搭建

    Redis 6.X Cluster 集群搭建

    码哥带大家完成在 CentOS 7 中安装 Redis 6.x 教程。在学习 Redis Cluster 集群之前,我们需要先搭建一套集群环境。机器有限,实现目标是一台机器上搭建 6 个节...

    码哥字节15752021-04-07
  • Redis《面试八股文》之 Redis十六卷

    《面试八股文》之 Redis十六卷

    redis 作为我们最常用的内存数据库,很多地方你都能够发现它的身影,比如说登录信息的存储,分布式锁的使用,其经常被我们当做缓存去使用。...

    moon聊技术8182021-07-26
  • RedisRedis Template实现分布式锁的实例代码

    Redis Template实现分布式锁的实例代码

    这篇文章主要介绍了Redis Template实现分布式锁,需要的朋友可以参考下 ...

    晴天小哥哥2592019-11-18
  • Redis详解三分钟快速搭建分布式高可用的Redis集群

    详解三分钟快速搭建分布式高可用的Redis集群

    这篇文章主要介绍了详解三分钟快速搭建分布式高可用的Redis集群,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    万猫学社4502021-07-25
  • Redis关于Redis数据库入门详细介绍

    关于Redis数据库入门详细介绍

    大家好,本篇文章主要讲的是关于Redis数据库入门详细介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    沃尔码6982022-01-24
  • RedisRedis集群的5种使用方式,各自优缺点分析

    Redis集群的5种使用方式,各自优缺点分析

    Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。...

    优知学院4082021-08-10
  • Redisredis缓存存储Session原理机制

    redis缓存存储Session原理机制

    这篇文章主要为大家介绍了redis缓存存储Session原理机制详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    程序媛张小妍9252021-11-25