目录
前言
上一篇我们完成了对Redis的入门了解以及Redis的基本数据类型。这里我们引出一个问题,那么既然Redis是基于内存的,那当我们的服务器重启后,Redis中的数据就都消失了,如果我们希望重启后数据还能够存在的话,就需要持久化到磁盘上,Redis重启后从磁盘上再把信息读取回来。
一、Redis持久化的方式
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
RDB持久化
RDB持久化方式也叫快照持久化方式,Redis 可以通过创建快照来获得存储在内存⾥⾯的数据在某个时间点上的副本。Redis 创建快照 之后,可以对快照进⾏备份,可以将快照复制到其他服务器从⽽创建具有相同数据的服务器副本 (Redis 主从结构,主要⽤来提⾼ Redis 性能),还可以将快照留在原地以便重启服务器的时候 使⽤。
简单来说,RDB持久化方式就是在一定的时间间隔内,将Redis中的数据集快照写入到磁盘中。
RDB的过程:redis会单独创建fork一个子进程来进行持久化操作,先将数据写到一个临时文件中,等持久化过程都结束了,再用这个临时文件替换原文件。整个过程中,主进程是不进行IO操作的,保证了性能。但是缺点是最后一次持久化的内容可能会丢失。
RDB持久化方式是Redis默认的持久化方式,在Redis.conf文件中有如下配置。
save 900 1 #在900秒(15分钟)之后,如果⾄少有1个key发⽣变化,Redis就会⾃动触发
BGSAVE命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果⾄少有10个key发⽣变化,Redis就会⾃动触发
BGSAVE命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果⾄少有10000个key发⽣变化,Redis就会⾃动
触发BGSAVE命令创建快照。
AOF持久化
appendonly yes
appendfsync always #每次有数据修改发⽣时都会写⼊AOF⽂件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步⼀次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进⾏同步
AOF重写
我们知道,AOF的持久化方式在于Redis会把对数据进行修改操作的指令都存到一个AOF文件中来实现。那么这个AOF文件肯定是不能够无限增大的,想象一下,一个AOF文件里有成千上万条指令,别说人了,机器估计都看的眼花缭乱吧哈哈哈。
那么AOF文件既然要保存所有的指令,就说明我们不能丢弃掉以前的指令,那我们怎么控制日益庞大的AOF文件呢。
答案是通过 AOF压缩重写机制来进行。
意思是,当我们进行AOF文件的重写时,会将整个AOF文件的指令压缩成一条指令,然后放到我们新的AOF文件中,然后用新的AOF文件替换原来那个。
默认情况下,当我们当前的AOF文件大于上一次AOF文件一倍且大于64M的时候,就会自动执行重写压缩操作。
在执⾏ BGREWRITEAOF (重写)命令时,Redis 服务器会维护⼀个 AOF 重写缓冲区,该缓冲区会在⼦
进程创建新 AOF ⽂件期间,记录服务器执⾏的所有写命令。当⼦进程完成创建新 AOF ⽂件的⼯
作之后,服务器会将重写缓冲区中的所有内容追加到新 AOF ⽂件的末尾,使得新旧两个 AOF ⽂
件所保存的数据库状态⼀致。最后,服务器⽤新的 AOF ⽂件替换旧的 AOF ⽂件,以此来完成
AOF ⽂件重写操作
Redis事务
终于到了事务部分啦,Redis作为一个数据库,而且是当下如此热门使用的情况下,如果没有事务的存在,那将会丢失掉十分多重要的数据!!
Redis事务不同于我们熟知的MySQL事务的ACID原则,Redis不支持事务的回滚,所以Redis没有原子性和持久性。
二、Redis可能会产生的问题
缓存穿透
缓存穿透,顾名思义,可以理解为,外界的请求穿透了Redis,直接流入到了我们后端的数据库中
简单的说,就是请求的Key在Redis中查找不到,那当然就要到我们的数据库中去找啦,那如果这样请求的Key非常非常多,我们就要多次在数据库中找,那我们设置缓存的意义就没有了,数据库表示我顶不住呀。
解决方案:
- 对空值做缓存。
- 设置可访问的名单(白名单)
- 采用布隆过滤器
- 对redis进行实时监控,当发现redis命中率降低的时候,设置黑名单拦截请求
布隆过滤器
缓存雪崩
缓存雪崩指的是Redis突然不可用了 有可能是因为Redis服务器宕机了,也有可能是因为我们缓存的Key突然在同一时间过期了,这样请求也会大量流入到我们的数据库中,数据库表示,怎么受伤的总是我。。。
所以对于缓存雪崩的两种场景,我们有不同的解决方案
1.Redis服务器不可用时
如果是Redis服务器整个不可用了,我们可以考虑对Redis服务器进行主从搭配,或者集群,并且使用哨兵进行监控,使得当前Redis服务器不可用能有其他服务器及时顶住。
提一嘴 Redis的哨兵监控是会不间断的向主服务器发送检测数据,一旦发现主服务器挂了,立刻安排小弟上位,做新的服务器。
2.Redis的Key同一时间大量失效。
那这不就简单了嘛 我们可以设置不同的时效时间,不要让大家一起挂掉就好啦
或者,我们干脆不设置过期时间,所有Key都是永久存在的!!(强烈不建议)
三、Redis分片集群
最后,讲一下Redis分片集群相关的知识吧。
呃,这一段由于我自己了解的也不多,能力有限,就自己讲一下自己的心得和了解,如果有错误的地方,还往各位道友帮我指正,感激不尽!!!
我们都知道,把数据全部放在一台服务器上是很不安全的,万一服务器挂掉了,且不说数据有流失的风险,我们整个服务都会无法进行,所以多服务器的集群部署,可以使我们的后端服务更加安全
那么我们都知道,Redis的节点一共16384个,我们搭建了集群环境后,应该如何分配节点呢。
哈希取余法
哈希取余法,顾名思义,就是我们通过key值进行hash函数的运算,然后对我们集群环境中Redis服务器的数量进行取余,然后判断这个数据改放到那个服务器中,这样是最简单暴力的方法,但是他也是最不好用的办法。因为当我们的服务器增加或者减少后,我们所有的数据都要进行重新的运算和分配,这是一笔巨大的开销,我们不用它!!
一致性哈希算法
一致性哈希算法的原理就是,我们把哈希空间(原本是一个数组的样子)我们把他的头尾相连,形成一个哈希环。
然后,我们服务器的节点就根据哈希函数的运算分布在整个环之上(不均匀的分布喔),然后在进行数据的存储的时候,数据通过哈希函数的运算,找到在哈希环上的位置,然后顺时针绕环走,碰到的第一个服务器,就是它存储的服务器了。
一致性哈希环相比哈希取余法好在,即使我们服务器有增加或者减少,影响的只是它相邻两个服务器的数据,恩,不用那么大动干戈地让全世界人都知道啦。
那如果我还是觉得这样不好,移动起来麻烦,再加上服务器不能均匀分布,造成很多服务器挤在一起,别的服务器孤零零一个人在角落怎么办!!
少年你要求真多啊,不过我们还是有办法滴,办法来自于Redis 3.0引入的哈希槽(slot)。
哈希槽分区法
哈希槽是什么东东嘞,用简单通俗一点的语言来讲,哈希槽就是在我们的Redis服务器之上,多了个盒子,数据是放在这个盒子里的,而不是放在服务器中的,盒子会通过配置文件地址将数据的地址映射到服务器上,所以呀,Redis服务器里面相当于没有这个数据,有的只是这个数据的地址。
那可就好办了,我们可以通过自己的所求所需,我们自己来为集群环境中的Redis服务器设置插槽的大小,数据要进来,我们对他进行哈希函数的取余运算,知道它要去到哪个槽后,我们把它放进去就行了。而如果要增加服务器或者减少服务器,我们只需要来转移哈希槽给其它的服务器,就可以完成数据的转移,是不是方便很多了嘞,嘿嘿。
总结
本篇文章重点讲了Redis的持久化操作,以及Redis在实际使用中可能会碰到的问题以及解决方案。最后我们还了解了一丢丢集群分片的相关知识。还是那句话,有错误,请不吝赐教,我很开心看到不同的见解,因为我本身就是个小菜鸟,我希望获取更多的知识。