【Redis】高可用架构之哨兵模式 - Sentinel
Redis 高可用架构之哨兵模式 - Sentinel
- 1. 前言
- 2. Redis Sentinel 哨兵集群搭建
- 2.1 一主两从
- 2.2 三个哨兵
- 3. Redis Sentinel 原理剖析
- 3.1 什么哨兵模式
- 3.2 哨兵机制的主要任务
- 3.2.1 监控
- (1)每1s发送一次 PING 命令
- (2)PING 命令的回复有两种情况
- (3)主观下线和客观下线
- 3.2.2 主从动态切换
- (1)筛选
- (2)综合评估
- 3.2.3 通知
- 3.3 哨兵机制的工作原理
- 3.3.1 pub/sub 实现哨兵间通信和发现 slave
- 3.3.2 选择哨兵执⾏主从切换
- 3.3.3 通过 pub/sub 实现客户端事件通知
- 4. 总结
- 4.1 哨兵主要任务
- 4.2 哨兵集群原理
1. 前言
上一篇文章,已经介绍了 Redis 主从架构:Redis 主从复制 + 读写分离。为Redis 配置主从模式,可以大幅度提高 Redis 的可用性,减少甚至避免 Redis 服务发生宕机的可能。
Redis 主从模式有以下作用:
-
故障隔离和恢复:无论主节点或者从节点宕机,其他节点依然可以保证服务的正常运行,并可以手动切换主从。
-
读写隔离:Master 节点提供写服务,Slave 节点提供读服务,分摊流量压力,均衡流量的负载。
-
提供高可用保障:主从模式是高可用的最基础版本,也是哨兵模式和 cluster模式实施的前置条件。
尽管 Redis 主从模式已经做的足够多了,但其还是存在不小的问题。我们先来学习一个专业名词:平均修复时间(Mean time to repair,MTTR),它是衡量系统可用性的关键指标:我们计算一下,从监控到 Redis 故障到手动切换主从止损,再到 Redis 服务恢复正常,这期间可能是一个较长的过程,这在生产环境(甚至是超高并发的大型交易系统)就是一个灾难,其带来的损失也是无法估计的。
所以我们需要系统自动的感知到 Master 故障,并选择一个 Slave 切换为 Master,实现故障自动转移的能力。
2. Redis Sentinel 哨兵集群搭建
2.1 一主两从
- Master
bind 0.0.0.0
# Master 端口
port 6379
# 后台执行
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis1.log"
dbfilename "pointer1.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly1.aof"
masterauth "123456"
- Slave
主要在于端口号不同,分别是 6380、6381。
bind 0.0.0.0
# Master 端口
port 6380
# 后台执行
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis2.log"
dbfilename "pointer2.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly2.aof"
# 从本机 6379 的 redis 实例复制数据,Redis 5.0 之前使用 slaveof
replicaof 192.169.0.1 6379
# 从节点开启只读模式(默认)
replica‐read‐only yes
# 从节点访问主节点的密码,和 requirepass ⼀样
masterauth "123456"
- 分别启动 Redis
./redis-6.2.4/src/redis-server redis-6379/redis.conf
./redis-6.2.4/src/redis-server redis-6380/redis.conf
./redis-6.2.4/src/redis-server redis-6381/redis.conf
2.2 三个哨兵
将哨兵配置文件分别复制到 sentinel26379 sentinel26380 sentinel26381,需要注意的是每个文件的端口配置以及 sentinel monitor mymaster 192.169.0.1 6379 2 中最后的数字 2,哨兵集群汇总每个节点必须一致。
- 分别修改这三个配置文件:
# 绑定IP
bind 0.0.0.0
# 后台运行
daemonize yes
# 默认yes,没指定密码或者指定IP的情况下,外网无法访问
protected-mode no
# 哨兵的端口,客户端通过这个端口来发现redis
port 26379
# 这个文件会自动生成(如果同一台服务器上启动,注意要修改为不同的端口)
pidfile /var/run/redis-sentinel-26379.pid
# sentinel 监控的 master 的名字叫做 mymaster,初始地址为 127.0.0.1 6379,2代表两个及以上哨兵认定为故障,才认为是真的故障
sentinel monitor mymaster 192.169.0.1 6379 2
- 启动哨兵集群
./redis-6.2.4/src/redis-sentinel sentinel26379/sentinel.conf
./redis-6.2.4/src/redis-sentinel sentinel26380/sentinel.conf
./redis-6.2.4/src/redis-sentinel sentinel26381/sentinel.conf
- 查看 sentinel 监控的 master-slave 信息:
redis-cli -h 192.168.0.1 -p 26379
sentinel master mymaster
SENTINEL replicas mymaster
SENTINEL sentinels mymaster
- 测试故障自动转移
redis-cli -p 6379 DEBUG sleep 30
- 再次检查当前 master 地址,这次将得到不同的响应:
SENTINEL get-master-addr-by-name mymaster
3. Redis Sentinel 原理剖析
3.1 什么哨兵模式
哨兵是 Redis 的⼀种运⾏模式,它专注于对 Redis 实例(主节点、从节点)运⾏状态的监控,并能够在主节点发⽣故障时通过⼀系列的机制实现选主及主从切换,实现故障转移,确保整个 Redis 系统的可⽤性。
-
Redis提供了哨兵的命令,是⼀个独⽴的进程;
-
哨兵通过发送命令给多个节点,等待 Redis 服务器响应,从⽽监控运⾏的多个 Redis 实例的运⾏情况;
-
当哨兵监测到 Master 宕机,会⾃动将 Slave 切换成 Master,通过通知其他的从服务器,修改配置⽂件切换主机。
3.2 哨兵机制的主要任务
Redis Sentinel 在不使用 Redis 集群时为 Redis 提供高可用性。结合 官方文档 - Redis Sentinel,可以知道 Redis 哨兵具备的能⼒有如下⼏个:
-
监控:Sentinel 会持续监测 master、slave 是否处于预期工作状态;
-
自动故障转移:当 Master 运⾏故障,哨兵启动⾃动故障恢复流程:从 slave 中选择⼀台作为新 master;
-
通知:让 slave 执⾏ replicaof ,与新的 master 同步;并且通知客户端与新 master 建⽴连接;
-
配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
3.2.1 监控
(1)每1s发送一次 PING 命令
哨兵模式启用的时候,会同步启用 sentinel 的进程。sentinel 进程会向所有的 master 和 slaves 以及其他 sentinel进程 发送1s一次 PING 命令(心跳包)
。
-
如果 slave 没有在规定的时间内响应 sentinel 的 PING 命令 , sentinel 会认为该实例已经挂了,将它记录为:「下线状态」;
-
同理,如果 master 没有在规定时间响应 sentinel 的 PING 命令,也会被判定为 offline 状态,开始执行 「自动切换 master 」 的流程。
(2)PING 命令的回复有两种情况
- 有效回复:返回 +PONG、-LOADING、-MASTERDOWN 任何一种;
- 无效回复:有效回复之外的回复,或者指定时间内返回任何回复。
但是还是可能存在因为网络拥塞、master实例假死、请求延迟等导致实例在某个短暂时间段不可用,后续又快速恢复了。如果这时候被我们主动下线了,其实整个系统的可用性反而遭到了退化;而且误判之后的一系列操作,master竞选、消息通知,slave 与新 master 同步数据,都会消耗大量资源。
为了保证判断的可靠性,Redis 对下线的标识做了区分:一种是主观下线
,一种是客观下线
。
(3)主观下线和客观下线
- 主观下线
哨兵利用 PING 命令来监测 master、 slave 实例节点的生命状态。如果是无效回复,哨兵就把这个实例节点标记为 「主观下线」。如果是 slave,一般是一主多从
,直接下线即可;但如果是 master,就要小心了:一个 sentinel 实例很容易造成误判,那就可以多个 sentinel 实例一起投票判断。
哨兵机制
就是这样的,采用多个实例组成 sentinel 集群模式进行部署,即哨兵集群
。多个哨兵实例一起来判断,就可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况。
同时,多个哨兵的网络同时不稳定的概率较小,由它们一起做决策,误判率也能降低。
- 客观下线
master 是否要下线不能是单个 sentinel 实例来决定,上面说了一般会有多个 sentinel 实例(即sentinel集群)。只有当 sentinel 集群里的实例过半判断 master 已经 「主观下线」 了,这时候我们就把 master 标记为 「客观下线」。
当 master 被判定为客观下线后,才会进⼀步触发哨兵执行主从切换流程。
- 如何区别主官下线、客观下线
主观下线是 sentinel 实例自己认为节点 offline,这时候节点并不是真正的下线;而客观下线是达到一定数量的 sentinel 实例(比如超过一半)都认为节点 offline 了,这时候会进一步触发离线、重新竞选主等一系列操作。
这里的「一定数量」是一个法定数量(Quorum),是由哨兵监控配置决定的:
# sentinel monitor <master-name> <master-host> <master-port> <quorum>
# 举例如下:
sentinel monitor mymaster 192.168.0.1 6379 2
-
sentinel monitor:代表监控。
-
mymaster:代表主节点的名称,可以自定义。
-
192.168.0.1:代表监控的主节点 ip,6379 代表端口。
-
2:法定数量,代表只有两个或两个以上的哨兵认为主节点不可用的时候,才会把 master 设置为客观下线状态,然后进行 failover 操作。
客观下线的标准就是,当有 N 个哨兵实例时,要有 N/2 + 1 个实例判断 master 为 主观下线 ,才能最终判定 master 为 客观下线 ,其实就是过半机制
。
3.2.2 主从动态切换
sentinel 的一个很重要工作,就是从多个 slave 中选举出一个新的 master。当然,这个选举的过程会比较严谨,需要通过筛选 + 综合评估
方式进行选举。
(1)筛选
-
过滤掉不健康的(下线或者断线),没有回复哨兵 PING 命令的从节点。
-
评估实例过往的网络连接状况
down-after-milliseconds
,如果一定周期内(如24h)从库和主库经常断连,而且超出了一定的阈值(如 10 次),则该 slave 不予考虑。
这样,就保留下比较健康的实例了。
(2)综合评估
筛选掉不健康的实例之后,我们就可以对于剩下健康的实例按顺序进行综合评估了。
-
slave 优先级:通过 slave-priority 配置项(redis.conf),可以给不同的从库设置不同优先级,优先级高的优先成为 master。
-
选择数据偏移量差距最小的:即 slave_repl_offset 与 master_repl_offset 进度差距,其实就是比较 slave 与原 master 复制进度差距。
-
slave runID:在优先级和复制进度都相同的情况下,选用 runID 最小的,runID 越小说明创建时间越早,优先选为 master。先来后到原则。
等这几个条件都评估完,我们就会选择出最适合 slave,把他推举为新的 master。
3.2.3 通知
推选出最新的 master 之后,后续所有的写操作都会进入这个 master 中。所以需要尽快通知到所有的 slave,让他们重新 replacaof 到 master 上,重新建立 runID 和 slave_repl_offset ,来保证数据的正常传输和主从一致性。如下图所示:
3.3 哨兵机制的工作原理
3.3.1 pub/sub 实现哨兵间通信和发现 slave
集群中的哨兵如何实现通信?
哨兵之间可以相互通信,主要归功于 Redis 的 pub/sub 发布/订阅机制`。哨兵与 master 建立通信之后,可以利用 master 提供发布/订阅机制发布自己的 ip、port 等信息
master 有一个 sentinel:hello 的专用通道,用于哨兵之间发布和订阅消息
。哨兵们都可以通过该通道发布自己的 name、ip、port 消息,同时订阅其他哨兵发布的 name、ip、port 消息。互相发现之后建立起了连接,后续的消息通信就可以直接进行了。
这个与微服务中的服务注册与发现,以及RPC通信类似的整套做法类似。
3.3.2 选择哨兵执⾏主从切换
哨兵如何与 slave 实现连接?
-
sentinel 向 master 发送 INFO 命令
-
master 返回与之关联的 slave 列表
-
sentinel 根据 master 返回的 slave 列表,逐个与 salve 建立连接,并且根据这个连接持续监控
3.3.3 通过 pub/sub 实现客户端事件通知
哨兵如何与客户端进行事件通知?
通过 pub/sub 机制,发布不同事件,让客户端在这里订阅消息
。客户端可以订阅哨兵的消息,哨兵提供的消息订阅频道有很多,不同频道包含了主从库切换过程中的不同关键事件。
4. 总结
4.1 哨兵主要任务
Redis Sentinel 在不使用 Redis 集群时为 Redis 提供高可用性
。主从架构集群的数据同步,是数据可靠
性的基础保障;主库宕机,自动执行主从切换是服务不间断的关键支撑。
-
监控 master 与 slave 运行状态,判断是否客观下线;
-
master 客观下线后,选择一个 slave 切换成 master;
-
通知 slave 和客户端新 master 信息。
4.2 哨兵集群原理
为了避免单个哨兵故障后无法进行主从切换,以及为了减少误判率,又引入了哨兵集群;哨兵集群又需要有一些机制来支撑它的正常运行:
-
基于 pub/sub 机制实现哨兵集群之间的通信;
-
基于 INFO 命令获取 slave 列表,帮助哨兵与 slave 建立连接;
-
通过哨兵的 pub/sub,实现了与客户端和哨兵之间的事件通知。
-
主从切换,并不是随意选择一个哨兵就可以执行,而是通过投票选举,选择一个 master,由这个 master 负责主从切换。
Redis 6.X Sentinel 哨兵集群搭建
相关文章:

【Redis】高可用架构之哨兵模式 - Sentinel
Redis 高可用架构之哨兵模式 - Sentinel1. 前言2. Redis Sentinel 哨兵集群搭建2.1 一主两从2.2 三个哨兵3. Redis Sentinel 原理剖析3.1 什么哨兵模式3.2 哨兵机制的主要任务3.2.1 监控(1)每1s发送一次 PING 命令(2)PING 命令的回…...

图片的美白与美化
博主简介 博主是一名大二学生,主攻人工智能研究。感谢让我们在CSDN相遇,博主致力于在这里分享关于人工智能,c,Python,爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主,博主会继续更新的,…...

面试官:关于CPU你了解多少?
CPU是如何执行程序的? 程序执行的基本过程 第一步,CPU 读取「程序计数器」的值,这个值是指令的内存地址,然后 CPU 的「控制单元」操作「地址总线」指定需要访问的内存地址,接着通知内存设备准备数据,数据准…...
UI自动化测试-Selenium的使用
文章目录 1. 环境搭建1.1 入门示例1.2 元素操作常用方法1.3 浏览器操作常用方法1.4 获取元素信息常用方法1.5 鼠标操作常用方法1.6 键盘操作常用方法1.7 下拉选择框操作2. 元素定位2.1 id定位2.2 name定位2.3 class_name定位2.4 tag_name定位2.5 link_text定位2.6 partail_link…...

嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
文章目录前言USART的相关寄存器介绍状态寄存器:USARTX->SR具体位代表的含义实际代码数据寄存器 USARTX->DR波特率寄存器 USARTX->BRR控制寄存器 (USART_CR)控制寄存器1(USART_CR1)控制寄存器2(USART_CR2)GPIO…...

Android setContentView流程分析(一)
对于做Android App的小伙伴来说setContentView这个方法再熟悉不过了,那么有多少小伙伴知道它的调用到底做了多少事情呢?下面就让我们来看看它背后的故事吧? setContentView()方法将分为两节来讲: 第一节:如何获取De…...

doris数据库操作数字遇到的问题
关于doris数据库Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库,以极速易用的特点被人们所熟知,仅需亚秒级响应时间即可返回海量数据下的查询结果,不仅可以支持高并发的点查询场景,也能支持高吞吐的复杂分析场景。…...

3.13文件的IO操作
一.文件1.定义文件一般指的是存储在硬盘上的普通文件形如:txt.jpg.mp4,rar等这些文件在计算机中,文件可能是一个广义的概念,不仅可以包含普通文件,还可以包含目录(也就是文件夹.把目录称为目录文件)在操作系统中,还会用文件来描述一些其他的硬件设备或者软件资源比如网卡,显示器…...

ffmpeg使用
1 下载FFmpeg安装 官网地址:https://www.ffmpeg.org/download.html#build-windows 进入网址,点击下面红框部分 点击下面范围进行下载,下载速度有点慢,等等吧! 下载成功后,解压后,复制bin的路…...
spark中的并行度(分区数)/分区器如何确定
源头RDD有自己的分区计算逻辑,一般没有分区器,并行度是根据分区算法自动计算的,RDD的compute函数中记录了数据如何而来,如何分区的hadoopRDD,根据XxxinputFormat.getInputSplits()来决定,比如默认的TextInputFormat将文…...

00后女生“云摆摊”两周赚1.5万,实体店转战线上真的能赚钱吗?
最近,山东临沂的00后女生利用小程序在线上“云摆摊”卖水果,两周赚1.5万,引发网友热议。不少人发出质疑的声音:年轻人不要有稳定的工作不做,去摆摊;网上开店成本低,开实体店结果就难说了&#x…...
华为OD机试题 - 最优资源分配(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:最优资源分配题目输入输出描述备注示例一输入输出说明示例二输入…...
利用python判断字符串是否为回文
1 问题 如何用python判断字符串是否为回文。 2 方法 用两个变量left,right模仿指针(一个指向第一个字符,一个指向最后一个字符),每比对成功一次,left向右移动一位,right向左移动一位,…...

GDB 调用之ptype、set variable
今天在公司的时候,排查一个问题,创建l3 lif 失败,查看各种日志发现是用key去创建的 lif失败了,日志里指示key为空,导致的创建失败。原因为一个结构体比基线的多了一些东西,导致版本不对,既而计算…...

并发编程---阻塞队列(五)
阻塞队列一 阻塞队列1.1.阻塞队列概念1.2.阻塞队列API案例1.2.1. ArrayBlockingQueue1.2.1.1.抛出异常1.2.1.2.返回布尔1.2.1.3.阻塞1.2.1.4.超时1.2.2.SynchronousQueue二 阻塞队列应用---生产者消费者2.1.传统模式案例代码结果案例问题---防止虚假唤醒2.2.⽣产者消费者防⽌虚…...
本科课程【计算机组成原理】实验1 - 输出ABCD程序的生成
大家好,我是【1+1=王】, 热爱java的计算机(人工智能)渣硕研究生在读。 如果你也对java、人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!! Good better best, never let it rest, until good is better, and better best. 近期会把自己本科阶段的一些课程设计、实验报…...

Java并发编程(2) —— 线程创建的方式与原理
一、Java线程创建的三种方式 1. 继承Thread类并重写run()方法 ///方法一:使用匿名内部类重写Thread的run()方法Thread t1 new Thread() {Overridepublic void run() {try {sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}log.debug("…...
你写的js性能有多差你知道吗 | js性能优化
性能的计算⽅式 确认⾃⼰需要关注的指标 常⻅的指标有: ⻚⾯总加载时间 load⾸屏时间⽩屏时间 代码 尝试⽤⼀个指令, 挂载在重要元素上, 当此元素inserted就上报 各个属性所代表的含义 connectStart, connectEnd 分别代表TCP建⽴连接和连接成功的时间节点。如果浏…...

线程的状态、状态之间的相互转换
目录 一、线程的状态 1. NEW 2. TERMINATED 3. RUNNABLE 4. TIMED_WAITING 5. BLOCKED 6. WAITING 二、线程状态转换 1. 线程状态转换简图 一、线程的状态 线程的状态一共有 6 种: NEW:安排了工作,还未开始行动(调用 st…...

Java8使用Lambda表达式(流式)快速实现List转map 、分组、过滤等操作
利用java8新特性,可以用简洁高效的代码来实现一些数据处理。1 数据准备1.1 定义1个Fruit对象package com.wkf.workrecord.work;import org.junit.Test;import java.math.BigDecimal; import java.util.ArrayList; import java.util.List;/*** author wuKeFan* date …...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...