Redis学习之路
redis
基本概念:Redis(Remote Dictionary Server),即远程字典服务,是基于内存的(Mysql基于硬盘),Key-Value数据库,是NoSQL(非关系型数据库)。
-
支持的数据类型
Key
仅支持String
类型,而Value
支持多种类型:String
:采用类似数组的形式储存。List
:双向链表实现。Hash
:基于拉链法实现,储存时将index
和00000011
相与,去最后两位,以防超出限制。Set
:不重复的集合。Sorted Set
:多了一个权重参数score
,集合内元素能够按score
进行排列。
-
持久化
RDB
(Redis DataBase):把目前redis
内存中的数据,生成一个快照(RDB文件),保存在硬盘中,如果发生事故,redis
可以通过RDB
文件,进行文件读取,并将数据重新载入内存中,是一种全量备份。- 可手动触发(
save
命令、bgsave
——会fork
一个子进程去执行) - 可自动触发(配置文件写入save m n,代表m秒内发生n次变化,会自动执行bgsave)。
- 可手动触发(
AOF
:记录之后所有对redis
数据进行修改的操作。如果发生事故,redis
可以通过AOF
文件,将文件中的数据修改命令全部执行一遍,一次恢复数据。AOF
重写,根据当前Redis
数据状态生成新AOF
文件,替换原本冗余的AOF
文件。可手动触发:bgrewriteaof
或自动触发:配置文件设置appendonly yes
开启。
-
缓存
-
缓存淘汰:
三种算法:先进先出FIFO、最近最少使用LRU(可以双向链表+哈希表实现:当某个key被访问到了,程序通过哈希表迅速定位节点,并将该节点移至链表开头)、最不经常使用LFU。
-
过期删除:
- 主动删除:设置删除时间间隔,在指定时间后进行主动删除工作。
- 惰性删除:程序取值时查看该数据是否过期,如果没过期,则返回;如果过期,则删除。
- 定期删除:每隔一段时间,执行主动删除,不跑主动删除时,则执行惰性删除。
-
缓存一致(Cache Aside)
-
**缓存击穿:**查询某个数据的值,该值不在缓存中,在数据库中有。
解决方法:
- 从MySQL出发,加锁,减少击穿后的直接流量
- 从Redis出发,设置热点数据永不过期,或热点数据后台启动一个一步线程,重新把数据回填缓存层
-
**缓存穿透:**查询一个缓存和数据库都不存在的数据。
解决方法:
- 对数据库访问前进行校验,对数据库拦截非法查询请求。
- 对于经常被访问的,并且数据库中没有的键,缓存层记录键 = null。
- 布隆过滤器:设置k个各不相同的hash映射函数,把在数据库中的有效数据通过这个映射函数得到数组指定位置,并置为1。当输入查询数据的时候,计算这k个hash函数,如果有一位是0,则一定是无效查询。
-
**缓存雪崩:**一大批被缓存的数据,同时失效,这批数据请求全部打到数据库,导致宕机。可以看作多条数据的缓存击穿。
解决方法(和缓存击穿类似):
- 从MySQL出发,加锁,减少击穿后的直接流量
- 从Redis出发,设置热点数据永不过期,或热点数据后台启动一个一步线程,重新把数据回填缓存层
- 分析失效时间,尽量让失效时间点分散
- 对于集群部署的情况,将热点数据分布在不同缓存中
-
-
集群
-
主从复制:
有主库(Master)节点和从库(Slave)节点两个角色,写操作作用于主库,读操作作用于从库(可多加几台从库),读写分离。
-
全量复制:主库执行
BGSAVE
,生成对应的RDB文件,同时开辟缓存区,是为了记录在RDB文件实行过程中,收到的新数据命令。RDB文件产生后,主库发给从库,从库通过RDB恢复数据。后面主库会把数据变更命令发给从库,从库收到后执行。 -
断线后重复制:需确定以下信息
- 服务器运行id:唯一确定主库身份,以防更换了主库,更换了以后只能全量复制
- 复制偏移量:从主节点传输了的字节数
- 复制积压缓冲区:这里储存的是最近主节点的数据修改命令
-
-
哨兵机制:
建立哨兵组(不提供数据服务的
redis
服务器),对主库从库统一进行监控,如果主库坏了,哨兵组进行投票,从从库中重新选出主库。每个哨兵每十秒向主库、从库和其他哨兵发送
ping
,若有哨兵发现主库连接不上,会将其主观下线,并通知其他哨兵ping
。若超过半数连接不上,则将其客观下线,执行故障转移,在从库中选个新主库(会选一个老大哨兵,主持新主库的选举)。若老主库重新上线,则退化为从库。
-
Cluster集群:
自动将你的数据切分给多个节点储存,及时这些节点中一部分宕机,也可以继续执行数据操作。
分区策略:所有键通过CRC16校验函数,对16384取模,分配到不同槽位,每个
redis
的cluster
节点负责一部分槽数据的储存。查询策略:每个节点都会储存整个集群节点信息,这些信息也被称为元信息。如果执行
get
操作,节点先验证该key
对应的槽编号是不是归本节点关,如果是则保存数据,否则发送正确的节点编号给客户端。
-