Redis运维篇-快速面试笔记(速成版)

文章目录

  • 1. Redis的持久化
    • 1.1 RDB(快照模式)
    • 1.2 AOF 模式
  • 2. Redis主从模型(高可用)
    • 2.1 Redis的主从复制
    • 2.2 Redis拓扑结构
  • 3. Redis集群模式(高并发)
    • 3.1 Redis的Slots
    • 3.2 集群模式的常用命令
    • 3.3 多主多从架构
  • 4. Redis的内存管理
    • 4.1 Redis的内存模型
    • 4.2 查看Redis内存占用情况
    • 4.3 Redis内存管理与优化
  • 5. Redis常见故障处理
    • 5.1 内存溢出
    • 5.2 命令阻塞
  • 参考资料

1. Redis的持久化

为了保证Redis中的数据尽可能不丢失,需要对Redis中的数据进行持久化。

Redis提供两种持久化方案:

  • 快照(snapshotting),也称为RDB:某一时刻将数据全部写入到磁盘(生成一个rdb文件)。
    • 优点:① 数据恢复速度快。② 存储效率高;③ 可用于数据备份;④ 备份文件占用存储空间小。
    • 缺点:① 数据会丢失一部分;② 备份时会占用系统资源;③ 备份文件在不同的redis版本之间存在兼容性问题。
  • 只追加文件(append-only file, AOF):执行写命令时,将命令复制到磁盘中。
    • 优点:① 数据不丢失或丢失较少(取决于策略);
    • 缺点:① 数据恢复速度慢,因为是把之前执行过的命令都再执行一遍。② 会频繁写入磁盘;③ 备份文件占用磁盘空间过大。

两种方案可以同时使用。若同时使用,启动Redis时,会优先使用AOF恢复数据。

1.1 RDB(快照模式)

创建RDB快照的方法:

  1. 执行save命令:save命令速度快,但会阻塞其他命令。因此生产应禁止使用
  2. 执行bgsave命令:bgsave相对较慢,但是是在后台“子进程”执行,不影响命令正常执行。
  3. 配置save <second> <number>:即当<second>秒内发生了<number>次写入时,自动执行bgsave命令。可以配置多个,例如:save 60 10000save 300 10save 900 1,即若60秒内写入1w次则自动执行bgsave,如果300秒内写入10次也执行bgsave,最后再来个保底的,900秒内只要发生过一次写入就执行bgsave

BGSAVE注意事项:bgsave会先创建一个子进程,然后将现有内存中的数据复制一份,然后再持久化到硬盘中。因此,主节点最好只使用50%~65%的内存,以免bgsave导致内存溢出。

RDB方法注意事项:

  • bgsave占用内存大:bgsave会将现有的数据拷贝一份,然后dump到硬盘中。因此,至少需要预留50%的内存空间
  • bgsave的fork操作:bgsave执行时,首先会创建一个子进程fork操作)。但是该fork操作是单线程的,其他命令需要排队。
  • 数据丢失问题:如果只用rdb做备份,那么redis宕机后,就会丢失“上次备份”到“崩溃前”这段时间写入的数据。

1.2 AOF 模式

AOF的配置方法:修改redis.conf配置文件

# 这里改成yes
appendonly yes# 配置策略,包含三种策略:always、everysec、no
appendfsync everysec

AOF的三种持久化策略:

  • always:每个写命令都写入硬盘,数据基本不会丢失,最多丢失一条。风险点:① 若写入频繁,磁盘写入跟不上内存写入;② 若使用固态硬盘,频繁写入会缩短硬盘寿命;
  • everysec(推荐):每秒写入一次。最多丢失一秒的数据。很好的平衡了数据丢失问题与磁盘频繁写入问题。
  • no:系统自己决定什么时候写入,大约30s。不推荐,这样还不如不用AOF。

AOP的注意事项:

  • 磁盘占用大:由于AOF会记录每条写日志,所以磁盘占用过大。因此,需要监控磁盘容量,避免出问题。
  • 恢复时间长:AOF的恢复是逐条在执行一遍写操作。若仅使用AOF做备份,那么Redis宕机后的重启会过慢
  • AOF重写机制:AOF的重写机制会定期重写AOF文件,降低文件大小(例如:对一个频繁更改的key,仅保留最后一个写命令即可)。但,重写期间会占用IO和CPU资源

2. Redis主从模型(高可用)

使用Redis的主从模式可以实现Redis的高可用。在主从模式下,Redis的一个主节点可以有多个主节点。主节点负责读写,从节点负责备份主节点数据。(也可以使用主从模式做读写分离,也就是读从节点,但会有延迟)。

当Redis主节点宕机后,Redis会自动从从节点中选举一个节点作为新的主节点。因此,只要保证主节点和所有的从节点不一起宕机,就可以保证Redis的高可用。

2.1 Redis的主从复制

为了保证主节点和从节点的数据一致,需要进行主从复制。即,将主节点的数据同步给从节点。

主从同步有两种:

  • 全量同步:将主节点的数据全部同步给从节点。
    • 触发场景:若从节点与主节点的数据相差过大时,会进行全量同步。常见场景:① 从节点首次主节点;② 从节点宕机较长时间后,重新连接主节点。
    • 判断方式:从节点连接主节点后,会告诉其同步的偏移量(即上次同步到哪个位置了)。主节点会检查缓冲区中的命令是否可以满足要求。若不满足,则全量同步,满足则部分同步。
    • 同步方式:全量同步采用RDB方式。具体为:生成RDB文件,发送给从节点。后续开始进行部分同步。
  • 部分同步:将近期写入的部分数据同步给从节点。
    • 同步方式:当主节点写入命令后,会将命令写入到同步缓冲区(Replication Backlog)。当缓冲区满了,或定期触发时,主节点会将缓冲区的命令传给从节点。

从节点首次/或重连接主节点时的详细同步流程如下:

序号主节点从节点
1等待从节点接入
2从节点发送SYNC命令连接主节点
3主节点执行BGSAVE。
执行过程以及之后用户写入的新命令都记录到缓冲区
4BGSAVE执行完毕,向从节点发送rdb文件
5接收到rdb文件后,丢弃现有数据,载入主节点发过来的rdb文件
6向从节点发送缓冲区中的命令
7接受缓冲区中的命令,写入到从节点
8缓冲区命令发送完毕
9主节点收到一条写命令,同步给从节点
10从节点执行主节点同步过来的写命令
11后续过程就是不断重复9,10步骤

如果从节点宕机一小段时间,从节点重新连接后,会告诉主节点上次复制的偏移量。若主节点的缓冲区里有数据,则部分复制,否则会重新全量复制。

与主从复制相关的常用配置:

  • slave-read-only=yes从节点是否只读。一般为yes。因为从节点的写入无法同步给任何机器。
  • repl-disable-tcp-nodelay是否开启主从同步延迟。默认关闭,即每个命令都立刻同步给从节点,延迟低,消耗带宽大。若开启,则主节点会合并部分数据一起发送,节省带宽,但延迟较高(大约40毫秒)。若从节点只用于容灾(不做读写分离),且网络带宽紧张,那么就可以开启。
  • repl-backlog-size复制积压缓冲区大小,用于给从节点同步数据。若从节点要同步的数据超出了缓冲区,则会引起全量同步。 默认1M,建议改为100M,太小容易引起全量同步。

2.2 Redis拓扑结构

Redis主从模式一般可以设计成是三种拓扑结构:一主一从、一主多从、树状主从。

如果有多个主节点同理,上面说的只是站在其中一个主节点的视角说的。


一主一从:一个主节点有一个从节点,通常该从节点用于容灾。

主节点
从节点

一主一从注意事项和使用技巧:

  • 不建议用一主一从做读写分离,这样主从都不能挂,没法做到容灾。
  • 可以只在从节点开启AOF持久化,降低主节点压力。但要注意,这样做的话,主节点不要做自动重启,要不然主节点重启后因为没有持久化文件,最后把从节点也清空了,导致数据丢失。

一主多从:一个主节点对应多个从节点。通常用于做读写分离。

主节点
从节点1
...
从节点N

一主多从注意事项与使用技巧:

  • 读多写少,可以用一主多从做读写分离,降低主节点压力。
  • 但如果读多,写也多,且从节点较多,建议改为树状主从结构,否则主节点的同步压力就太大了。
  • 注意复制风暴,当主节点宕机后重启、或一次大量从节点连接主节点时,会同时有大量从节点要求全量复制,造成主节点带宽压力大。可改为树状主从结构解决。

树状主从:主节点有从节点,从节点还有从节点。用于降低主节点的同步压力,由下游的从节点数据来自上游从节点的复制。

主节点
从节点1
...
从节点N
从节点1a
...
...
...

3. Redis集群模式(高并发)

所有的写操作一定要在主节点完成,若Redis仅有一个主节点,则无法实现高并发。

因此,Redis之后提供了分布式解决方案,Redis集群

3.1 Redis的Slots

Redis之所以可以实现高吞吐量,除了基于内存的设计外,更重要的是:Redis是基于Hash算法实现的

Redis的Hash桶大小为16384,被称为16384个槽(Slots)

当操作key时,Redis首先会使用CRC16(key) % 16384(CRC16是一种Hash算法)计算出该key存放的slot,然后在该slot对其进行操作。

在Redis单主节点模式下,所有的slot都在该主节点上。

在Redis集群模式下(多主节点),slot会平均分到不同的主节点上。例如:

在这里插入图片描述

当客户端连接Redis后,会获取到Redis集群的各个节点信息。在对key操作时,客户端会计算key的slot,然后直接访问对应的主节点。

若该slot不在对应的主节点时,会返回moved错误。例如:“(error) MOVED 16281 127.0.0.1:7003”。即该key的slot为16281,其不在该机器上,请移动到“127.0.0.1:7003”上访问。

3.2 集群模式的常用命令

可以使用该项目快速搭建一个Redis集群进行测试

# 查看集群信息,包括集群基本信息、集群状态、slot状态等
> cluster info# 查看节点信息,包括各节点的IP端口、主从状态、slot范围等
> cluster nodes# 计算key所属的slot
> cluster keyslot <your-key>

3.3 多主多从架构

使用Redis集群可以将slots分散在不同的主节点上,分散了单机写入的压力,实现了高并发

使用主从架构可以为一个主节点配置多个从节点,当主节点宕机后可以自动主从切换,实现了高可用

Redis本身基于Hash算法和内存数据库,可以做到高吞吐量,实现了高性能

因此,将三者结合起来,则可以实现一个三高Redis:高并发、高可用、高性能。

例如,一个三主六从的Redis架构如下:

在这里插入图片描述

共有三个主节点,平分slot。每个主节点有两个从节点做容灾。

4. Redis的内存管理

4.1 Redis的内存模型

Redis的内存占用主要包含如下部分:

  • 数据对象内存:用户存储的数据所占的内存大小。
  • 程序自身内存:Redis自身进程所要占用的内存。占用很小。
  • 缓冲区内存:Redis有三种缓冲区,分别是:
    • 客户端缓冲:客户端对Redis读取和写入都会经过读或写缓冲区。若有大量客户端连接,或有BigKey,可能导致缓冲区内存溢出,引起OOM。
    • 复制积压缓冲区:用于给丛节点同步数据。若从节点要求的数据已经不在缓冲区了,则会引起全量同步。建议设置大一点。
    • AOF缓冲区:用于AOF重写期间保存最近写入的命令。占用通常很小。
  • 内存碎片:为了便于内存管理,Redis内的内存分配器会将内存划分为不同的固定大小的内存块。每个key会选择适合自己大小的内存块来存放数据,但通常不会刚好,总会有些内存被浪费掉,这部分称为内存碎片。
  • 子进程内存:(这部分可以被归类到“程序自身内存”中)通常指执行bgsave或“AOF重写”时创建的子进程。由于要复制一份父进程的数据对象内存,因此内存占用量是数据对象内存的1倍。

4.2 查看Redis内存占用情况

使用info memory命令可以看到Redis的内存使用情况。在展示的结果中,常用的信息如下:

  • used_memory:“数据对象内存+程序自身内存+缓冲区”三者所占用的内存总量。
  • used_memory_human:used_memory的易读模式。
  • used_memory_rss:Redis占用的物理内存,即“used_memory+内存碎片”
  • used_memory_peak:used_memory的峰值。帮助运维人员判断redis的最大使用量,防止内存不够用。
  • mem_fragmentation_ratio:内存碎片率。计算方式为:used_memory_rss / used_memory。若mem_fragmentation_ratio较大,说明内存碎片率严重。若mem_fragmentation_ratio<1,说明发生了内存交换(使用到了虚拟内存),需要格外注意。

4.3 Redis内存管理与优化

与Redis内存管理相关的常用设置有:

  • maxmemory最大可用内存(不包含内存碎片),可动态使用修改。通常需要为操作系统和Redis内存碎片预留一部分空间,避免OOM。
  • maxmemory-policy内存回收策略,可动态设置。当内存使用达到maxmemory上限后,使用哪种策略对key进行回收。常用的策略有:
    • noeviction:默认策略,不删除数据,给客户端返回OOM错误;
    • volatile-lru:删除最近最少使用(LRU)且设置了超时时间的key。若没有可删除的,则按noeviction处理。
    • allkeys-lru:删除最近最少使用的key
    • volatile-ttl:删除最近将要过期的key。如果没有,则按noeviction处理。

Redis常用的优化策略有:

  • 缩短key的长度
  • 缩短value的长度:当Redis用作对象缓存时,可以用如下手段降低value长度,包括:① 去掉无用的字段;② json压缩后再存;③ 选用压缩比更高的序列化手段,如:protostuff、kryo等。
  • 使用整数:Redis中维护了一个[0-9999]的整数共享对象池。若你的key、value或list、set等内的对象使用的是整数,那么就会共享整数对象,节约内存。注意:当volatile-lruallkyes-lru等lru策略时,共享对象池会失效。因为对象要记录自己的lru值(即上次被访问的时间),导致没法共享了。
  • 指定ziplist作为底层数据结构:当使用list/hash/zset时,可以指定使用ziplist作为底层数据结构,这样可以节省空间,不过增改查的效率会受影响,即使用时间换空间。若不是很熟悉数据结构,不建议使用。

5. Redis常见故障处理

5.1 内存溢出

Redis发生OOM或内存突然增加可能是因为如下原因造成的:

  • 数据量大:确实是写入的数据太多了。
  • 正在执行bgsave:bgsave的执行会将现在的内存拷贝一份,因此会占用大量内存。典型的现象是:主节点的内存占用量是从节点的一倍。
  • 缓冲区被占满:客户端与Redis服务器交互时(写入和读取),会使用缓冲区(详情可参考Redis缓冲区机制)。若写入/读取速度过快,或写入/读取过多BigKey,就会导致缓冲区被占满。

5.2 命令阻塞

现象:客户端收到大量的超时异常

发生命令阻塞的原因可能有:

  • 存在慢查询:由于Redis是单线程执行的,若出现慢查询命令,那么后面的命令都会处于等待状态,那如果这个慢查询过慢,那么后面排队的命令对应的客户端可能都会超时。造成慢查询通常是因为“不合理的使用API或数据结构”,例如:keys *,操作大对象等。
  • CPU饱和:Redis是单线程执行的,因此执行命令只会在一个CPU上(其他CPU负责Redis的其他后台线程)。若该CPU饱和,也会造成命令执行阻塞。
  • fork子进程:“RDB”和“AOF重写”会fork一个子进程, fork过程是主线程执行的,其它命令需等待。由于fork过程需要拷贝主进程的内存页表,因此,若Redis内存过大,则fork过程就会慢。(通常10GB的redis内存大约有20MB的内存页表)。
  • AOF刷盘阻塞:AOF持久化会每秒做一次fsync操作,也就是写入数据到硬盘。若硬盘压力大,fsync操作会等待。若超过2秒未完成,为了保证数据安全,主线程会等待fsync完成后,再执行后续命令。
  • CPU竞争:若你的Redis服务器部署了其他程序,那CPU可能被其他程序给抢占了
  • 内存交换:如果内存不够大,导致一部分数据存到虚拟内存里,那读写速度会极大变慢,一定要警惕,最好禁止使用虚拟内存。
  • 网络问题




参考资料

  • Redis设计与实现(黄健宏 著)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/317974.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全景剖析阿里云容器网络数据链路(七):Terway DataPath V2(Terway≥1.8.0)

作者&#xff1a;余凯 前言 近几年&#xff0c;企业基础设施云原生化的趋势越来越强烈&#xff0c;从最开始的IaaS化到现在的微服务化&#xff0c;客户的颗粒度精细化和可观测性的需求更加强烈。容器网络为了满足客户更高性能和更高的密度&#xff0c;也一直在高速的发展和演…

2024年五一数学建模C题完整解题思路代码

2024年第二十一届五一数学建模竞赛题目 C题 煤矿深部开采冲击地压危险预测 煤炭是中国的主要能源和重要的工业原料。然而&#xff0c;随着开采深度的增加&#xff0c;地应力增大&#xff0c;井下煤岩动力灾害风险越来越大&#xff0c;严重影响着煤矿的安全高效开采。在各类深…

MySQL之多表查询

1. 前言 多表查询&#xff0c;也称为关联查询.指两个或两个以上的表一起完成查询操作.前提条件 : 这些一起查询的表之间是有关系的(一对一/一对多).他们之间一定是有关联字段&#xff0c;这个关联字段可能建立了外键&#xff0c;也可能没有建立外键. 2. 笛卡尔积现象(交叉连接…

【Vulhub靶场】Nginx 漏洞复现

Nginx 漏洞复现 一、Nginx 文件名逻辑漏洞&#xff08;CVE-2013-4547&#xff09;1、影响版本2、漏洞原理3、漏洞复现 二、Nginx 解析漏洞1、版本信息&#xff1a;2、漏洞详情3、漏洞复现 一、Nginx 文件名逻辑漏洞&#xff08;CVE-2013-4547&#xff09; 1、影响版本 Nginx …

【数据结构】:链表的带环问题

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;数据结构 &#x1f337;追光的人&#xff0c;终会万丈光芒 前言&#xff1a; 链表的带环问题在链表中是一类比较难的问题&#xff0c;它对我们的思维有一个比较高的要求&#xff0c;但是这一类…

【数据结构】链表专题3

前言 本篇博客我们继续来讨论链表专题&#xff0c;今天的链表算法题是经典中的经典 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 目录 1.判断链表是否…

【Scala---01】Scala『 Scala简介 | 函数式编程简介 | Scala VS Java | 安装与部署』

文章目录 1. Scala简介2. 函数式编程简介3. Scala VS Java4. 安装与部署 1. Scala简介 Scala是由于Spark的流行而兴起的。Scala是高级语言&#xff0c;Scala底层使用的是Java&#xff0c;可以看做是对Java的进一步封装&#xff0c;更加简洁&#xff0c;代码量是Java的一半。 因…

操作系统安全:Linux安全审计,Linux日志详解

「作者简介」:2022年北京冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础对安全知识体系进行总结与归纳,著作适用于快速入门的 《网络安全自学教程》,内容涵盖系统安全、信息收集等12个知识域的一百多个知识点,持续更新。 这一章节需要直到Linux…

09_Scala函数和对象

文章目录 函数和对象1.函数也是对象 scala中声明了一个函数 等价于声明一个函数对象2.将函数当作对象来用&#xff0c;也就是访问函数&#xff0c;但是不执行函数结果3.对象拥有数据类型(函数类型)&#xff0c;对象可以进行赋值操作4.函数对象类型的省略写法&#xff0c;也就是…

Java创建并遍历N叉树(前序遍历)

力扣 title589&#xff1a;N叉树的前序遍历 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔&#xff08;请参见示例&#xff09;。 思路&#xff1a; 1.初始化时…

CSS-复合选择器

作用&#xff1a; 后代选择器&#xff1a; 子代选择器 并集选择器 用逗号隔开&#xff0c;在style里面写的时候&#xff0c;每一个标签空一行。 <title>Document</title><style>p,div,span{color: aqua;}</style> </head> <body><p>…

细说SVPWM原理及软件实现原理,关联PWM实现

细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现 文章目录 细说SVPWM原理及软件实现原理&#xff0c;关联PWM实现1. 前言2. 基础控制原理回顾2.1 FOC 原理回顾2.2 细说 SVPWM2.2.1 矢量扇区计算2.2.2 矢量作用时间计算 2.2.3 如何理解 U4 U6 2/3Udc?2.2.4 如何理解 U4m…

工业异常检测

工业异常检测在业界和学界都一直是热门&#xff0c;近期其更是迎来了全新突破&#xff1a;与大模型相结合&#xff01;让异常检测变得更快更准更简单&#xff01; 比如模型AnomalyGPT&#xff0c;它克服了以往的局限&#xff0c;能够让大模型充分理解工业场景图像&#xff0c;判…

Java中使用Redis实现分布式锁的三种方式

1. 导语 随着软件开发领域的不断演进,并发性已经成为一个至关重要的方面,特别是在资源跨多个进程共享的分布式系统中。 在Java中,管理并发性对于确保数据一致性和防止竞态条件至关重要。 Redis作为一个强大的内存数据存储,为在Java应用程序中实现分布式锁提供了一种高效的…

第11章 数据库技术(第一部分)

一、数据库技术术语 &#xff08;一&#xff09;术语 1、数据 数据描述事物的符号描述一个对象所用的标识&#xff0c;可以文字、图形、图像、语言等等 2、信息 现实世界对事物状态变化的反馈。可感知、可存储、可加工、可再生。数据是信息的表现形式和载体&#xff0c;信…

Mac brew安装Redis之后更新配置文件的方法

安装命令 brew install redis 查看安装位置命令 brew list redis #查看redis安装的位置 % brew list redis /usr/local/Cellar/redis/6.2.5/.bottle/etc/ (2 files) /usr/local/Cellar/redis/6.2.5/bin/redis-benchmark /usr/local/Cellar/redis/6.2.5/bin/redis-check-ao…

【PyTorch 实战3:YOLOv5检测模型】10min揭秘 YOLOv5 检测网络架构、工作原理以及pytorch代码实现(附代码实现!)

YOLOv5简介 YOLOv5&#xff08;You Only Look Once, Version 5&#xff09;是一种先进的目标检测模型&#xff0c;是YOLO系列的最新版本&#xff0c;由Ultralytics公司开发。该模型利用深度学习技术&#xff0c;能够在图像或视频中实时准确地检测出多个对象的位置及其类别&…

win下vscode的vim切换模式的中英文切换

问题描述 在vscode中安装vim插件后&#xff0c;如果insert模式下完成输入后&#xff0c;在中文输入方式下按esc会发生无效输入&#xff0c;需要手动切换到英文。 解决方法 下载完成vscode并在其中配置vim插件下载github—im-select.exe插件&#xff08;注意很多博文中的gitcod…

【STM32+HAL+Proteus】系列学习教程4---GPIO输入模式(独立按键)

实现目标 1、掌握GPIO 输入模式控制 2、学会STM32CubeMX配置GPIO的输入模式 3、具体目标&#xff1a;1、按键K1按下&#xff0c;LED1点亮&#xff1b;2、按键K2按下&#xff0c;LED1熄灭&#xff1b;2、按键K3按下&#xff0c;LED2状态取反&#xff1b; 一、STM32 GPIO 输入…

数据结构的队列(c语言版)

一.队列的概念 1.队列的定义 队列是一种常见的数据结构&#xff0c;它遵循先进先出的原则。类似于现实生活中排队的场景&#xff0c;最先进入队列的元素首先被处理&#xff0c;而最后进入队列的元素则要等到前面的元素都被处理完后才能被处理。 在队列中&#xff0c;元素只能…