大家好,欢迎来到IT知识分享网。
目录
一、Redis 是什么
Redis 是Remote Dictionary Server(Redis) 的缩写,是一个使用 C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型的Key-Value数据库,并提供多种语言的API。
它是一种 NoSQL(not-only sql,泛指非关系型数据库)的数据库,可以用作数据库、缓存、消息中间件、分布式锁等。
二、Redis 的特点和功能
- 性能优秀,数据在内存中,读写速度非常快,支持并发 10W QPS(每秒查询量)。
- 单进程单线程,是线程安全的,采用 IO 多路复用机制。
- 丰富的数据类型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。
- 支持数据持久化。
可以将内存中数据保存在磁盘中,重启时加载。
- 主从复制,哨兵,高可用。
- 可以用作分布式锁。
- 可以作为消息中间件使用,支持发布订阅
三、缓存和数据库数据一致性问题
分布式环境下非常容易出现缓存和数据库间数据一致性问题,针对这一点,如果项目对缓存的要求是强一致性的,那么就不要使用缓存。
我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。
合适的策略包括合适的缓存更新策略,更新数据库后及时更新缓存、缓存失败时增加重试机制,以及使用canal同步mysql到redis,具体可见如下链接:
linux 利用canal充当中间件同步mysql数据到redis_linux下canal实现mysql数据同步-CSDN博客。
四、缓存选型(Redis 和 Memcached 的区别)
Redis 和 Memcached 的区别
- 存储方式上:Memcache 会把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis 有部分数据存在硬盘上,这样能保证数据的持久性。
- 数据支持类型上:Memcache 对数据类型的支持简单,只支持简单的 key-value,,而 Redis 支持五种数据类型。
- 使用底层模型不同:它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Redis 直接自己构建了 VM 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- Value 的大小:Redis 可以达到 1GB,而 Memcache 只有 1MB
五、Redis 为什么能这么快
官方提供的数据可以达到 + 的 QPS(每秒内的查询次数),这个数据不比 Memcached 差。
- Redis 完全基于内存,绝大部分请求是纯粹的内存操作,非常迅速,数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度是 O(1)。
- 数据结构简单,对数据操作也简单。
- 采用单线程,避免了不必要的上下文切换和竞争条件,不存在多线程导致的 CPU 切换,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。
- 使用多路复用 IO 模型,非阻塞 IO。
六、Redis 缓存的淘汰策略
Redis 有六种淘汰策略,如下图:
Redis 4.0 加入了 LFU(least frequency use)淘汰策略,包括 volatile-lfu 和 allkeys-lfu,通过统计访问频率,将访问频率最少,即最不经常使用的 KV 淘汰
七、Redis 持久化
1.为什么需要持久化
比如redis里有10gb数据,突然停电或者意外宕机了,再启动的时候10gb都没了!所以需要持久化,宕机后再通过持久化文件将数据恢复。
2.Redis 的持久化策略的两种方式
- RDB(默认):快照形式是直接把内存中的数据保存到 dump.rdb 文件中,定时全量保存,保存的是数据。
- AOF:把所有的对 Redis 的服务器进行修改的命令都保存到 appendonly.aof 文件中,定时向文件中追加,保存的是命令。
3.RDB的特点
RDB性能高,速率快,全量持久化,但数据可靠性低。
(1)rdb文件
RDB(Redis DataBase):基于时间的快照,Redis默认是会以快照”RDB”的形式将数据持久化到磁盘的一个二进制文件 dump.rdb中,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前时间点之间未做快照的数据。
但是我们可以通过配置文件配置多个时间点的备份,这样就可以保留多个备份,当出现问题时候方便恢复到不同时间节点,很适合备份,并且此文件格式支持不少第三方工具可以进行后续的数据分析。比如:可以在最近24小时内,每小时进行一次备份RDB文件,并且在每个月的每一天,也备份一个RDB文件,这样的话,即便遇上问题,也可以随时将数据集还原到不同的版本,所以RDB 非常适合灾难恢复。
(2)优点
由于rdb文件都是二进制文件,所以很小,在灾难恢复的时候会快些。
他的效率(宕机恢复的效率,而不是持久化的效率)相对于aof要高(bgsave而不是save),因为每来个请求他都不会处理任何事,只是bgsave的时候他会fork()子进程且可能copyonwrite,但copyonwrite只是一个寻址的过程,纳秒级别的。而aof每次都是写盘操作,毫秒级别。没法比。
注:fork()子进程以及copyonwrite(写时复制)的详解可见文末的参考“RDB原理”
(3)缺点
4.AOF的特点
AOF数据可靠性高,增量持久化,但宕机恢复的效率相比于RDB还是略低。
(1)aof文件
AOF(Append Only File):只追加文件,使用 AOF 做持久化,每一个写命令都通过 write 函数追加到 appendonly.aof 中。而RDB是压缩成二进制等时机开子进程去干这件事。
(2)优点
①持久化的速度快,因为每次都只是追加,rdb每次都全量持久化。
②全程持久化,只需要在配置中开启 appendonly yes。这样 Redis 每执行一个修改数据的命令,都会把它添加到 AOF 文件中,当 Redis 重启时,将会读取 AOF 文件进行重放,恢复到 Redis 关闭前的最后时刻。
③数据相对更可靠,丢失少,使用 AOF 的优点是会让 Redis 变得非常耐久。可以设置不同的 Fsync 策略,AOF的默认策略是每秒钟 Fsync 一次,在这种配置下,就算发生故障停机,也最多丢失一秒钟的数据。
(3)缺点
5.项目中如何选择这两种方式
如果你追求性能,同时仍然可以承受数分钟内的数据丢失的话,那么可以使用 RDB 持久化。
如果你非常关心你的数据,并且性能对性能要求不是那么高的话,那么可以使用 AOF 持久化。
注:Redis 支持同时开启 RDB 和 AOF,系统重启后,Redis 会优先使用 AOF 来恢复数据,这样丢失的数据会最少。
八、Redis 集群模式选择
redis集群有三种模式 1.主从复制 2.哨兵模式 3.Cluster集群模式
主从复制:选取有三台(奇数)服务器,一主两从,主节点负责写入,从节点负责读取,达到读写分离,此时三台集群上的数据一致,但是有个不好的点在于 当主节点挂了的话,就需要人为操作,来重启主节点。
哨兵模式:哨兵模式在原有主从复制的基础上加了哨兵机制,简单理解就是监测各个节点活性,假如主节点挂了,还可以自动重启主节点。
Cluster集群模式:将数据均分到所有主节点上。与主从复制不同,集群中的节点不存储全量数据,而是分片存储。这种方式适合数据量较大的场景,可以均摊服务器压力
九、Redis 哨兵的基本原理
如图,是 Redis Sentinel(哨兵)的架构图。Redis Sentinel(哨兵)主要功能包括主节点存活检测、主从运行情况检测、自动故障转移、主从切换。
Redis Sentinel 最小配置是一主一从。Redis 的 Sentinel 系统可以用来管理多个 Redis 服务器。
该系统可以执行以下四个任务:
- 监控:不断检查主服务器和从服务器是否正常运行。
- 通知:当被监控的某个 Redis 服务器出现问题,Sentinel 通过 API 脚本向管理员或者其他应用程序发出通知。
- 自动故障转移:当主节点不能正常工作时,Sentinel 会开始一次自动的故障转移操作,它会将与失效主节点是主从关系的其中一个从节点升级为新的主节点,并且将其他的从节点指向新的主节点,这样人工干预就可以免了。
- 配置提供者:在 Redis Sentinel 模式下,客户端应用在初始化时连接的是 Sentinel 节点集合,从中获取主节点的信息。
哨兵的工作原理:
①每个 Sentinel 节点都需要定期执行以下任务:每个 Sentinel 以每秒一次的频率,向它所知的主服务器、从服务器以及其他的 Sentinel 实例发送一个 PING 命令。(如上图)
②如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel 标记为主观下线。(如上图)
③如果一个主服务器被标记为主观下线,那么正在监视这个服务器的所有 Sentinel 节点,要以每秒一次的频率确认主服务器的确进入了主观下线状态。
④如果一个主服务器被标记为主观下线,并且有足够数量的 Sentinel(至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断,那么这个主服务器被标记为客观下线。
⑤一般情况下,每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。
当一个主服务器被标记为客观下线时,Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率,会从 10 秒一次改为每秒一次。
⑥Sentinel 和其他 Sentinel 协商客观下线的主节点的状态,如果处于 SDOWN 状态,则投票自动选出新的主节点,将剩余从节点指向新的主节点进行数据复制。
⑦当没有足够数量的 Sentinel 同意主服务器下线时,主服务器的客观下线状态就会被移除。
当主服务器重新向 Sentinel 的 PING 命令返回有效回复时,主服务器的主观下线状态就会被移除。
十、Redis缓存雪崩、穿透、击穿概念及解决办法
雪崩场景:
如果首页所有 Key 的失效时间都是 12 小时,中午 12 点刷新的,我零点有个大促活动大量用户涌入,假设每秒 6000 个请求,本来缓存可以抗住每秒 5000 个请求,但是缓存中所有 Key 都失效了,此时 6000 个/秒的请求全部落在了数据库上,数据库必然扛不住,真实情况可能 数据库都没反应过来直接挂了,此时,如果没什么特别的方案来处理,DBA 很着急,重启数据库,但是数据库立马又被新流量给打死了。这就是我理解的缓存雪崩。
雪崩解决方案:
在批量往 Redis 存数据的时候,把每个 Key 的失效时间都加个随机值就好了,这样可以保证数据不会再同一时间大面积失效,或者设置热点数据永不过期。
穿透场景:
缓存穿透是指缓存和数据库中都没有的数据,而用户(黑客)不断发起请求,这样的不断攻击导致数据库压力很大,严重会击垮数据库
穿透解决方案:
缓存穿透我会在接口层增加校验,比如用户鉴权,参数做校验,不合法的校验直接 return,或者 使用高级用法布隆过滤器(Bloom Filter)这个也能很好的预防缓存穿透的发生。
击穿场景:
缓存击穿,这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了 DB。而缓存击穿不同的是缓存击穿是指一个 Key 非常热点,在不停地扛着大量的请求,大并发集中对这一个点进行访问,当这个 Key 在失效的瞬间,持续的大并发直接落到了数据库上,就在这个 Key 的点上击穿了缓存。
击穿解决方案:
使用互斥锁或者分布式锁来对并发请求进行控制,避免对同一资源的并发读写竞争,另外也可以使用热点数据预加载等机制来提前将热点数据加入缓存,在其失效时快速刷新缓存
参考:2W 字图解 Redis,面试必过必杀技!!
JAVA架构 | Redis分布式缓存原理分析
十三、Redis持久化之RDB原理_会飞的IT蜗牛的博客-CSDN博客_rdb
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/123209.html