Redis数据结构和单线程

Redis 数据结构和内部编码

type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是 Redis 对外的数据结构。
实际上 Redis 针对每种数据结构都有自己的底层内部编码实现,而且是多种实现,这样 Redis 会
在合适的场景选择合适的内部编码

|--------|--------------------|
| 数据结构 | 内部编码 |
| string | raw int embstr |
| hash | hashtable ziplist |
| list | linkedlist ziplist |
| set | hashtable intset |
| zset | skiplist ziplist |

可以看到每种数据结构都有⾄少两种以上的内部编码实现,例如 list 数据结构包含了 linkedlist 和ziplist 两种内部编码。同时有些内部编码,例如 ziplist,可以作为多种数据结构的内部实现,可以通过 object encoding 命令查询内部编码:

bash 复制代码
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> object encoding hello
"embstr"
127.0.0.1:6379> object encoding mylist
"quicklist"

Redis 这样设计有两个好处:
1)可以改进内部编码,而对外的数据结构和命令没有任何影响,这样⼀旦开发出更优秀的内部编码, 无需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了⼀种更为优秀的内部编码实现,而对用户来说基本⽆感知。
2)多种内部编码实现可以在不同场景下发挥各⾃的优势,例如 ziplist 比较节省内存,但是在列表元素比较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为
linkedlist,整个过程用户同样无感知。

单线程架构

现在开启了三个 redis-cli 客户端同时执行命令。

bash 复制代码
客户端 1 设置⼀个字符串键值对:
127.0.0.1:6379> set hello world

客户端 2 对 counter 做⾃增操作:
127.0.0.1:6379> incr counter

客户端 3 对 counter 做⾃增操作:
127.0.0.1:6379> incr counter

Redis 是采用单线程模型执行命令的是指:虽然三个客户端看起来是同时要求 Redis 去执行命令的,但微观角度,这些命令还是采用线性方式去执行的,只是原则上命令的执行顺序是不确定的,但一定不会有两条命令被同步执行。

可以想象 Redis 内部只有一个服务窗口,多个客户端按照它们达到的先后顺序被排队在窗口前,依次接受 Redis 的服务,所以两条 incr 命令无论执行顺序,结果一定是 2,不会发生并发问题,这个就是 Redis 的单线程执行模型。

为什么单线程还能这么快

a. 纯内存访问。Redis 将所有数据存放在内存中,内存的响应时长大约为 100 纳秒,这是 Redis 能够实现高性能访问的重要基础。

b. 非阻塞 IO。Redis 使用 epoll 作为 I/O 多路复用技术的实现,再结合自身的事件处理模型,将 epoll 中的连接、读写、关闭等操作转换为事件,不在网络 I/O 上浪费过多时间,如图所示。

c. 单线程避免了线程切换和竞态产生的消耗。单线程可以简化数据结构和算法的实现,让程序模型更简单;同时避免了多线程环境下,因竞争共享数据而产生的线程切换与等待开销。

虽然单线程给 Redis 带来很多好处,但还是有一个致命的问题:对于单个命令的执行时间都是有要求的。如果某个命令执行过长,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客户端的阻塞,对于 Redis 这种高性能的服务来说是非常严重的,所以 Redis 是面向快速执行场景的数据库。

相关推荐
睡不醒男孩0308232 小时前
第二篇:深入探索开源数据库高可用:构建基于CLup的PostgreSQL生产级高可用与读写分离架构
数据库·postgresql·开源·clup
Micro麦可乐4 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统
码农阿豪4 小时前
从零到一:Spring Boot快速接入金仓数据库实战
数据库·spring boot·后端
鼎讯信通4 小时前
风电光缆运维提质增效:G-4000A 光缆故障追踪仪破解风场巡检难题
运维·网络·数据库
三十..5 小时前
MySQL 从入门到高可用架构实战精要
运维·数据库·mysql
cfm_29145 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis
如竟没有火炬6 小时前
最大矩阵——单调栈
数据结构·python·线性代数·算法·leetcode·矩阵
真实的菜6 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
你想考研啊6 小时前
mysql数据库导出导入
数据库·mysql·oracle
十年编程老舅7 小时前
Linux DRM:底层逻辑与实践架构
数据库·mysql