Redis
如有侵权,请联系~
如有错误,也欢迎批评指正~
本篇文章大部分是来自学习极客时间的笔记
1、redis数据类型与底层数据结构对应关系
这些都是value的存储结构。而键值之间的数据结构使用的是哈希表。set的底层实现有两种:整数数组和哈希表。整数数组需要满足两个条件:1、存储必须是整数 2、元素个数不超过512个。
2、redis的持久化
redis不和数据库一样WAL(日志先行),而是先记录数据,再保存日志。
详细描述 | 优缺点 | 刷盘时机 | 备注 | |
---|---|---|---|---|
AOF(Append of file) | AOF里记录的是Redis收到的每一条命令,这些命令是以文本形式保存的。 | 优点: 为了避免额外的检查开销,Redis在向AOF里面记录日志的时候,并不会先去对这些命令进行语法检查。所以,如果先记日志再执行命令的话,日志中就有可能记录了错误的命令,Redis在使用日志恢复数据时,就可能会出错。它是在命令执行后才记录日志,所以不会阻塞当前的写操作。 缺点: 如果刚执行完一个命令,还没有来得及记日志就宕机了,那么这个命令和相应的数据就有丢失的风险。AOF虽然避免了对当前命令的阻塞,但可能会给下一个操作带来阻塞风险。这是因为,AOF日志也是在主线程中执行的,如果在把日志文件写入磁盘时,磁盘写压力大,就会导致写盘很慢,进而导致后续的操作也无法执行了。 | AOF机制给我们提供了三个选择,也就是AOF配置项appendfsync的三个可选值。 Always,同步写回: 每个写命令执行完,立马同步地将日志写回磁盘;Everysec,每秒写回: 每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,每隔一秒把缓冲区中的内容写入磁盘;No,操作系统控制的写回: 每个写命令执行完,只是先把日志写到AOF文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘。 | AOF存储格式: 以Redis收到"set testkey testvalue"命令后记录的日志为例,看看AOF日志的内容。其中,"*3"表示当前命令有三个部分,每部分都是由"$+数字"开头,后面紧跟着具体的命令、键或值。这里,"数字"表示这部分中的命令、键或值一共有多少字节。例如,"$3 set"表示这部分有3个字节,也就是"set"命令。AOF文件太大怎么办? 重写机制。AOF重写机制就是在重写时,Redis根据数据库的现状创建一个新的AOF文件,也就是说,读取数据库中的所有键值对,然后对每一个键值对用一条命令记录它的写入。比如说,当读取了键值对"testkey": "testvalue"之后,重写机制会记录set testkey testvalue这条命令。这样,当需要恢复时,可以重新执行该命令,实现"testkey": "testvalue"的写入。(其实和数据库的全量备份、快照是不是一个原理,万物相通)。 AOF重写流程 每次AOF重写时,Redis会先执行一个内存拷贝,用于重写;然后,使用两个日志保证在重写过程中,新写入的数据不会丢失。而且,因为Redis采用额外的线程进行数据重写,所以,这个过程并不会阻塞主线程。 |
RDB | Redis提供了两个命令来生成RDB文件,分别是save和bgsave。save:在主线程中执行,会导致阻塞;bgsave:创建一个子进程,专门用于写入RDB文件,避免了主线程的阻塞,这也是Redis RDB文件生成的默认配置 | 优点:进行数据恢复的时候不用执行过多的aof命令,恢复快 缺点:不能实时 每时每刻都进行RDB存储 | 推荐:使用RDB,在RDB之间使用aof进行存储 |
3、主从同步
三种模式:全量复制、基于长连接的命令传播,以及增量复制。
全量复制:
基于长连接的命令传播:这是第一次进行全量的同步数据。当第一次同步完成之后,主库和从库就会维持一个长网络连接,主库会通过这个连接将后续陆续收到的命令操作再同步给从库,这个过程也称为基于长连接的命令传播,可以避免频繁建立连接的开销。
增量复制:如果长连接断开。主库每次命令都会同时存储到repl buffer以及repl backlog环形缓存中,等到从库重新连接之后会从repl backlog中读取这一段时间增加的命令,通过主库和从库偏移量的不同。 repl buffer:每一个从库对应一个repl buffer(不同从库进行全量复制的时间不一样,使用同一个不方便?)
4、哨兵机制
哨兵其实就是一个运行在特殊模式下的Redis进程,主从库实例运行的同时,它也在运行。哨兵主要负责的就是三个任务:监控、选主(选择主库)和通知。
任务 | 介绍 | 备注 |
---|---|---|
监控 | 监控是指哨兵进程在运行时,周期性地给所有的主从库发送PING命令,检测它们是否仍然在线运行。如果从库没有在规定时间内响应哨兵的PING命令,哨兵就会把它标记为"下线状态";同样,如果主库也没有在规定时间内响应哨兵的PING命令,哨兵就会判定主库下线,然后开始自动切换主库的流程。 | 主观下线和客户下线。主观下线只要有一个哨兵判断机器下线(ping不通)那就是主观下线,这对于从库来说没问题,因为断定从库下线没集群影响不大。而主库不行,一旦任务主库下线就要进行下面的选主,通知比较浪费资源。所以一个哨兵ping不通则认为是主观下线,需要这个哨兵集群中的多数都认为是主观下线,才断定为客观下线,此时才进行下面选主 通知。 |
选主 | 主库挂了以后,哨兵就需要从很多个从库里,按照一定的规则选择一个从库实例,把它作为新的主库 | 主要有两步: 筛选 。按照在线状态和网络状态过滤掉不符合条件的从库;打分。依此按照从库优先级、从库复制程度、从库ID进行打分。只有优先级出现两个一样高的才会将这两个从库进行复制程度进行比较,否则直接选出最高的。 |
通知 | 在执行通知任务时,哨兵会把新主库的连接信息发给其他从库,让它们执行replicaof命令,和新主库建立连接,并进行数据复制。同时,哨兵会把新主库的连接信息通知给客户端,让它们把请求操作发到新主库上。 |
5、redis为什么这么快
- 数据是基于内存进行存储的
- redis是key-value进行存储的,使用的hash结构,数据的操作度O(1)
- redis使用C语言进行实现,执行效率高,可以直接操作硬件,更好地管理内存,这使得Redis在处理大量数据时能保持高效的性能
- 它采用单进程单线程模型,这样做的好处就是避免了上下文切换和不必要的线程之间引起的资源竞争
- 在技术上Redis还采用了多路I/O复用技术。这里的多路指的是多个socket网络连接,复用指的是复用同一个线程。采用多路I/O复用技术的好处是可以在同一个线程中处理多个I/O请求,尽量减少网络I/O的消耗,提升使用效率。
6、RESP协议
RESP(Redis Serialization Protocol )是Redis服务器用来与客户端进行通信的协议。它是一种简单的文本协议,设计上易于实现和解析。
RESP协议的主要特点包括:
- 简单:RESP协议的设计非常简单,易于理解和实现。它使用简单的符号来表示不同的数据类型,例如使用冒号(:)表示整数,使用美元符号($)表示二进制安全的字符串。
- 可读性:尽管RESP是一种二进制协议,但是它的设计使得在人类可读的文本中也可以表示大部分的消息。这使得开发者在调试应用程序时可以更容易地理解Redis服务器和客户端之间的通信。
- 高效:RESP协议的设计使得它在处理大量数据时仍然能保持高效的性能。例如,它使用特殊的数据类型来表示数组,这使得它可以高效地处理大量的数据。
redis有标准的通信协议RESP,任意支持了这套协议的都可以当sdk。