目录
Redis
一 特点
优
- Redis直接操作内存,因此速度快;
- 支持的数据类型丰富,如:String,Hash,List,Set,Zset;
- 事物支持原子性,要么全改,要么不改。
劣
- 受物理内存的制约,不支持大数据的高性能读写。
二 缓存方案
1. 数据读取
用户读取数据:
a . 先拿入参生成对应的Key值,再拿Key去Redis中查询缓存;
b. 若存在缓存,则直接返回缓存;
c .若不存在,访问数据库,将查询结果写入缓存,并返回数据。
2. 缓存更新策略
用户更新数据:
Cache Aside Pattern
当数据更新时,先修改数据库成功后将缓存失效。
为何不先让缓存失效在修改数据库?
因为在多线程操作时,假设一个Read Thread和一个Write Thread。WT先进来让缓存失效,还未更新数据库时,
RT进来读到了Drity Data,然后将其写入缓存。WT更新完数据库后也未对缓存进行操作,那缓存将会一直Drity下去。
Read/Write Through Pattern
Read:读取时命中缓存就取缓存数据,没有命中就访问数据库,再将数据库数据写入缓存;
Wirte:命中缓存则同步的修改缓存,再更新数据库,没命中则直接更新数据库。(与Cache Aside不同)
Write Behand Cacheing Pattern
更新数据的时候不更新数据库,只更新缓存,再让缓存异步的批量更新数据库。可以让数据I/O的飞快,但是数据不是强一致性的,可能会让数据丢失。
三 持久化
由于Redis的数据都存储在内存中,在Redis重启后就会失效。因此需要持久化,将数据存储在磁盘中,重启后将数据恢复。
RDB快照
在指定的时间间隔内将内存中的数据快照写入磁盘。先fork一个子进程(Bgsave1)来将数据生成数据快照,主进程依然可以处理请求,当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
优点:
- RDB文件便于传输转移数据;
- 效率高;
- 易于恢复数据(每小时存一天的,每天存一个月的)。
缺点:
- 定时持久化之前的数据在宕机后会丢失;
- 当数据集较大时,fork时会阻塞。
AOF日志
以追加的形式将更新删除的操作日志写入文本文件当中(不记录查询日志)。
优点:
- 数据安全性高,Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其 效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变 化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的;
- AOF文件是以追加的形式写入磁盘,因此在写入时宕机也不会影响已存在的内容,也可使用redis-check-aof工具修复;
- AOF文件易读。
缺点:
- AOF写入频繁效率较慢;
- 相同数量级的情况下,AOF文件大于RDB文件,因此数据恢复较慢。
四 运行模式
主从模式(Master-Slave)2.8版本之前
一般Read操作的压力比Write大,为分担Read的压力提高Redis性能将Read与Write操作分割开来,由Master进行读、写操作,而Slave只负责Read。
主从复制
当启动一个Slave连接之后,Master会生成RED文件且会在缓存区记录接下来的命令,然后将RED文件发送给Slave,Slave写入磁盘再再加载到内存,最后Master再将缓存区的命令发送至Slave实现数据同步。(若Slave是第一次连接则是全量的RED文件,不然只复制缺失的文件)。
优点:
- 解决数据备份问题;
- 分担Read压力,提高性能。
缺点:
- 服务宕机需手动重启,若主机宕机,从机全部宕机;
- 不支持动态扩容。
哨兵模式(Sentinel)2.8版本之后
与主从搭配使用,设置哨兵来监控主机,若主机宕机则将从机设为主机,主机重新启动成为从机,弥补主从模式的不足。
优点:
- 弥补主从模式的不足,宕机可以快速恢复。
缺点 - 从节点宕机不会触发哨兵机制,连着从节点的服务器缓存失效;
- 无法实现动态扩容。
Cluster模式 3.0版本
部署一个Redis集群,存在主机与从机。任意节点之间都是相通的,用户连接一个节点可以访问所有的节点。
投票机制
集群通过ping-pong来判断节点是否宕机,当半数的Master节点去ping该节点超时,则认为该节点fail(==投票机制==),
启动它的Slave。
集群fail
a. 集群任意Master宕机且无Slave;
b. 集群半数Master宕机,无论存不存在Slave。
优点:
- 分布式负载均衡;
- 实现动态扩容;
- 去中心化。
五 缓存异常机制
缓存击穿
热点Key的并发访问量很大,当它失效时,导致大量请求直接访问数据库,导致数据库宕机。
解决方法:热点Key设置不过期。
缓存穿透
恶意攻击故意用很大的并发量访问数据库中不存在的数据,绕过缓存直接对数据库造成负荷。
解决方法:
- 查询数据库不存在的数据,将空值放入缓存(设置过期时间小,30s的样子);
- 将不合理的入参直接拦截。
缓存雪崩
大片Key同时失效,导致数据库访问量增大。
解决方法:
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中。
- 设置热点数据永远不过期。
若是手动调用RDB,可以选择save(会阻塞Redis进程直到持久化完成)或者Bgsave(会fork出一个分支来进行持久化的操作,阻塞发生在fork的时候)。 ↩︎