首页 > 自考资讯 > 高考百科

Redis原理介绍(Redis备份与恢复原理)

小条 2024-06-27

一、什么是Redis

Redis(远程字典服务器)是一个用C 编写的开源(BSD 许可)高性能非关系(NoSQL)键/值数据库。

二、数据类型

1)String(字符串)

字符串是Redis中最基本的类型,可以理解为一个键对应一个值。数据类型“String”非常简单,对应于字符串数据结构。字符串是Redis中最基本的数据类型,字符串值最大可以存储512MB。

2)List(列表)

列表该数据类型支持存储一组数据。相应的实现有两种:压缩列表(ziplist)和双向循环链表。如果列表存储的数据量比较小,可以通过压缩列表的方式来实现。必须满足以下条件:列表中存储的一条数据(可以是字符串类型)必须小于64字节,并且列表中的数据数量必须小于512字节。说到压缩列表,它并不是一个基本的数据结构,而是Redis自己设计的一种数据存储结构。

3)Hash(字典或哈希)

在Redis 中,哈希值称为字典。 Redis 字典使用哈希表作为底层实现。哈希表有多个哈希表节点,每个哈希表节点都在字典中存储键值对。字典类型用于存储数据对集。每个数据对包含两部分:键和值。实现字典类型也有两种方法。一种是压缩列表,另一种是哈希表。 Redis仅在存储的数据量较小时才使用压缩列表来实现字典类型。具体来说,必须满足两个条件。字典中存储的键和值的大小必须小于64字节。字典中键值对的数量必须小于512字节。如果以上两个条件不同时满足,Redis会使用哈希表来实现字典类型。 Redis的哈希函数采用MurmurHash2,这是一种执行速度快、随机性好的哈希算法。对于哈希冲突问题,Redis使用链表的方法来解决问题。此外,Redis还支持哈希表的动态扩展和收缩。通过Redis哈希,当存在多个具有相同键映射值的键值对时,系统以单链表的形式存储这些键值。根据哈希表占用的内存大小,Redis采用双哈希表ht[2]结构逐步扩展哈希表容量的策略。 【注】保存前,每个键值对都会计算其值,并以类似于HASH(key) MOD N 的方式确定其在哈希表中对应的位置。

36f430d3298c49c28605104c11cff42b~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=3DnPwXgH8jTYGb3Qy8q%2F1%2F2yy34%3D

4) Set(集合)

该数据类型用于存储唯一的数据集。该数据类型也有两种实现方式,一种基于有序数组,一种基于哈希表。 Redis 使用满足两个条件的有序数组:所有存储的数据都是整数,存储的数据元素数量不超过512。如果不满足上述条件,即存储的数据量很大,Redis会使用哈希表将数据存储在集合中。

5)Zset(sorted set:有序集合)

Redis 排序集的使用场景与集合类似,只不过集合不会自动排序,而排序集允许用户指定一个额外的优先级(分数)参数即可排序,即自动排序。如果您想要不同集合的有序列表,则可以选择排序集合数据结构。 【如何实现】Redis有序集内部使用HashMap和SkipList来保证数据的存储和排序。另一方面,跳过列表将所有成员保存在排序条件中。 HashMap:跳表结构,搜索效率较高,实现起来相对容易。事实上,与Redis 中的其他数据类型一样,有序集合并不局限于跳跃列表。当数据量比较小时,Redis使用压缩列表来实现有序集合。要使用压缩列表实现有序集,所有数据的大小必须小于64 字节,并且元素的数量必须小于128 字节。

三、Redis的持久化机制

1)RDB

RDB持久化是指在指定时间间隔内将内存中数据集的快照写入磁盘。实际操作过程中,会fork出一个子进程,首先将数据集写入临时文件。如果写入成功,则替换之前的文件,并以二进制形式压缩并保存。 Redis 的默认模式。

07ceb2121983408badc2e251a3bc5daf~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=pj5lWgV6XnzUtdxMFDGf25sXhpA%3D

RDB优势

用于备份:此方法非常适合备份文件,因为整个Redis 数据库仅包含一个文件。方便的数据恢复:RDB是灾难恢复非常好的选择。因为您可以轻松地压缩单个文件并将其传输到其他存储介质。最大化性能:对于Redis服务进程,启动持久化所需要做的就是fork出子进程。然后子进程完成持久化工作。这很大程度上避免了运行服务进程。IO操作完成。与AOF相比数据量小:与AOF机制相比,当数据集较大时RDB启动效率较高。

RDB劣势

数据完整性和一致性不高:如果系统在计划持久化之前崩溃,则任何未来得及写入磁盘的数据都将丢失。备份时占用的内存:Redis在备份时会创建自己的子进程,将数据写入临时文件(此时内存中的数据是原来大小的两倍),最后用临时文件替换备份文件。因此,在半夜进行Redis持久化和数据恢复更有意义。

RDB持久化配置

Redis 将数据集的快照转储到dump.rdb 文件。此外,您可以通过配置文件更改Redis 服务器转储快照的频率。打开6379.conf文件后,搜索save找到如下配置信息:

save 900 1 #如果900 秒(15 分钟)后至少有一个键发生更改,则转储内存快照。 save 300 10 #如果至少有10个键发生了变化,则在300秒(5分钟)后转储内存快照。 save 60 10000 #如果60秒(1分钟)后至少有10000个键发生更改,则转储内存快照。除了上述设置触发RDB持久化之外,还有以下默认方法:

运行save(阻塞,仅保存快照,等待其他操作)或bgsave(异步)命令。执行flushall命令清除数据库中的所有数据。这没有多大意义,但运行shutdown 命令以确保服务器正常关闭。而不丢失数据。

2)AOF

AOF 持久性记录服务器处理的所有写入和删除操作。查询操作不被记录。您可以打开该文件查看详细的操作记录。

11905a7b06b440ac968d27ad49ae8bd6~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=stVah%2BDvI4kEzl5m15jhSjcmst8%3DRedis AOF 默认关闭。您必须手动将“否”更改为“是”才能生效。

# 开启appendonly yes # 指定文件名appendfilename 'appendonly.aof'

AOF的优势

更高的数据完整性和一致性:Redis支持3种同步:每秒同步、每次更改同步,异步提供两种同步策略。事实上,同步也每秒异步完成,因此非常高效。唯一的区别是,如果系统宕机,这一秒内修改的数据就会丢失。每当更改同步时,您都可以将其视为同步持久性。这意味着发生的所有数据更改都会立即记录到磁盘上。

AOF的劣势

占用磁盘空间大,数据恢复慢:对于相同数量的数据集,AOF 文件通常比RDB 文件大。恢复大型数据集时,RDB 比AOF 更快。运行效率低、同步频繁:根据同步策略的不同,AOF在运行效率上往往慢于RDB。即同步策略的每秒效率较高,同步禁用策略的效率与RDB相当。

AOF持久化配置

同步Redis配置文件的方式有3种。

appendfsyncalways #每次发生数据更改时都会写入AOF文件。 appendfsync everysec #1 每秒同步。该策略是AOF 的默认策略。 appendfsync no #不同步。高效,但不保留任何数据。

RDB与AOF如何选择

一般来说,如果你想达到相当于PostgreSQL的数据安全性,你应该同时使用两种持久化方法。虽然很多用户只使用AOF持久化,但并不推荐这种方法。定期生成RDB快照(快照)对于数据库备份非常有用,而且RDB恢复数据集比AOF恢复更快。

四、Redis三种集群模式

安装部署:https://www.cnblogs.com/liugp/p/12591721.html

1)主从模式

主从复制模式包括一个主数据库实例(master)和一个或多个从数据库实例(slave)。数据复制是单向的,只能从主节点到从节点。它通常是只读的,如下所示。

如果多个从机断开连接并需要重新启动,只要从机启动,就会发送同步请求,它们将与主机完全同步。如果同时出现多个从站,主站IO 停机时间会迅速增加。

配置Redis主/从复制非常简单,并且允许从服务器成为主服务器的精确副本。 Redis主从复制需要明确几个重要点。

Redis 使用异步复制。然而,从Redis 2.8开始,除了连接到单个主服务器的多个从服务器之外,从服务器将定期响应复制流中正在处理的数据量。服务器,还可以将多个从服务器连接到单个从服务器,形成类似图形的结构。 Redis主从复制不会阻塞主服务器。这意味着当多个从服务器进行初始同步时,主服务器可以继续处理请求。主从复制不会阻塞从服务器端。当从服务器执行初始同步时,它使用旧版本的数据来响应查询请求。可用于提高可扩展性。它可以用来处理使用多个从服务器的只读请求(例如,可以在一个从服务器上执行大型排序操作),或者只是为了数据冗余。

1、特点

是Redis 2.8版本中引入的,引入了哨兵的概念。 Redis Sentinel 是社区版本原生高可用解决方案的部署架构由两个主要部分组成:Redis Sentinel 集群和Redis 数据集群。

Redis Sentinel 集群是由多个Sentinel 节点组成的分布式集群,提供故障检测、自动故障转移、配置中心和客户端通知等功能。 Redis Sentinel 节点的数量必须是2n+1 (n=1) 的奇数。d99346280a14476f9d95457fe9add59e~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=Fq52sJmTelRqEVx8T6FWpPyrsMw%3D

2、工作机制

当主站宕机时,Sentinel 选择其中一个从站作为主站并更改其配置文件。例如,slaveof属性指向新的master。重启后,它将不再是Master,而是作为Slave接收新Master的同步数据。由于Sentinel也是进程,可以挂起,所以Sentinel也会启动多个Sentinel,组成一个Sentinel。当配置多个Sentinel时,它们会自动相互监视。如果主从模式配置了密码,Sentinel会同步更改配置信息。一个Sentinel集群可以管理多个主/从Redis,也可以同时被多个Sentinel监控。最好不要将redissentinel与Redis部署在同一台机器上。否则Redis服务器挂掉后,Sentinel也会挂掉。

3、优点

每个Sentinel 每秒向主站、从站和其他已知Sentinel 实例发送一次消息。发送PING 命令。如果自上次对PING 命令有效响应以来的时间超过了“Down After Milliseconds”中指定的值。如果您选择该选项,该实例将被哨兵主观标记为离线。当一个master被标记为主观离线时,所有监控该master的sentinel都会注意到,如果有足够数量的sentinel(大于或等于指定的值),则该master实际上被标记为主观离线,必须检查一次。每一秒。配置文件),如果在规定的时间范围内确认master确实进入了主观下线状态,一般情况下master会被标记为客观下线,并且每个sentinel都会发送消息给slave。 INFO 命令每10 秒识别一次。当某个master被sentinel客观标记为下线时,sentinel向该下线master的所有slave发送INFO命令的频率从每10秒一次变为每秒一次。如果没有足够多的Sentinel 同意Master 已下线,则Master 会取消客观下线状态。如果Master对Sentinel的PING命令返回有效响应,则Master的主观离线状态被移除。 1010高可用:主从自动切换,系统可用性更高。实现多个节点组的监控:您可以实现一组Sentinel来监控一组Redis数据节点或多个数据节点组。

4、缺点

部署复杂:部署比Redis主从模式更复杂,原理更难理解。资源浪费:Redis数据节点的Slave节点作为备份节点,不提供服务。默认不支持读写分离。读写分离的问题无法解决,而且实现起来相对复杂。维护成本高:必须维护另一套监控节点。 Redis难以支持在线扩容:对于集群来说,一旦达到容量,在线扩容就变得非常复杂。

5、主从同步原理

前两种模式所有数据都在一个节点上,且单个节点存在存储限制。在集群模式下,当一个分片的数据达到上限时,数据会被分割到多个分片上。 Redis3.0加入Redis集群模式,通过对数据进行分片,将不同的数据存储在不同的主节点上,实现大规模数据的分布式存储和在线扩展。

Redis Cluster集群模式通常具有高可用、可扩展、分布式、容错等特点。最小Redis Cluster集群节点配置大于6个节点(3主3从)。主节点提供读写操作,从节点作为备份节点,不服务请求,仅用于使用。用于故障转移。 Redis集群使用虚拟槽分区,每个键根据哈希函数映射到0到16383之间的整数槽,并维护该槽的一部分以及该槽映射的键值数据。

PJc%3D" alt="d911a65b0aac410dbf0fd70d4d7cf169~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=bzhodlcNaLFRLvqHNJL5RXXNPJc%3D" />如上图所示,Redis集群可以看成多个主从架构组合起来的,每一个主从架构可以看成一个节点(其中,只有master节点具有处理请求的能力,slave节点主要是用于节点的高可用)

1、数据分片怎么分?

集群的键空间被分割为16384个slots(即hash槽),通过hash的方式将数据分到不同的分片上的。 HASH_SLOT = CRC16(key) & 16384 CRC16是一种循环校验算法,这里不是我们研究的重点,有兴趣可以看看。 这里用了位运算得到取模结果,位运算的速度高于取模运算。 1d2e17da17124a51be7ecdfb3adf061d~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=i1R0Xhag75rTB2J8Uw%2Fy8x2SQ%2B4%3D

2、数据分片之后怎么查,怎么写?

读请求分配给slave节点,写请求分配给master,数据同步从master到slave节点。读写分离提高并发能力,增加高性能。 1c53376c35e84cd18159a7438cda282c~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=HPmGlGXal%2Fnf5CftKaRsKRX47wg%3D

3、如何做到水平扩展?

master节点可以做扩充,数据迁移redis内部自动完成。当你新增一个master节点,需要做数据迁移,redis服务不需要下线。【举个栗子】上面的有三个master节点,意味着redis的槽被分为三个段,假设三段分别是0~7000,7001~12000、12001~16383。 槽需要重新分配,数据也需要重新迁移,但是服务不需要下线。现在因为业务需要新增了一个master节点,四个节点共同占有16384个槽。redis集群的重新分片由redis内部的管理软件redis-trib负责执行。redis提供了进行重新分片的所有命令,redis-trib通过向节点发送命令来进行重新分片。a7434d7f9ad14d7d9a9f81b328c6874b~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=lE2P2KAkSySvNQp%2FnvFAhcOCz34%3D

4、如何做故障转移?

假如下图中红色的节点故障了,此时master3下面的从节点会通过 选举 产生一个主节点。替换原来的故障节点。此过程和哨兵模式的故障转移是一样的。483f6c93ed1b4cea860d2c2cb4e953c4~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1720063738&x-signature=mP6bdOYWgkP6cnpknTSgde5VPMY%3D

5、特点

多个redis节点网络互联,数据共享所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为支持在线增加、删除节点客户端可以连接任何一个主节点进行读写

6、工作机制

选举集群启动后,主从已分配完成,经过了 N 轮的选举。当某一个主节点宕机,那么从节点需要经过选举成为主节点。简单介绍选举过程: 所有子节点向其他节点发送请求,请求自身成为主节点,其他节点收到请求后,返回投票信息,只有主节点 master 有权投票,且只能投一次,当获取到的票数大于一半人数时(master 个数),就当选 master。 期间,所有子节点发送请求的时机有所有不同。所以基本都有先后顺序,所以很少会出现票数相同情况,如果相同,则重新选举,直到选出 master 为止。 故,需要至少 3 主 3 从,否则节点出现问题,将选举失败。 槽位在 Redis 集群中,定义了 16384 个逻辑上的槽位。将这些槽位均匀分配给 N 个节点(一主一从为一个节点),此文 3 个节点,自动均匀分配。意思为,0-5460 个槽位分配给第一个节点。 当用户 set 一个值时,除了计算 key 本身的 hashCode 之外,还会调用 C 语言的一个 CRC16 算法,将 key 当 hash 值再计算出一个数字,然后与 16384 取模,得到的数字落在哪个槽位,则会将数据放在对应的节点。 比如,计算出的数字为 16387,则取模 16384 后,得到 3,在 0-5460 之间,则放入对于的第一个节点。其他以此类推。 跳转大家都知道,主从模式中,只有主节点可以写入数据,而从节点只能读取数据。在 Cluster 集群中,设置值时,如果计算出的槽位在另一台服务器上,则集群连接会自动跳转至相应服务器。

7、优点

无中心架构;数据共享:数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除;高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升;任意节点读写:客户端可以连接任何一个主节点进行读写。

8、缺点

实现复杂,开发成本高;需要建立配套的周边设施,如监控,域名服务,存储元数据信息的数据库等;维护成本高。

五、Redis 缓存穿透、击穿、雪崩原因&解决方案

1)缓存穿透原因&解决方案

key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。 【解决方案】 布隆过滤器:有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。空结果进行缓存,缓存时间设置短:另外也有一个更为简单粗暴的方法(我们采用的就是这种),如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。

2)缓存击穿原因&解决方案

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。针对的是一个热点key(例如一个秒杀活动),并发量非常大。 【解决方案】 使用互斥锁(mutex key):业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

3)缓存雪崩原因&解决方案

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,也会给后端系统(比如DB)带来很大压力。与缓存击穿的区别在于这里针对很多key缓存,前者则是某一个key。 【解决方案】 关于缓存崩溃的解决方法,这里提出了三种方案:使用锁或队列、设置过期标志更新缓存、为key设置不同的缓存失效时间,还有一种被称为“二级缓存”的解决方法。缓存标记解释 缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。 版权声明:本文转载于网络,版权归作者所有,如果侵权,请联系本站编辑删除

猜你喜欢