Redis:高级特性和底层工作原理

高级特性

简单消息队列

可以用list的rpush+lpop实现简单的消息队列功能(用blpop可以阻塞连接直到有消息时才返回)

发布订阅模式

消费者通过subscribe订阅一个频道,生产者通过publish发布消息到频道,实现多条发布。
通过unsubscribe取消订阅。
订阅的频道可以用通配符,比如(*)。

Redis事务

事务:保证指令一次性执行,和传统事务的区别是假如执行了,中途有错误也无法回滚(语法错误例外,语法错误会导致都不能执行)
指令

  • MULTI:开启事务(不能嵌套)
  • EXEC:执行事务
  • DISCARD:中途放弃事务的执行
  • WATCH:类似乐观锁的实现,监视一个KEY,假如KEY的值中途有修改,会阻止这个事务的执行
  • UNWATCH
    多条命令一次性执行,只保证执行的"原子性"
Lua脚本

好处

  • 一次发送多个命令,减少网络开销
  • 原子性
  • lua file 实现命令集的复用

使用

  • redis中调用脚本:eval script (参数key) (参数value)
  • lua脚本中执行redis:redis.call(command, key [param1, param2...]),command是命令,key是键,param代表给key的参数
  • 设置lua脚本命令执行超时时间,避免出现意想不到的bug(redis是单线程的),但是超时以后也是只接受不执行,为了保证原子性,这时候需要执行script kill命令,但是假如脚本中已经有数据变更了,执行script kill命令也杀不掉。这时候只能shutdown了。。。。。所以使用lua脚本要注意脚本的稳健性。

案例
限流令牌桶

Redis为什么这么快

1、纯内存操作,KV结构(时间复杂度O1)
2、单线程:没有创建、销毁线程的开销,也不需要上下文的切换
3、多路复用I/O
为什么不用多线程?Redis的瓶颈在于内存,用多线程会提高复杂度,所以使用了单线程。

虚拟内存
  • 物理内存共享出现不安全的问题,使用空间有限
  • 使用虚拟内存可以提高使用空间,划分用户使用空间
用户空间user space和内核空间kernel space
  • 内核态:进程运行在内核空间
  • 用户态:进程运行在用户空间
上下文切换

CPU分时间片运行时,需要保存程序计数器等信息,然后切换,就叫上下文切换,比较耗资源。

多路复用I/O

传统I/O阻塞
Redis:高级特性和底层工作原理
非阻塞I/O(NIO)少了准备数据的阻塞过程,等待数据准备过程中是非阻塞的。
异步I/O(AIO)少了自己主动拷贝数据的过程,拷贝过程中也是非阻塞的。

多路复用I/O:服务端会和多个客户端socket连接,使用轮询的方式轮询访问socket,任意一个socket的数据准备好了都执行读取该socket的数据。使得一个进程可以快速的保持多个连接,优点是连接多。

Redis的过期策略

定时过期:每个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位记录访问频率

持久化机制

RDB redis database

默认的持久化方案,生成快照dump.rdb到磁盘中,重启时根据该文件恢复,
触发机制:save seconds changes
save 900 1
save 300 10
save 60 10000

手动触发:save命令(会阻塞),redis自身是异步持久化数据,bgsave,fork子进程生成快照,并替换原来的rdb文件。

  • 优点:恢复速度快;rdb文件紧凑,适合备份
  • 缺点:有一定延迟,不能非常精准的备份。
AOF append only file

默认不开启,需要通过配置开启
保存操作指令,也有触发机制:appendfsync
appendfsync always(每次操作都存储)
appendfsync everysecond(每秒同步一次,最常用
appendfsync no(由系统自行决定什么时候同步)
文件特别大时可以通过rewrite指令压缩,bgrewriteaof,系统根据配置参数(上次重写比例和最小大小)来重写。
重写的时候假如有新指令过来会缓存新指令,AOF重写结束后将缓存命令追加到AOF里面中。

  • 优点:安全性高
  • 缺点:恢复速度慢

相关推荐