为什么用Redis?
数据类型丰富
支持数据磁盘持久化存储
支持主从
支持分片
为什么Redis能这么快?
完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
数据结构简单,对数据操作耶简单
采用单线程,单线程也能处理高并发请求,想多核也可以启动多实例
使用多路I/O复用模型,非阻塞IO
Redis常用数据类型
String : 最基本的数据类型,二进制安全
Hash:String元素组成的字典,适用于存储对象
List:列表,按照String元素插入顺序排序
Set:String元素组成的无序集合,通过哈希表实现,不允许重复
Sorted Set:通过分数来为集合中的成员进行从小到大的排序
用于计数的HyperLogLog,用于支持存储存储地理位置信息Geo
实际项目中可能会遇到的问题
1. 分布式锁需要解决的问题
互斥锁
安全性
死锁
容错
2. 通过Redis命令实现分布式锁
SETNX key value : 如果key不存在,则创建并赋值
时间复杂度:O(1)
返回值:设置成功,返回1,否则返回0
3. 如何解决SETNX长期有效的问题
EXPIRE key seconds
设置key的生存时间,当key过期时(生存时间为0),会被自动删除
缺点:原子性得不到满足
解决上述原子性得不到满足的问题:
通过Redis命令解决:SET key value [EX seconds] [PX milliseconds] [NX | XX]
EX second:设置键的过期时间为second秒
PX millisecond: 设置键的过期时间为millisecond秒
NX:只在键不存在时,才对键进行设置操作
XX:只在键已经存在时,才对键进行设置操作
SET操作成功完成时,返回OK,否则返回nil
4. 大量的key同时过期的注意事项
集中过期,由于清除大量的key很耗时,会出现短暂的卡断现象
解决方案:在设置key的过期时间的时候,给每个key加上随机值
如何使用Redis来做异步队列
使用List作为队列,RPUSH生产消息,LPOP消费消息
缺点: 没有等待队列里有值就直接消费
弥补:可以通过在应用层引入Sleep机制去调用LPOP重试
一对多的消费队列
采用pub/sub:主题订阅者模式
发送者(pub)发送消息,订阅者(sub)接收消息
订阅者可以订阅任意数量的频道
缺点:消息的发布时无状态的,无法保证可达
Redis如何做持久化–三种持久化方式
1.RDB(快照)持久化:保存某个时间点的全量数据快照
SAVE:阻塞Redis的服务器进程,直到RDB文件被创建完毕
BGSAVE:Fock出一个子进程来创建RDB文件,不阻塞服务器进程
2.自动化触发RDB持久化的方式
根据redisc.config配置里的SAVE m n 定时触发(用的是BGSAVE)
主从复制时,主节点自动触发
执行Debug Reload
执行Shutdown且没有开启AOF持久化
BGSAVE原理
首先检查当前主进程是否存在AOF/RDB的子进程,如果存在则返回错误
如果不存在触发持久化,调用rdbSaveBackground
执行fock指令
如果是主进程相应其他操作
如果是子进程执行rdb操作
系统调用fork():创建进程,实现了Copy-on-Write
Copy-on-Write:
如果有多个调用者同时要求相同资源,他们会共同获取相同的指针指向相同的资源,
直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本给该调用者,
而其他调用者所见到的最初的资源仍然保持不变
RDB持久化缺点
内存数据的全量同步,数据量大会由于I/O而严重影响性能
可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据
3.AOF(Append-Only-File) 持久化:保存写状态
记录下除了查询以外的所有变更数据库状态的指令
以append的形式追加保存到AOF文件中(增量)
AOF持久化
日志重写解决AOF文件大小不断增大的问题,原理如下:
1. 调用fock(),创建一个子进程
2. 子进程把新的AOF写到一个临时文件里,不依赖原来的AOF文件
3. 主进程持续将新的变动同时写到内存和原来的AOF里
4. 主进程获取子进程重写AOF的完成信号,往新AOF同步增量变动
5. 使用新的AOF文件替换掉旧的AOF文件
RDB与AOF的优缺点
1. RDB优点:全量数据快照,文件小,恢复快
2. RDB缺点:无法保证最近一次快照之后的数据
3. AOF优点:可读性高,适合保存增量数据,数据不易丢失
4. AOF缺点:文件体积大,回恢复时间长
RDB-AOF混合持久化方式
BGSAVE做镜像全量持久化,AOF做增量持久化
Redis同步机制
主从同步原理
1.全同步过程
1. Slave发送sync命令到Master
2. Master启动一个后天进程,将Redis中的数据快照保存到文件中
3. Master将保存数据快照期间接收到的写命令缓存起来
4. Master完成写文件操作后,将该文件发送给Slave
5. 使用新的RDB文件替换掉旧的RDB文件
6. Master将这期间收集的增量写命令发送给Slave端
2.增量同步过程
1. Master接收到用户的操作指令,判断是否需要传播到Slave
2. 将操作记录追究到AOF文件
3. 将操作传播到其他Slave:1.对齐主从库;2.往响应缓存写入指令
4. 将缓存中的数据发送给Slave
ps:
第一次写博文,以上都是小编自我总结,如有不对的地方,请各位大佬指教,谢谢。勿喜勿喷!