Redis介绍
深层理解redis细节原理
、主线程(处理网络请求)单线程,读写请求,串行处理,避免上下文切换和锁竞争,效率更高。保证了每个操作的原子性
虽然处理器是单线程上运行的,但是通过IO多路复用模块的引入,实现了同时对多个FD读写的监控,提高了网络通信模型的性能
多路复用IO
“多路”指的是多个网络连接,“复用”指的是复用同一个线程。采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求**(尽量减少网络IO的时间消耗)。可以直接理解为:单线程的原子操作,避免上下文切换的时间和性能消耗**;加上对内存中数据的处理速度,很自然的提高redis的吞吐量
redis常用的数据类型
从海量数据中查询出某一固定前缀key
迭代到了哪里
可能会获取重复数据,所以需要开发代码获取。
分布式锁
不同系统,防止访问共享资源的互斥性
容错是指redis宕机之后,依然能让客户端获取锁
安全性是指 能要同一个redis客户端加锁和解锁如何解决分布式锁
如何解决SETNX长期有效问题
代码实现伪代码实现如下:
但这个代码有风险
程序设置后挂掉,没有过期时间
Redis2.6.1.2 版本有原子性操作
java中就可以使用这个伪代码来实现这个操作了,和redis操作保持原子性一样
大量的Key同时过期的注意事项:
Redis 做异步队列
不想sleep怎么处理:
替代sleep做更加精准的控制
实现生产一次,多次消费
这个频道是不需要预先创建的
持久化方式之RDB
redis.conf 配置,redis启动的之后会自动加载这个配置文件
因为流量不同,所以进行多条配置
当备份进程出错时候,主进程停止操作,保证备份一致性,如果自己的业务有完善的监控系统,可以禁止此项配置,要么开启
rdb 进行压缩后在进行保存,建议设置为no,因为redis本身就是cpu密集服务器,压缩带来更多消耗,比起硬盘,cpu更值钱
禁用rdb
进入src 文件夹,会有dump.rdb文件,可以查看,二进制文件
如何创建rdb文件
子进程,创建完之后发送信号给父进程,父进程轮询子进程信号。后台方式创建rdb,调用后立马返回OK,主进程可以使用lastsave命令进行查看,时间不同,报错成功。
可以自己写进程,报错redis文件自动触发rdb
同一时间只有一个BGSAVE子进程,为了防止资源竞争,
rdbsavebackground,其实就是调用操作系统的fork函数
传统方式下fork子进程,将父进程所有资源赋值给子进程,简单但效率低下
linux 改进了fork实现方式,创建子进程,内核只为子进程创建虚拟空间,父子进程使用相同物理空间,只有父子进程发生更改时,才会为子进程开启独立的物理空间,这个是操作系统层面的优化
这个过程对其他调用者是透明的,COW需要为读请求维护一个指针,新数据写入完成后,更新这个指针,提高了读写并发能力
子进程,rdb了全量COW原先的物理内存之后,替换到原有rdb文件后,退出,完成一次备份操作
redis加载rdb文件是自动的
因为全量同步,如果数据量大,必然引起大量磁盘IO操作,可能会严重影响性能
持久化方式之AOF
备份写入redis的指令
默认关闭,需要打开
及时写入,每隔一秒写入,no交由操作系统处理,缓存区填满,自行写入磁盘
上图验证了shutdown 会保证save rdb,重启会加载rdb,不接受外部访问
此时 ping pong才可以访问
AOF是个纯追加问价,断点也会尽可能保存
AOF重写依旧利用了COW,和老的AOF文件无关:
使用bgrewrite 命令
Redis 数据恢复
AOF 人类可读,所以文本较大.
Redis 4.0使用了混合持久化方式,作为默认的方式,
之前重写也是先写一分redis数据到AOF文件中,再追加增量,只不过全量数据是同redis命令方式写入的,可以用rdb方式写入,在同步增量,就结合来了两者优点,并保证了完整性
子进程在使用AOF重写时,会通过管道从父进程同步增量数据并缓存下来,在rdb读取数据后呢,再从管道获取,并不会阻塞管道
这个需要张高清图
redis实例重启后,先用rdb恢复,再用aof会放,实现完整之前的状态
Pipeline 以及主从同步
redis的同步机制:
主从同步原理
不是高可用
一般都是一个Master进行写操作,其他slave进行读操作
slave 收到数据后就将文件保存在磁盘中
全量同步之后slave就用来读,master 用来写
对齐主从库, 确保该数据库是该操作对应的数据库,并按照Redis的命令格式写到响应slave的缓存中Redis Sentinel:
这个是 分布式系统,可以在一个环境运行多个sentinel
fabric就是用这个协议,进行通信
Redis 集群原理
如何从海量数据里快速找到所需?
为了解决这个问题,redis引入了一致性hash算法
服务器IP哈希,确定服务器位置,数据进行hash 碰到那个,用哪个
好处在于,c出问题,会保存到nodeD上,最坏就是逆时针走的第一台服务器,其他数据不受影响,换到顺时针。
受影响的就是逆时针环的一小部分数据需要被重新分配,其他数据不会受到影响。
引入虚拟节点,放上编号,均匀分布到环上,多了虚拟节点和真实节点的映射,这些redis集群机制都帮实现了。
源码底层自己在看吧