分布式专题(1)之Redis持久化、主从与哨兵架构详解

一、Redis持久化

1.1 RDB快照(snapshot)

        在默认的情况下,Redis将内存数据快照保存名字为:dump.rdb的二进制文件中,当然你在配置文件redis.conf中修改对应的二进制文件名。

        redis开启RDB快照,可以在redis中设置,如:让它在N秒内至少有多少个改动这一条件满足时,就自动保存一次快照数据。例如:

比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动保存一次数据集:

save 60 1000 //关闭RDB只需要将所有的save保存策略注释掉即可

        我们还可以手动执行命令来生成RDB快照,进入redis客户端执行命令save或bgsave可以生成dump.rbd文件,每次命令执行都会将所有的redis命令快照到一个新的rdb文件中,并覆盖原有的rdb快照文件。 

1.1.1 bgsave的写时复制(COW)机制

        Redis借助操作系统系统的写时复制技术,在生成快照的同时,依然可以正常的执行命令,简单的来说,bgsave子进程是由主线程fork生成的,可以共享主线程的所有内存数据。bgsave子进程运行后,开始读取主进程的内存数据,并把他们写入RDB文件中,此时,如果主线程对这些数据也是读操作,那么主线程和bgsave子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本,然后,bgsave子进程会把这个副本数据写入RDB文件,而这个过程中,主线程仍然可以直接修改原来的数据。

        save与bgsave的区别:

命令

save

bgsave

IO类型

同步

异步

是否阻塞redis其它命令

否(在生成子进程执行调用fork函数时会有短暂阻塞)

复杂度

O(n)

O(n)

优点

不会消耗额外内存

不阻塞客户端命令

缺点

阻塞客户端命令

需要fork子进程,消耗内存

1.2 AOP(append-only file)

        RDB持久化方式存在的缺点是:如果Redis因为某些原因宕机,那么服务器将丢失最近写入的数据 ,所以从Redis1.1版本开始增加了AOF持久化,将修改的每一条指令记录进文件appendonly.aof中(先写入os cache,每隔一段时间fsync到磁盘)。

        比如执行命令“set zhuge 666”,aof文件里会记录如下数据:

*3
$3
set
$5
zhangsan
$3
666

         这是一种resp协议格式数据,星号后面的数字代表命令有多少个参数,$号后面的数字代表这个参数有几个字符,注意,如果执行带过期时间的set命令,aof文件里记录的是并不是执行的原始命令,而是记录key过期的时间戳,比如执行“set tuling 888 ex 1000”,对应aof文件里记录如下:

*3
$3
set
$6
test
$3
888
*3
$9
PEXPIREAT
$6
tuling
$13
1604249786301

        通过修改配置文件来打开AOF功能:

# appendonly yes

        从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 重新启动时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

        你可以配置 Redis 多久才将数据 fsync 到磁盘一次。有三个选项:

appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。 appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。 appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。

        如果每次修改数据的命令都往aof文件中追加,AOF文件可能会存在太多无效的命令,所以AOF会定期根据内存的最新数据生成aof文件,其实就是重写aof文件。

         例如,执行了如下几条命令:

127.0.0.1:6379> incr readcount
(integer) 1
127.0.0.1:6379> incr readcount
(integer) 2
127.0.0.1:6379> incr readcount
(integer) 3
127.0.0.1:6379> incr readcount
(integer) 4
127.0.0.1:6379> incr readcount
(integer) 5

         重写后AOF文件里变成:

*3
$3
SET
$2
readcount
$1
5

        在redis.conf文件中可以配置AOF文件的重写频率:

# auto-aof-rewrite-min-size 64mb   //aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
# auto-aof-rewrite-percentage 100  //aof文件自上一次重写后文件大小增长了100%则再次触发重写

        当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF,注意,AOF重写redis会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响。

1.3 RDB与AOF持久化方式对比

        生产环境可以都启用,redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更全一点。

命令

RDB

AOF

启动优先级

体积

恢复速度

数据安全性

容易丢数据

根据策略决定

1.4 混合持久化 

        重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。

        通过如下配置可以开启混合持久化(必须先开启aof): 

# aof-use-rdb-preamble yes   

        如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。 

        于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。

        混合持久化AOF文件结构如下:

1.5 Redis备份策略

  1. 写crontab定时调度脚本,每小时都copy一份rdb或aof的备份到一个目录中去,仅仅保留最近48小时的备份
  2. 每天都保留一份当日的数据备份到一个目录中去,可以保留最近1个月的备份
  3. 每次copy备份的时候,都把太旧的备份给删了
  4. 每天晚上将当前机器上的备份复制一份到其他机器上,以防机器损坏。

二、主从架构

2.1 主从架构搭建步骤 

1、复制一份redis.conf文件2、将相关配置修改为如下值:
port 6380
pidfile /var/run/redis_6380.pid  # 把pid进程号写入pidfile配置的文件
logfile "6380.log"
dir /usr/local/redis-5.0.3/data/6380  # 指定数据存放目录
# 需要注释掉bind
# bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)3、配置主从复制
replicaof 192.168.0.60 6379   # 从本机6379的redis实例复制数据,Redis 5.0之前使用slaveof
replica-read-only yes  # 配置从节点只读4、启动从节点
redis-server redis.conf   # redis.conf文件务必用你复制并修改了之后的redis.conf文件5、连接从节点
redis-cli -p 63806、测试在6379实例上写数据,6380实例是否能及时同步新修改数据7、可以自己再配置一个6381的从节点

2.2 主从架构工作原理 

        如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个PSYNC命令给master请求复制数据。

        如果master接收到从节点的psync的指令之后 ,会在后天进行数据的持久化操作,通过bgsave生成dump.rdb文件,并且在这个持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。

        当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。

2.2.1 全量复制流程

2.2.1 增量数据复制

        当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,redis改用可以支持部分数据复制的命令PSYNC去master同步数据,slave与master能够在网络连接断开重连后只进行部分数据复制(断点续传)。

        master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制。

        流程图如下:

        如果有很多从节点,为了缓解主从复制风暴(多个从节点同时复制主节点导致主节点压力过大),可以做如下架构,让部分从节点与从节点(与主节点同步)同步数据 :

三、Redis哨兵高可用架构 

        sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。

        哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息) 

3.1redis哨兵架构搭建

1、复制一份sentinel.conf文件
cp sentinel.conf sentinel-26379.conf2、将相关配置修改为如下值:
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.3/data"
# sentinel monitor <master-redis-name> <master-redis-ip> <master-redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.168.0.60 6379 2   # mymaster这个名字随便取,客户端访问时会用到3、启动sentinel哨兵实例
src/redis-sentinel sentinel-26379.conf4、查看sentinel的info信息
src/redis-cli -p 26379
127.0.0.1:26379>info
可以看到Sentinel的info里已经识别出了redis的主从5、可以自己再配置两个sentinel,端口26380和26381,注意上述配置文件里的对应数字都要修改

        entinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的最下面),我们查看下如下配置文件sentinel-26379.conf,如下所示:

sentinel known-replica mymaster 192.168.0.60 6380 #代表redis主节点的从节点信息
sentinel known-replica mymaster 192.168.0.60 6381 #代表redis主节点的从节点信息
sentinel known-sentinel mymaster 192.168.0.60 26380 52d0a5d70c1f90475b4fc03b6ce7c3c56935760f  #代表感知到的其它哨兵节点
sentinel known-sentinel mymaster 192.168.0.60 26381 e9f530d3882f8043f76ebb8e1686438ba8bd5ca6  #代表感知到的其它哨兵节点

        当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件的集群元数据信息,比如6379的redis如果挂了,假设选举出的新主节点是6380,则sentinel文件里的集群元数据信息会变成如下所示:

sentinel known-replica mymaster 192.168.0.60 6379 #代表主节点的从节点信息
sentinel known-replica mymaster 192.168.0.60 6381 #代表主节点的从节点信息
sentinel known-sentinel mymaster 192.168.0.60 26380 52d0a5d70c1f90475b4fc03b6ce7c3c56935760f  #代表感知到的其它哨兵节点
sentinel known-sentinel mymaster 192.168.0.60 26381 e9f530d3882f8043f76ebb8e1686438ba8bd5ca6  #代表感知到的其它哨兵节点

        同时还会修改sentinel文件里之前配置的mymaster对应的6379端口,改为6380:

sentinel monitor mymaster 192.168.0.60 6380 2

        当6379的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点加入集群 。

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

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

相关文章

Y20030053 JSP+SSM+MYSQL+LW+旅游系统的设计与实现 源码 配置 文档 全套资料

旅游系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 摘 要 随着旅游业的蓬勃发展和人们对休闲度假需求的不断增加&#xff0c;旅游业管理面临着越来越多的挑战。为了提高管理效率、优化客户体验并增强市场竞争力&#xff0c;本文介绍…

TypeScript进阶

Typescript进阶 基础知识 JavaScript 的核心特点就是灵活&#xff0c;但随着项目规模的增大&#xff0c;灵活反而增加开发者的心智负担。例如在代码中一个变量可以被赋予字符串、布尔、数字、甚至是函数&#xff0c;这样就充满了不确定性。而且这些不确定性可能需要在代码运行…

github操作学习笔记

git开源的分布式版本控制系统&#xff1a; 每次修改文件提交后&#xff0c;都会自动创建一个项目版本 查看git版本看有没有安装成功&#xff1a;git --version 把默认编辑器设置成vim&#xff1a;git config --global core.editor "vim" 1、设置昵称和邮箱&#xff…

QT 多级嵌套结构体,遍历成员--半自动。<模板+宏定义>QTreeWidget树结构显示

Qt的QTreeWidget来显示嵌套结构体的成员&#xff0c;并以树形结构展示。 #include <QApplication> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QString> #include <cstdint>// 假设这些是你的结构体定义 struct BaseMeterPa…

简明速通Java接口

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文从代码层面直接整理Java接口 让老油子们无需再理解繁杂的概念了。 Java接口在代码层面是做什么的 说白了老铁&#xff0c;Java的接口就是一个类&#xff0c;这个类中只能声明属性和方法&#xff0c;属性需要…

2.linux中调度kettle

一.准备转换&#xff0c;等会在linux中用 1.添加excel输入组件&#xff0c;并添加对应的文件 2.添加列拆分为多行组件 3.添加文本文件输出组件 4.保存转换 二.linux安装java 1.把jdk-8u144-linux-x64.tar.gz上传到linux的/lx目录下 2. 解压jdk包&#xff0c;然后配置环境变量…

【C#设计模式(19)——备忘录模式(MementoPattern)】

前言 备忘录模式&#xff1a;将想要备份的信息交给备忘录对象来管理。通过设置初始、备份、修改、恢复等状态展示备忘录模式的使用。 代码 //备忘录类 public class Memento {private string state;public string State { get>state;}public Memento(string state){this.st…

如何将CSDN博客下载为PDF文件

1.打开CSDN文章内容 2.按键盘上的f12键&#xff08;或者右键—审查元素&#xff09;进入浏览器调试模式&#xff0c;点击控制台&#xff08;Console&#xff09;进入控制台 3.在控制台输入以下代码&#xff0c;回车 (function(){ $("#side").remove(); $("#…

GWAS分析先做后学

大家好&#xff0c;我是邓飞。 GWAS分析是生物信息和统计学的交叉学科&#xff0c;上可以学习编程&#xff0c;下可以学习统计。对于Linux系统&#xff0c;R语言&#xff0c;作图&#xff0c;统计学&#xff0c;机器学习等方向&#xff0c;都是一个极好的入门项目。生物信息如…

git命令基本操作

一、git介绍 Git 是一个开源的分布式版本控制系统&#xff0c;旨在提供一个快速、灵活且分布式的版本控制系统&#xff0c;能够处理从小型个人项目到大型复杂企业项目的各种规模的开发工作。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制…

快速了解 Aurora DSQL

上周在 AWS re:Invent大会&#xff08;类似于阿里云的云栖大会&#xff09;上推出了新的产品 Aurora DSQL[1] &#xff0c;在数据库层面提供了多区域、多点一致性写入的能力&#xff0c;兼容 PostgreSQL。并声称&#xff0c;在多语句跨区域的场景下&#xff0c;延迟只有Google …

大数据之国产数据库_OceanBase数据库002_在centos7.9上_安装部署OceanBase001_踩坑指南_亲测可用

部署前最好看一下,部署前的要求, 主要是系统 以及系统内核版本,还有比如清理一下缓存等,按照做一做. 这些都是前置条件. 清一下缓存. 也就是说官网给的前置的条件,都要根据说明去执行一遍,如果不执行可能后面安装会报错. 然后用户最好也去创建一个用户. 注意前置

Kafka Stream实战教程

Kafka Stream实战教程 1. Kafka Streams 基础入门 1.1 什么是 Kafka Streams Kafka Streams 是 Kafka 生态中用于 处理实时流数据 的一款轻量级流处理库。它利用 Kafka 作为数据来源和数据输出&#xff0c;可以让开发者轻松地对实时数据进行处理&#xff0c;比如计数、聚合、…

Leecode刷题C语言之判断国际象棋棋盘中一个格子的颜色

执行结果:通过 执行用时和内存消耗如下&#xff1a; 代码如下 &#xff1a; bool squareIsWhite(char* s) {return s[0] % 2 ! s[1] % 2; } 解题思路&#xff1a; 这段代码的目的是判断一个给定的字符串 s 所表示的棋盘上的格子是否为白色。这里假设字符串 s 的前两个字符…

Oracle之表空间迁移

问题背景&#xff1a;一个数据表随着时间的累积&#xff0c;导致所在表空间占用很高&#xff0c;里面历史数据可以清除&#xff0c;保留近2个月数据即可 首先通过delete删除了2个月以前的数据。 按网上的教程进行空间压缩&#xff0c;以下sql在表所在用户执行: -- 允许表重新…

Redis中pipeline(管道)详解

redis管道pipeline 举个例子&#xff1a; 小卖铺免费让你拿50瓶饮料&#xff0c;你是一次拿一瓶拿回家&#xff0c;还是打包一次或者多次拿回家&#xff1f; 概念 Redis管道(pipelining)是一种在客户端向服务端发送多个请求而不等待响应的技术。它可以显著提高Redis应用程序…

Mybatis 关联查询

在 MyBatis 中&#xff0c;关联查询&#xff08;也称为复杂映射&#xff09;是指将多个表的数据通过 SQL 查询和结果映射的方式&#xff0c;组合成一个或多个 Java 对象。这种查询方式用于处理实体之间的关系&#xff0c;如一对一、一对多和多对多关系。通过关联查询&#xff0…

【数据分享】1901-2023年我国省市县三级逐年最低气温数据(Shp/Excel格式)

之前我们分享过1901-2023年1km分辨率逐月最低气温栅格数据和Excel和Shp格式的省市县三级逐月最低气温数据&#xff0c;原始的逐月最低气温栅格数据来源于彭守璋学者在国家青藏高原科学数据中心平台上分享的数据&#xff01;基于逐月栅格数据我们采用求年平均值的方法得到逐年最…

appium学习之二:adb命令

1、查看设备 adb devices 2、连接 adb connect IP:端口 3、安装 adb install xxx.apk 4、卸载 adb uninstall 【包名】 5、把对应目录下的1.txt文件传到手机sdcard下 adb push 1.txt /sdcard 6、进入对应的设备里 adb shell 7、切入sdcard目录 cd /sdcard 8、ls 查…

HTML5教程-表格宽度设置,最大宽度,自动宽度

HTML表格宽度 参考&#xff1a;html table width HTML表格是网页设计中常用的元素之一&#xff0c;可以用来展示数据、创建布局等。表格的宽度是一个重要的参数&#xff0c;可以通过不同的方式来设置表格的宽度&#xff0c;本文将详细介绍HTML表格宽度的不同设置方式和示例代…