为什么Redis能这么快
100000+QPS ( QPS即query per second,每秒内查询次数)
➢完全基于内存,绝大部分请求是纯粹的内存操作,执行效率高
➢数据结构简单,对数据操作也简单
➢采用单线程,单线程也能处理高并发请求,想多核也可启动多实例
➢使用多路I/O复用模型,非阻塞IO
Redis的数据类型
供用户使用的数据类型
➢String :最基本的数据类型,二进制安全
➢Hash : String元素组成的字典,适合用于存储对象
➢List :列表,按照String元素插入顺序排序
➢Set : String元素组成的无序集合,通过哈希表实现,不允许重复
➢Sorted Set :通过分数来为集合中的成员进行从小到大的排序
redis数据淘汰策略(6种,
volatile-lru:从已设置过期时间的数据集,中挑选最近最少使用 的数据淘汰
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数 据淘汰
volatile-random:从已设置过期时间的数据集中任意选择数据 淘汰
allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
allkeys-random:从数据集中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据)
怎么从海量Key里查询出某一固定前缀的Key??
1.使用KEYS指令 (不推荐)
使用keys对线上的业务的影响KEYS pattern :查找所有符合给定模式pattern的key
➢KEYS指令-次性返回所有匹配的key
➢键的数量过大会使服务卡顿
2.SCAN cursor [MATCH pattern] [COUNT count]
➢基于游标的迭代器,需要基于上一-次的游标延续之前的迭代过程
➢以0作为游标开始一次新的迭代,直到命令返回游标0完成一次遍历
➢不保证每次执行都返回某个给定数量的元素,支持模糊查询
➢一次返回的数量不可控,只能是大概率符合count参数
如何通过Redis实现分布式锁??
首先:
分布式锁需要解决的问题
➢互斥性 ➢安全性 ➢死锁 ➢容错
方法1:SETNX指令
SETNX key value :如果key不存在,则创建并赋值
➢时间复杂度: 0(1)
➢返回值:设置成功,返回1;设置失败,返回0。
如何解决SETNX长期有效的问题
EXPIRE key seconds
设置key的生存时间 当key过期时 会被自动删除
方法2
SET key value [EX seconds] [PX milliseconds] [NX|XX]
➢EX second :设置键的过期时间为second秒
➢PX millisecond :设置键的过期时间为millisecond毫秒
➢NX:只在键不存在时, 才对键进行设置操作
➢XX:只在键已经存在时,才对键进行设置操作
➢SET操作成功完成时,返回OK ,否则返回nil
如何使用Redis做异步队列??
1.使用List作为队列, RPUSH生产消息, LPOP消费消息
➢缺点:没有等待队列里有值就直接消费
➢弥补:可以通过在应用层引入Sleep机制去调用LPOP重试
2.pub/sub :主题订阅者模式
➢发送者(pub)发送消息,订阅者(sub)接收消息
➢订阅者可以订阅任意数量的频道
缺点:消息的发布是无状态的 无法保证可达
Redis如何做持久化??
1.RDB (快照)持久化:保存某个时间点的全量数据快照
➢SAVE :阻塞Redis的服务器进程,直到RDB文件被创建完毕
➢BGSAVE : Fork出一一个子进程来创建RDB文件,不阻塞服务器进程
RDB持久化缺点
➢内存数据的全量同步,数据量大会由于I/O而严重影响性能
➢可能会因为Redis挂掉而丢失从当前至最近一-次快照期间的数据
2.AOF ( Append-Only-File )持久化:保存写状态
➢记录下除了查询以外的所有变更数据库状态的指令
➢以append的形式追加保存到AOF文件中(增量)
AOF持久化
日志重写解决AOF文件大小不断增大的问题,原理如下:
➢调用fork() ,创建一个子进程
➢子进程把新的AOF写到一一个临时文件里,不依赖原来的AOF文件
➢主进程持续将新的变动同时写到内存和原来的AOF里
➢主进程获取子进程重写AOF的完成信号,往新AOF同步增量变动➢使用新的AOF文件替换掉旧的AOF文件
RDB和AOF的优缺点:
➢RDB优点:全量数据快照,文件小,恢复快
➢RDB缺点:无法保存最近一次快照之后的数据
➢AOF优点:可读性高,适合保存增量数据,数据不易丢失
➢AOF缺点:文件体积大,恢复时间长
使用RDB-AOF混合持久化方式
BGSAVE做全量持久化 AOF做增量持久化