Redis核心技术总结
文章目录
导论
在平时的工作项目中,使用redis很长时间了,但一直没有系统的学习总结过,现在看到极客时间蒋德钧老师开设的《Redis核心技术与实战》,干货满满,特地跟随课程小小总结一下,以供日后复习之用。
Redis 知识全景----两大维度,三大主线
应用维度学习路线:
-
应用场景驱动
-
典型案例驱动
1. redis的数据结构
数据类型(5种):String(字符串)、List(列表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)
数据结构(6种):简单动态字符串(Simple Dynamic String)、双向链表、压缩列表(ziplist)、哈希表、跳跃表(skiplist)和整数集合(intset)
数据类型与数据结构对应关系:
一种:String–>SDS
二种:集合类型(一个键对应了一个集合的数据) List、Hash、Set 和 Sorted Set
键-值的结构组织
全局哈希表
无论String,还是集合类型,哈希桶中的元素都是指向它们的指针。
哈希表的rehash
哈希冲突解决方式:链式哈希
渐近式哈希:把一次性大量拷贝的开销,分摊到了多次处理请求的过程中,避免了耗时操作,保证了数据的快速访问。
redis数据结构的时间复杂度
不同操作的复杂度
单元素操作是基础
一种集合类型对单个数据实现的增删改查操
范围操作非常耗时
集合类型中的遍历操作,可以返回集合中的所有数据
统计操作通常高效
集合类型对集合中所有元素个数的记录
例外情况只有几个
压缩列表和双向链表都会记录表头和表尾的偏移量
2. 单线程的Redis为何这么快
Redis是单线程的吗?
Redis对外提供键值存储服务的主要流程,即网络IO和键值对读写是由一个线程完成的,但其它功能,比如持久化、异步删除、集群数据同步等,是由额外的线程执行的。
Redis为什么要用单线程?
多线程编程模式面临的共享资源的并发访问控制问题,会造成系统吞吐率并没有随线程的增加而线性增长
单线程Redis为什么那么快?
-
Redis 的大部分操作在内存上完成,再加上它采用了高效的数据结构,例如哈希表和跳表
-
Redis 采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,实现高吞吐率
基于多路复用的高性能I/O模型
Linux中的select/epoll多路复用机制,指一个线程处理多个IO流。Redis 单线程运行时,该机制允许内核中,同时存在多个监听套接字和已连接套接字。内核会一直监听这些套接字上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。
3.Redis持久化
AOF(Append Only File)
AOF是写后日志,将数据写入内存,然后再记录日志。
写后日志好处:1.避免出现记录错误命令的情况;2.不会阻塞当前的写操作
写回策略
重写(rewrite)
一个拷贝,两处日志
“一个拷贝” - 每次执行重写时,主线程 fork 出后台的 bgrewriteaof 子进程,子进程拷贝一份含有 数据库最新数据的内存
“两处日志”
- 正在使用的AOF日志。
- 新的AOF重写日志。
何时重写ROF文件
- 手动执行 bgrewriteaof 触发 AOF 重写
- 在 redis.conf 文件中配置重写的条件,如:
auto-aof-rewrite-min-size 64MB // 当文件小于64M时不进行重写
auto-aof-rewrite-min-percenrage 100 // 当文件比上次重写后的文件大100%时进行重写
RDB
执行的是全量快照
两个命令
-
save 主线程执行,导致阻塞
-
bgsave fork一个子进程,避免阻塞,默认配置
执行快照时数据能否修改
采用写时复制技术(Copy-On-Write, COW),在执行快照的同时,正常处理写操作。
如果主线程要修改一块数据(例如图中的键值对 C),则被修改据被复制一份,生成该数据的副本。然后,bgsave 子进程将副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据.
混合使用 AOF 日志和内存快照
内存快照以一定的频率执行,在两次快照之间,使用 AOF 日志记录这期间的所有命令操作,当执行第二次全量快照时清空AOF日志。
Redis 4.0 开始支持 rdb 和 aof 的混合持久化(默认关闭,aof-use-rdb-preamble配置)。如果把混合持久化打开,aof rewrite 的时候就直接把 rdb 的内容写到 aof 文件开头
AOF 和 RDB 的选择
- 数据不能丢失时,内存快照和 AOF 的混合使用是一个很好的选择
- 如果允许分钟级别的数据丢失,可以只使用 RDB
- 如果只用 AOF,优先使用 everysec 的配置选项,因为它在可靠性和性能之间取了一个平衡。