缓存淘汰策略
reids服务器繁忙时,有大量信息要保存,如果Redis服务器内存全满,再要往Redis中保存新的数据,就需要淘汰老的数据,才能保存新数据
noeviction: 返回错误(默认)
allkeys-random: 所有数据中随机删除数据
volattile-random: 有过期时间的数据库中随机删除数据
volatile-ttl:删除剩余有效事假那最少的数据
allkeys-lru:所有数据中删除上次使用时间最久的数据
volatile-lru:有效期时间的数据中删除上次使用时间最久的数据
allkeys-lfu: 所有数据中删除使用频率最少的
volatile-lfu: 有过期时间的数据中删除使用频率最少的
缓存穿透:
从数据库查询出的数据可以保存在redis中,下次查询时直接从redis中获取,大幅提高响应速度,提高系统性能.
所谓缓存穿透就是查询了一个数据库中都不存在的数据,redis中没有这个数据,在数据库中查找也没有这个数据,如果这样的请求多了,那么数据库压力就会很大,我们使用向redis中保存null,来防止一个查询反复穿透,但是这样的策略有问题,
如果用户不断更换查询关键字反复穿透也是对数据库性能极大的威胁,使用布隆过滤器来解决这个问题
事先创建好布隆过滤器,可以在进入业务逻辑层时判断用户查询的信息数据库中是否存在,如果不存在于数据库中,直接终止查询返回,
缓存击穿:
正常运行的情况我们设计的应该在redis中保存的数据如果有请求访问到redis而redis没有这个数据,导致请求从数据库中查询,这种现象就是缓存击穿
但是这个情况也不是异常情况,因为我们大多数数据都需要设置过期时间,而过期时间到时这些数据一定需要从数据库中同步, 所以击穿只是这个现象的名称,并不是不允许
缓存雪崩
上面讲到击穿现象,同一时刻少量击穿是正常的,但是如果出现同一时间发生大量的击穿,就会导致雪崩
这种情况下,mysql会在短时间出现很多新的查询请求,这样就会发生性能问题,如何避免这样的问题?
因为出现这个问题的原因通常是同时加载的数据设置了相同的有效期,我们需要在设置有效期时添加一个随机数,大量的数据就不会同时失效了
redis持久化
redis将信息保存在内存中,内存的特征就是一旦断电,所有信息都丢失,redis来讲,所有数据丢失,就需要从数据库中重新查询所有数据,这个查询是慢的,更有可能redis本身是有新数据的还没有和数据库同步就断电了,所以redis支持了持久化方案
在当前服务器将redis中的数据保存在当地硬盘上,
redis恢复策略有两种:
RDB: 数据库快照,将当前数据库转换为二进制的数据,保存在硬盘上,redis生成一个叫做dump.rdb的文件,我们可以在redis安装程序的配置文件中进行配置,
空白位置编写如下内容
save 60 5
60 表示秒数,即一分钟,
5 表示key被修改的次数
配置效果:1分钟内如果有5个key以上被修改就启动rdb数据库快照程序
优点:
因为是整体redis数据的二进制格式,数据恢复是整体恢复的
缺点:
生成的rdb文件是一个硬盘上的文件,读写效率低
如果突然断电,只能恢复最后一次生成的rdb中的数据
AOF: AOF策略是将redis运行过得所有命令(日志) 备份下来,这样即使信息丢失,我们也能根据运行过得日志,恢复为断电前的样子,
它的配置如下
appendonly yes
它的特点: 只保存命令不保存数据
理论上redis运行过得命令都可以保存下来,但是实际情况下,redis非常繁忙的时候,我们会将日志命令缓存之后,整体发送备份,减少IO次数,以提高日志备份的性能,和对redis性能的影响
实际开发中,配置一般会采用每秒将日志违建发送一次的策略.断电最多丢失一秒数据
为了减少日志大小redis支持AOF rewrite 将一些已经进行删除的数据的新增命令也从日志中移除,达到减少日志容量的目的,
Redis存储原理
redis将内存划分为16384个槽(类似hash槽),将数据(key) 使用CRC16 算法计算出槽值在0-16383之间,将数据存储到这个槽中
当再次使用这个key计算是,直接从这个槽获取,大幅提高查询效率
redis集群
最小状态reids是一台服务器,这台服务器的状态直接决定了redis的运行状态,如果它宕机了,那么redis服务就没了,系统面临崩溃的风险
我们可以在主机运行时使用一台备用机,
主从复制
也就是主机(master)工作时,安排一天备用机(slave)实时同步数据,万一主机宕机,我么可以切换到备用机运行
缺点: 这样的方案,slave节点没有任何实质的作用,只要master不宕机,它就形同虚设,没有体现价值
读写分离
这样slave在master正常工作时也能分担master工作了,但是如果master宕机,实际上主备机的切换还是需要人工介入的,这还是需要时间的,那么如果想实现故障时自动切换,一定是有配置好的固定策略的,
哨兵模式: 故障自动切换
哨兵节点每隔固定时间向所有节点发送请求,如果正常响应认为节点正常,如果没有响应,认为该节点出现问题,哨兵能自动切换主备机,如果主机master下线,自动切换到备用机运行
但是这样的模式存在问题 :
但是如果哨兵判断节点状态时发生了误判, 那么就会错误的将master下线,降低整体运行性能,我们可以将哨兵节点做成集群,由多个哨兵投票来决定是否下线某个节点
哨兵集群中,每个节点都会定时想master和slave发送ping请求,如果ping请求有2个(集群得半数节点以上)以上的哨兵节点没有收到正常的响应,会认为该节点下线
分片集群
当业务不断扩展,并发不断增高时,有可能一个Master节点做写操作性能不足,成为了系统性能的瓶颈,这是就可以部署多个master节点,每个节点支持主从复制,只是每个节点负责不同的分片,
例如: redis16384个槽位,master1 负责0-5000,master2负责5001-10000,master3负责10001-16393,一个key根据CRC16算法,只能得到固定的结果,一定在指定的服务器上找到数据;
有了这个集群结构,我们就能更加稳定和更加高效的处理业务请求了
- 为了节省哨兵服务器的成本,有些公司在redis集群中,直接添加哨兵功能,即master\slave节点完成数据任务的同时也互相监测他们的健康状态