文章目录
一.线程IO
1.redis快的原因
redis数据都在内存中,运算更快
2.并发高
- 采用非阻塞IO,读写可以瞬间完成,然后线程处理其他事
- 多路复用,周期调用事件轮询函数,处理响应的读写函数
3.指令队列
redis会为每个客户端套接字关联一个指令队列,redis同样会为每个套接字关联一个响应队列,通过响应队列将结果返回。
4.定时任务
redis会将定时任务记录在一个最小堆,最快要执行的任务在堆顶,每个周期内都会记录下来最快要执行的任务的时间,作为select函数执行的timeout时间。
二.RESP
redis serialization protocol,redis序列化协议,特点:异常简单,性能极高,易于理解和实现。
1.单元类型
- 单行字符,+开头
- 多行字符,$开头
- 整数值,:开头
- 错误消息,-开头
- 数组,*开头
三.持久化
1.快照
二进制形式,存储紧凑。
进行内存快照读,使用多线程的COW(copy on write)机制来实现持久化。调用glibc的函数fork一个子线程,将快照持久化的工作完全交给子线程处理,父线程和子线程共享内存。父线程继续接收请求,在对数据进行修改时会将共享的数据片段复制出来进行修改,子线程对应的内存页面是没有变化的。
2.AOF
存储指令文本。
在收到客户端修改指令后,先进行参数校验,如果没问题就会将指令存到AOF文件中。AOF指令存储占用空间较大,长时间存储会对通过bgrewrite其进行重写:先遍历内存形成aof文件,然后将操作期间的AOF指令进行追加,最后对原有文件进行替换。
fysnc:AOF实际是以文件的形式存储的,当程序对AOF文件进行写操作时,实际上是将内容写到了内核文件为文件描述符分配的缓存中,然后内核会将数据刷新到磁盘上。刷新有三种模式:
- 定时,如1s一次,宕机时会丢失1s内的数据
- 每次执行修改指令,太慢
- 由内核决定何时刷新,具有不确定性
3.运维
redis的主节点通常不会进行持久化操作,持久话操作通常是在从节点进行。从节点是备份节点,没有客户端压力,操作系统资源比较充足。
四.管道
1.消息交互
客户端批量写入,然后整体发送到服务端,服务端处理完成后,客户端连续读出,减少网络请求次数。同时改变了读写顺序带来了巨大的性能提升。
2.实现步骤
- 客户端调用write将指令写到到发送缓冲区
- 内核将发送缓冲区的内容发送到网卡,网卡通过路由发送到服务端网卡
- 服务器将网卡接收到的数据写入接收缓冲区
- 服务端调用read读取接收缓冲区的数据进行处理
- 服务端处理完成后将返回结果写入到服务端发送缓冲区
- 内核将发送缓冲区的数据发送到网卡,网卡通过路由发送到客户端网卡
- 客户端网卡将接收到的数据写入到接收缓冲区
- 客户端调用read从接收缓冲区读取数据返回给上层业务逻辑
五.事务
使用multi开启事务,创建管道,添加指令,exec提交执行指令。discard可以用来丢弃指令。一些特性
-
redis不具备原子性,在执行异常时不会回滚,redis仅满足事务的隔离性(串行化执行)
-
redis事务使用了管道,可以将命令暂存,然后分组发送,减少网络IO
-
watch命令可以在事务开始前监控某个变量,如果事务执行过程中,该变量发生变化,exec会返回null,代表执行失败
六.pub/sub
可以实现消息多播,即多个消费者可以订阅同一个发布者
-
消息订阅
可以同时订阅多个队列,也支持模式匹配订阅
-
消息结构
- data:数据
- channel:队列主题
- type:消息类型
- pattern:订阅时使用的匹配模式
七.小对象压缩存储
优化技术:
-
如果使用32bit编译,内部指针占用空间小一半,前提是redis内存占用不超过4G
-
二维结构转化为一维数组存储,使用intset存储整数
- hash将key、value在数组中紧凑存储
- zset将value和score在压缩列表中紧凑存储
-
redis使用del删除键时,不会释放内存,但是可以被其他键值复用,想释放需调用flushdb进行刷新
八.主从同步
1.分布式理论基础
CAP理论,网络分区发生时,可用性和一致性没法同时保证。
- P-partiotion:分区容忍性
- A-avaliable:整体可用性
- C-consitent:各个节点数据一致性
2.最终一致性
分区发生时,在数据一致性上妥协,允许数据暂时不一致,分区消除后,数据会进行同步追赶,保证最终数据的一致性
3.主从同步
- 主从同步,数据源统一
- 从从同步,减小主节点数据同步压力
- 增加从节点时,会先进性快照同步,然后进行AOF的增量同步
4.无盘复制
主节点不生成快照文件,只将快照文件的内容发送到从节点
5.wait指令
同步复制,保证系统的一致性,参数N:同步从库的数量,t:同步的等待时间