2.1 鞭辟入里——线程IO模型
Redis使用单线程执行模型。
Redis快的核心在于所有数据都在内存中,所有运算都是内存级别的运算。
2.1.1 非阻塞IO
2.1.2 事件轮询(多路复用)
2.1.3 指令队列
Redis会将每个客户端套接字都关联到一个指令队列。客户端的指令通过队列来排队进行顺序处理,先到先服务。
2.1.4 响应队列
2.1.5 定时任务
2.2 交头接耳——通信协议
2.3 未雨绸缪——持久化
Redis的持久化机制有两种,第一种是快照(RDB),第二种是AOF日志。快照是一次全量备份,AOF日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而AOF日志记录的是内存数据修改的指令记录文本。AOF日志在长期的运行过程中会变得无比庞大,若用AOF日志进行恢复,时间很长,因此需要定期进行AOF重写,给AOF日志瘦身。
2.3.1 快照原理(RDB)
Redis采用fork()创建进程时的Copy On Write机制,来形成快照。调用fork()创建子进程后,父子进程将共享物理内存页。只有当某一方试图修改内存数据时,才会拷贝一页数据给子进程,然后然后再修改。随着修改越来越多,两者的物理页才逐渐分离。利用这种机制,可以瞬间创建一个内存快照,且父进程可以继续提供服务,而子进程将快照持久化。
2.3.3 AOF原理
AOF日志存储的是Redis服务器的顺序指令序列,AOF日志只记录对内存进行修改的指令记录。
假设AOF日志记录了自Redis实例创建以来所有的修改性指令序列,那么就可以通过对一个空的Redis实例顺序重放所有指令,来恢复Redis当前实例的内存数据结构的状态。
2.3.4 AOF重写
Redis提供bgrewriteaof指令用于对AOF日志进行瘦身,其原理是fork一个子进程,对内存快照进行遍历,转换成一系列Redis的操作指令,序列化到一个新的AOF日志文件中。序列化完毕后,再讲操作期间发生的增量AOF日志追加到这个新的AOF日志中,追加完毕后就立即替代旧的AOF日志文件。
2.3.5 fsync
AOF日志通常并非实时保存到硬盘上,而是先保存到内存缓存中,然后依据配置决定何时保存到硬盘上。通常会选择1s保存一次。
2.3.6 运维
持久化是一个比较重量级的操作,因此通常不会在Redis的主节点进行持久化,而是在从节点上进行持久化。
2.3.7 Redis 4.0混合持久化
使用RDB文件恢复Redis非常快,但RDB快照的实时性不够,很容易丢失数据。AOF日志实时性很高(通常只会丢失最多1S数据),但是日志体积大,恢复速度很慢。
Redis 4.0为了解决这个矛盾,带来了一个新的持久化选项——混合持久化。通过将RDB文件和增量的AOF日志文件存放在一起,从而拥有了两者的优点。
2.4 雷厉风行——管道
本质上就是客户端批量发送命令。
2.5 同舟共济——事务
让一批命令连续地、不间断的执行。通常要配合pipeline使用。Redis事务不具备原子性,队列中一个执行失败,不会导致之前已经成功的指令回滚,也不能阻止队列后续指令的执行。不过可以保证serializable的隔离性。
