redis学习笔记
redis的基本数据类型 :
String:set get
hash:hmset hget
列表:lpush lrange
集合:sadd smumbers
有序集合:zadd zrangebyscore
如何从海量数据中查找某些固定前缀的key:
使用keys指令
使用keys对线上业务的影响:
1.一次性需要返回所有匹配的key
2.如果key的数量过大会导致服务卡顿
使用scan指令
1.scan指令每次执行只会返回少量数据,是一个基于游标的迭代器,每次迭代都需要上次的游标作为游标参数,延续迭代过程。
2.以0作为游标新一次的迭代,直到返回游标0完成一次完整的遍历。
3.并且不保证每次返回的数量。
4.一次返回的数量并不可控,只能大概率符合count参数
分布式锁需要解决的问题:
互斥性 :任意时刻只能有一个客户端获取锁
安全性 :锁只能被持有该锁的客户端删除
死锁 :避免获取锁的客户端出现问题导致无法有其他客户端访问,所造成的死锁
容错 :当Redis出现问题时,客户端可以访问获取锁
如何通过Redis实现分布式锁:
setnx key value:如果key不存在,则创建并且赋值
解决setnx长期有效的方法:给key设定生存时间 expire key time
实现分布式锁的伪代码:
该方法的缺陷:因为由两个原子性的操作组合导致非原子性,容易在未执行到判断时方法挂断,导致锁一直存在
解决方法
采用set key value [EX seconds] [PX milliseconds] [NX|XX]
ex:设置秒
px:设置毫秒
nx:只在键存在时的操作
xx:只在键不存在时进行的操作
redis代码
实现分布式锁的伪代码
大量key过期时会出现卡顿:只要将设置key过期时间时每个key加上随机值使得过期时间分散就可以解决。
如何使用Redis做异步队列:
rpush生产 lpop消费
但是lpop在队列里没有值得时候不会等待,这时候使用blpop key timeout,key添加使用时间,阻塞队列到有消息或者超时。
但是blpop缺点是只能供一个消费者消费
这时候就需要使用pub/sub主题订阅者模式
pub发送者,sub接受者
但是发送者发布消息时时及时发送及时消失的,所以在生产者生产的时候,消费者下线,就不会接收到该消息,可以使用专业的消息队列kafka等解决该问题
redis如何做持久化:
使用RDB持久化:保存某个时间点的全量数据快照
save:阻塞redis进程,知道全部完毕
bgsave:分出一个子进程执行,不会阻塞
缺点:内存数据的全量同步,数据量大的话会由于I/O而严重影响性能
可能会因为redis的挂断而导致这一时间内的数据丢失
如果不能丢失数据,则使用AOF持久化
AOF持久化:保存写状态,保存了除了查询以外的所有变更数据库指令,会append的形式追加到AOF文件中,一定时间后会自动创建之进程,在不影响执行的情况下,自动优化AOF文件
config set appendonly yes //将aof打开,在每次退出后会自动更新文件appendonly.aof
如果RDB和AOF都存在时会先查找AOF
RDB和AOF混合持久化方式
使用BGSAVE做全量持久化,用AOF做增量持久化
自动触发RDB持久化的方式:
1.根据redis.conf配置里面的save定时出发
2.主从复制的时候,主节点自动触发
3.执行Debug Reload
4.执行shutdown并且没有开启AOF持久化
AOF和RDB的优缺点
RDB优点:全量数据,文件小,恢复快
RDB缺点:无法保存最近一次快照之后的数据
AOF优点:可读性高,适合保存增量数据,数据不易丢失
AOF缺点:文件体积大,恢复时间长
Pipeline
Pipeline与linux的管道类似
Redis基于请求响应模型,单个请求需要一一应答,这样大大加深了io消耗
Pipeline批量执行指令,节省多次io往返时间,这样Redis就允许一次发送多条指令,有顺序依赖的建议分批发送 =_=
Redis的同步机制
分为全同步过程和增量同步
全同步过程
增量同步过程
Redis Sentinel
Redis哨兵模式只要是为了解决Redis中Master宕机后的主从切换问题,它有如下功能:
1.监控:检查主从服务器是否能正常运行
2.提醒:通过API向管理员或者其他应用程序发送故障通知
3.自动故障迁移:主从切换
Gossip流言协议
为了各节点之间保持一致
Redis集群的原理
分片:去按照某种规则去划分数据,分散存储到多个节点上
如果按照常规哈希划分方法会导致无法动态的实现节点的增减
这个时候就需要引入一致性哈希算法,哈希环
如果节点减少
如果节点增多
但是可能会出现数据偏移的情况,因为如果只有两个节点的话,两个节点相近,那么会有一大部分的数据会觉得离其中一个更近,那么就会造成数据偏移,这时候就需要调用虚拟节点的方法,为每台服务器后增加编号创建虚拟节点。