redis 2020-07-17
可以用list的rpush+lpop实现简单的消息队列功能(用blpop可以阻塞连接直到有消息时才返回)
消费者通过subscribe订阅一个频道,生产者通过publish发布消息到频道,实现多条发布。
通过unsubscribe取消订阅。
订阅的频道可以用通配符,比如(*)。
事务:保证指令一次性执行,和传统事务的区别是假如执行了,中途有错误也无法回滚(语法错误例外,语法错误会导致都不能执行)
指令
好处
使用
案例
限流令牌桶
1、纯内存操作,KV结构(时间复杂度O1)
2、单线程:没有创建、销毁线程的开销,也不需要上下文的切换
3、多路复用I/O
为什么不用多线程?Redis的瓶颈在于内存,用多线程会提高复杂度,所以使用了单线程。
CPU分时间片运行时,需要保存程序计数器等信息,然后切换,就叫上下文切换,比较耗资源。
传统I/O阻塞
非阻塞I/O(NIO)少了准备数据的阻塞过程,等待数据准备过程中是非阻塞的。
异步I/O(AIO)少了自己主动拷贝数据的过程,拷贝过程中也是非阻塞的。
多路复用I/O:服务端会和多个客户端socket连接,使用轮询的方式轮询访问socket,任意一个socket的数据准备好了都执行读取该socket的数据。使得一个进程可以快速的保持多个连接,优点是连接多。
定时过期:每个key创建一个定时器,但是key很多的时候定时器很多。
惰性过期:下次访问key的时候,判断key是否已过期,过期则删除。(对内存不友好,过期的还在占用内存)
set memory到达上限时,调用activeExpireCycle()释放内存
定期过期:每次扫描一定数量,采样删除。
redis中使用了惰性过期(访问键)和定期过期(一定时间扫描)。
淘汰策略
allkeys-lru 最近最少使用
allkeys-random
(exception)noeviction 不淘汰
allkeys-lfu 一段时间内使用最少
volatile-lfu 一段时间内使用最少 (只针对ttl)
volatile-lru
volatile-ttl 把最快过期的删除
volatile-random
lru算法通过对象里使用一个缓存的lru时间戳来比较,当前缓存时间与对象lru时间戳距离越久,说明热度越低。
lfu算法和lru同一个字段,分位统计,高16位记录访问时间,低8位记录访问频率
默认的持久化方案,生成快照dump.rdb到磁盘中,重启时根据该文件恢复,
触发机制:save seconds changes
save 900 1
save 300 10
save 60 10000
手动触发:save命令(会阻塞),redis自身是异步持久化数据,bgsave,fork子进程生成快照,并替换原来的rdb文件。
默认不开启,需要通过配置开启
保存操作指令,也有触发机制:appendfsync
appendfsync always(每次操作都存储)
appendfsync everysecond(每秒同步一次,最常用)
appendfsync no(由系统自行决定什么时候同步)
文件特别大时可以通过rewrite指令压缩,bgrewriteaof,系统根据配置参数(上次重写比例和最小大小)来重写。
重写的时候假如有新指令过来会缓存新指令,AOF重写结束后将缓存命令追加到AOF里面中。