Redis的数据结构
String
字符串 、Hash
字典 、List
列表 、Set
集合 、SortedSet
有序集合 。
高级的还有 HyperLogLog
,Geo
,Pub/Sub
相关的还有Redis Module
,egs:BloomFilter
,RedisSearch
,Redis-ML
Redis分布式锁的原理
setnx
来锁定锁- 用
expire
给锁加一个过期时间防止锁忘记了释放。
setnx
之后执行expire
之前进程意外crash
或者要重启维护了
1.锁无法释放
2.set指令有非常复杂的参数,可以同时把setnx
和expire
合成一条指令来用的
如何找出某个固定的已知的前缀开头的key
使用 keys
指令
> KEYS key*
"key3"
"key1"
"key2"
keys
指令的特性
1.redis
是单线程
keys
指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。服务恢复后才可以使用 scan
指令,scan
指令可以无阻塞的提取出指定模式的 key
列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys
指令长。
Redis
做异步队列
一般使用 list
结构作为队列,rpush
生产消息,lpop
消费消息。当 lpop
没有消息的时候,要适当 sleep
一会再重试。
1.不能用
sleep
,list
还有个指令叫blpop
,在没有消息的时候,它会阻塞住直到消息到来。
2.使用pub/sub
主题订阅者模式,可以实现 1:N 的消息队列。
pub/sub的缺点
在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq
等。
redis
的延时队列
1.使用 sortedset
,拿时间戳作为 score
,消息内容作为 key
调用 zadd
来生产消息,消费者用zrangebyscore
指令获取N秒之前的数据轮询进行处理。
大量的 key
需要设置同一时间过期的注意点
如果大量的 key
过期时间设置的过于集中,到过期的那个时间点, redis
可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。
Redis
的持久化
1.bgsave
做镜像全量持久化,aof
做增量持久化。
因为 bgsave
会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要 aof
来配合使用。
在 redis
实例重启时,会使用 bgsave
持久化文件重新构建内存,再使用 aof
重放近期的操作指令来实现完整恢复重启之前的状态。
如果突然机器掉电,取决于
aof
日志sync
属性的配置,如果不要求性能,在每条写指令时都sync
一下磁盘,就不会丢失数据。
但是在高性能的要求下每次都sync
是不现实的,一般都使用定时sync
,比如 1s1次 ,这个时候最多就会丢失1s的数据。
bgsave
的原理是什么?
fork
&&cow
。
fork
是指 redis
通过创建子进程来进行 bgsave
操作, cow
指的是 copy on write
,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
Pipeline
可以将多次IO
往返的时间缩减为一次,前提是pipeline
执行的指令之间没有因果相关性。
使用 redis-benchmark
进行压测的时候可以发现影响 redis
的 QPS
峰值的一个重要因素是 pipeline
批次指令的数目。
Redis
的同步机制
Redis
可以使用主从同步,从从同步。
第一次同步时,主节点做一次 bgsave
,并同时将后续修改操作记录到内存 buffer
,待完成后将 rdb
文件全量同步到复制节点,复制节点接受完成后将 rdb
镜像加载到内存。
加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
Redis
集群以及原理
Redis Sentinal
着眼于高可用,在 master
宕机时会自动将 slave
提升为 master
,继续提供服务。
Redis Cluster
着眼于扩展性,在单个 redis
内存不足时,使用 Cluster
进行分片存储。