高可用总结

**摘要:**本文围绕高可用体系建设展开,重点澄清高可用不等于强一致性、集群不等于备份、复制也不等于容灾。内容涵盖 Redis Sentinel 与 Cluster 高可用方案、开发测试生产环境一致性、Syslog 日志级别、容器时间同步、Ansible 自动化管理、Nginx 与 Keepalived 高可用、MySQL 主从复制、备份体系以及日志排错等核心知识点,并结合常见误区进行纠偏和复习总结。

0. 先建立整体认识

高可用不是简单地把服务部署成集群,而是同时考虑:

  1. 服务是否可以持续访问
  2. 单节点故障后是否能自动切换
  3. 数据是否可靠、是否会发生丢失
  4. 故障发生后能否快速定位和恢复
  5. 是否有备份、监控、告警和应急流程

常见指标:

  • MTBF:平均无故障时间
  • MTTR:平均恢复时间
  • RTO:业务恢复目标时间
  • RPO:允许丢失的数据时间范围

高可用 = 冗余 + 健康检查 + 自动切换 + 数据一致性 + 可恢复能力。

1. Redis 高可用

分布式系统中,参与投票的多数节点在线,才能完成主节点选举和故障切换。

这里的"多数"指的是投票节点,不是业务实例数量。

例如:

Sentinel 数量 达成多数需要
3 个 至少 2 个
5 个 至少 3 个
7 个 至少 4 个

大多数分布式系统要求奇数个投票节点,就是为了避免出现两个投票结果相同的情况。

需要注意:

  • 多数节点在线,解决的主要是高可用和故障切换问题
  • 多数节点在线,不等于数据一定强一致
  • Redis 默认使用异步复制
  • 主节点宕机时,最近还没有同步到从节点的数据可能丢失

Redis 高可用不等于 Redis 强一致。

1.2 Redis Sentinel 模式

Sentinel 适合中小规模场景。

数据拓扑:

text 复制代码
         +-------------+
         |   Master    |
         +------+------+
                |
       +--------+--------+
       |                 |
+------+------+   +------+------+
|  Replica 1  |   |  Replica 2  |
+-------------+   +-------------+

特点:

  • 1 个主节点负责写入
  • 多个从节点负责读取
  • Sentinel 负责监控、判断故障和自动切换
  • 读性能可以横向扩展
  • 写性能仍然受限于单个 Master
  • 数据量不能超过单机内存容量

Sentinel 节点一般至少部署 3 个,并且不要全部放在同一台机器上。

Sentinel 的主要工作:

  1. 监控 Master 和 Replica
  2. 判断 Master 是否真实故障
  3. 选举一个 Sentinel 作为故障切换领导者
  4. 将一个 Replica 提升为新的 Master
  5. 更新其他 Replica 的复制关系
  6. 通知客户端新的 Master 地址

故障判断通常分为:

  • 主观下线 SDOWN:单个 Sentinel 认为 Master 不可用
  • 客观下线 ODOWN:多个 Sentinel 共同确认 Master 不可用

注意两个概念:

  • quorum:判断故障需要多少个 Sentinel 同意
  • majority:真正执行故障切换需要多数 Sentinel 授权

1.3 Redis Cluster 模式

Redis Cluster 适合数据量大、写入量大的场景。

原笔记中的最小规模:

text 复制代码
至少 6 台节点
3 个 Master
3 个 Replica

Redis Cluster 使用 16384 个哈希槽:

text 复制代码
Key
 |
 v
CRC16 计算
 |
 v
16384 取模
 |
 v
对应 Slot
 |
 v
对应 Master

特点:

  • 数据分片存储
  • 可以横向扩展内存
  • 可以扩展写能力
  • 某个 Master 故障后,可以提升它的 Replica
  • 不同 Key 可能分布在不同节点
  • 多 Key 操作、事务和 Lua 脚本通常要求 Key 在同一个 Slot

Redis Cluster 不是没有代价:

  • 客户端必须支持 Cluster
  • 运维复杂度更高
  • 扩容、缩容和迁移 Slot 需要谨慎操作
  • 多 Key 操作容易踩坑
  • 异步复制仍然可能丢数据

1.4 Sentinel 和 Cluster 怎么选

场景 推荐方案
数据量能放进单机内存 Sentinel
读多写少 Sentinel + 多个 Replica
写入量大 Redis Cluster
数据量超过单机内存 Redis Cluster
中小型业务 Sentinel
大型业务或云原生平台 托管 Redis 或 Cluster
强一致要求高 不能只看 Redis,需要重新评估方案

2. 开发、测试、生产环境一致性

原笔记的典型问题:

text 复制代码
开发:Windows / macOS
测试:Linux 虚拟机
生产:物理机或虚拟机

底层环境不一致会导致:

  • 依赖版本不同
  • 动态库不同
  • 文件路径不同
  • 字符编码不同
  • 时区不同
  • 权限模型不同
  • 内核参数不同
  • 网络行为不同

容器化的价值在于:

把应用代码、运行环境和依赖打包成同一镜像,减少环境差异。

但容器不能解决所有问题:

  • 容器共享宿主机内核
  • 宿主机内核版本仍然可能不同
  • 生产网络、存储、权限和容器编排环境仍然可能不同
  • 配置和密钥必须按环境隔离

CI/CD 多分支流水线

text 复制代码
生产线:
client -> v2 -> v3
k8s-namespace1
测试线:
client
k8s-namespace2
v3 -> v4

理解:

  1. 代码提交后自动构建
  2. 自动执行单元测试和静态检查
  3. 构建不可变镜像
  4. 推送镜像到镜像仓库
  5. 测试环境自动部署
  6. 生产环境经过审批后发布
  7. 同一镜像在不同环境逐级晋级

生产环境不应该重新编译一份代码,而应该:

同一个构建产物,经过测试后晋级到生产。

Kubernetes Namespace 可以隔离资源,但它不是天然的安全边界。生产环境还需要:

  • RBAC
  • NetworkPolicy
  • ResourceQuota
  • LimitRange
  • 独立密钥
  • 独立镜像仓库权限
  • 必要时使用独立集群

3. Syslog 日志级别

数字越小,级别越高,越严重。

级别 名称 含义 典型场景
0 emerg 系统不可用 内核崩溃、系统无法继续运行
1 alert 必须立即处理 数据库损坏、核心服务不可用
2 crit 严重错误 磁盘即将故障、关键资源耗尽
3 err 一般错误 请求处理失败、服务异常
4 warning 警告 磁盘使用率偏高、连接数接近上限
5 notice 正常但重要 用户登录成功、服务启动
6 info 一般信息 请求日志、正常状态变化
7 debug 调试信息 最详细,仅排障时开启

生产环境日志建议:

  • 正常运行使用 infowarning
  • 排障时临时开启 debug
  • 不要长期开启大量 debug
  • 不要记录密码、Token、身份证、银行卡等敏感信息
  • 日志要有时间、主机、服务、请求 ID
  • 日志应集中收集,避免只存在单台机器
  • 配置日志轮转、保留周期和磁盘告警

4. 容器时间不一致问题

容器默认使用宿主机时钟。

TZ 环境变量主要影响时间显示,不一定能修复系统时间错误。

真正的时间同步应该在宿主机完成:

bash 复制代码
timedatectl
chronyc sources -v

Ansible 创建 Nginx 容器的示例:

yaml 复制代码
- name: 创建 Nginx 容器
  community.docker.docker_container:
    name: nginx
    image: "nginx:{{ nginx_version }}"
    state: started
    restart_policy: always
    network_mode: host
    env:
      TZ: Asia/Shanghai
    volumes:
      - /data/nginx-ansible/conf:/etc/nginx/conf.d
      - /data/nginx-ansible/logs:/var/log/nginx
      - /data/nginx-ansible/html:/usr/share/nginx/html

补充说明:

  • community.docker 需要安装 Ansible Collection
  • network_mode: host 表示容器直接使用宿主机网络
  • 生产环境不一定适合使用 host 网络
  • 挂载日志目录时要注意宿主机和容器用户权限
  • 如果镜像中没有时区文件,可以安装 tzdata
  • 容器时间错误时,先检查宿主机时间,不要只在容器里调整

验证:

bash 复制代码
date
timedatectl
docker exec nginx date

5. Ansible 管理思路

text 复制代码
批量部署,统一管理
SSH 免密
模块:shell、copy、dnf、file 等
Playbook:控制谁、怎么控制
notify 和 handlers 处理服务重启

补充:

5.1 Inventory 控制管理范围

ini 复制代码
[web]
node1 ansible_host=192.168.88.101
node2 ansible_host=192.168.88.102
[redis]
node3 ansible_host=192.168.88.103

5.2 Playbook 控制执行步骤

yaml 复制代码
- name: 配置 Web 服务器
  hosts: web
  become: true
  tasks:
    - name: 安装 Nginx
      dnf:
        name: nginx
        state: present
    - name: 复制 Nginx 配置
      copy:
        src: nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: reload nginx
  handlers:
    - name: reload nginx
      systemd:
        name: nginx
        state: reloaded

关键点:

  • hosts:控制哪些机器
  • tasks:控制做什么
  • notify:配置变化时触发 handler
  • handlers:通常用于重启或 reload 服务
  • become:需要提权时使用
  • 密码和密钥应使用 ansible-vault 管理
  • 生产环境不建议所有机器统一使用 root 私钥

6. Nginx 高可用

Nginx 通常是无状态服务,或者只提供静态数据。

常见能力:

  • Web 服务器
  • 反向代理
  • 负载均衡
  • TLS 终止
  • 缓存
  • 压缩
  • 动静分离
  • 限流和访问控制

6.1 负载均衡算法

算法 特点
round-robin 轮询,默认方式
weight 按权重分配
least_conn 转发给连接数最少的后端
ip_hash 按客户端 IP 保持会话
hash 按指定 Key 分流
random 随机选择

6.2 Keepalived 高可用

Keepalived 通过 VRRP 提供虚拟 IP:

text 复制代码
Client
  |
  v
VIP 192.168.88.200
  |
  +--> Nginx 1
  +--> Nginx 2

主要概念:

  • VIP:统一访问入口
  • MASTER / BACKUP:主备状态
  • priority:优先级
  • preempt:是否抢占
  • nopreempt:不抢占
  • VRRP:虚拟路由冗余协议
  • 健康检查:确认本机 Nginx 是否可用
  • 脑裂:主备节点互相失去心跳,都认为自己是主节点

Keepalived 需要配套健康检查,否则可能出现:

text 复制代码
VIP 还在本机
但本机 Nginx 已经挂了

注意纠偏:

Sentinel 属于 Redis 高可用组件,不是 Nginx 高可用组件。

7. 有状态服务

7.1 Redis

  • 写永远进入 Master
  • Replica 主要用于读扩展和故障接管
  • 写性能受单 Master 限制
  • 读性能可以通过多个 Replica 扩展
  • 默认异步复制
  • Sentinel 负责故障切换
  • RDB 和 AOF 负责持久化
  • 复制不等于备份

7.2 MySQL 架构层级

可以用餐厅类比理解:

层级 作用 类比
连接层 认证、连接、线程 迎宾和接待
服务层 解析、优化、执行 SQL 点单和调度
引擎层 InnoDB 等存储引擎 厨师
存储层 表空间、Redo、Undo、Binlog 仓库

常用分析工具:

sql 复制代码
SHOW PROCESSLIST;
EXPLAIN SELECT ...;
SHOW PROFILE;  -- 旧版本常见,新版本逐渐废弃

现代 MySQL 更推荐使用:

  • performance_schema
  • sys
  • EXPLAIN ANALYZE

7.3 MySQL 主从复制

主从基本流程:

text 复制代码
Master 写 Binlog
    |
    v
Replica 拉取 Binlog
    |
    v
写入 Relay Log
    |
    v
SQL 线程重放

特点:

  • 只有 Master 具备写入权限
  • Replica 通常用于读扩展和备份
  • Binlog 用于复制和按时间点恢复
  • GTID = 源实例 UUID + 事务 ID
  • 主从复制默认通常是异步的
  • 单纯依赖 Binlog 或 GTID,并不会自动完成故障切换

要实现自动切换,还需要:

  • MHA
  • Orchestrator
  • MySQL Group Replication
  • InnoDB Cluster
  • MySQL Router
  • ProxySQL 等中间件
  • 云数据库的自动主备切换能力

注意纠偏:

Redis 的 AOF 负责持久化,不负责故障切换;Redis 自动故障切换主要依靠 Sentinel 或 Cluster。

8. 备份体系

8.1 备份分类

类型 优点 缺点
物理备份 快,恢复快 文件大,跨版本兼容性差
逻辑备份 可读性好,便于迁移 慢,恢复时间长
全量备份 恢复简单 占用空间大
增量备份 节省空间 恢复链路复杂

8.2 MySQL 备份

常见组合:

text 复制代码
XtraBackup 物理备份
+
Binlog
+
Redo Log

说明:

  • XtraBackup 适合 InnoDB 热备
  • Binlog 用于时间点恢复
  • Redo Log 用于 InnoDB 崩溃恢复
  • 逻辑备份可使用 mysqldumpmysqlpump

8.3 Redis 备份

  • RDB:周期快照,恢复速度快,但可能丢失部分数据
  • AOF:记录写命令,数据更完整,但文件更大
  • 混合持久化:RDB + AOF,生产中较常见
  • 主从复制不能替代备份

8.4 备份原则

  • 3 份数据
  • 2 种介质
  • 1 份异地
  • 备份加密
  • 定期恢复演练
  • 监控备份是否成功
  • 明确 RPO 和 RTO

9. 日志与排错

排错基本顺序:

  1. 确认影响范围
  2. 确认故障开始时间
  3. 查看最近变更
  4. 查看监控指标
  5. 查看应用日志
  6. 查看系统日志
  7. 查看网络和磁盘
  8. 查看数据库和中间件
  9. 进行复现和验证
  10. 修复后观察一段时间
  11. 记录复盘和改进项

常用命令:

bash 复制代码
journalctl -xe
dmesg -T
ss -lntup
df -hT
free -h
top
iostat -x 1
vmstat 1
pidstat 1
tcpdump -i any port 80
curl -v http://127.0.0.1

生产环境还应具备:

  • 集中日志平台
  • 请求链路 ID
  • 日志采集和检索
  • 关键错误告警
  • 日志轮转
  • 日志保留策略

10. 云计算、虚拟化和容器

10.1 云计算分层

  • 虚拟化云:OpenStack、VMware 等
  • 容器云:Kubernetes 等
  • 云操作系统:负责资源整合、管理和调度
  • 底层资源:计算、存储、网络
  • 上层能力:数据库、中间件、监控、备份等

Kubernetes:

  • 容器编排平台
  • 底层常用 Docker、containerd
  • 负责调度容器、网络、存储和服务发现

OpenStack:

  • IaaS 云平台
  • 底层常用 KVM、QEMU
  • 管理虚拟机、网络、存储等资源

需要纠正一点:

云平台不制造硬件资源,但会负责资源的分配、调度和对外提供。

10.2 虚拟化与容器

对比项 虚拟机 容器
内核 独立 Guest Kernel 共享宿主机内核
启动速度
资源开销
隔离强度 通常更强 通常较弱
部署密度
镜像大小
适用场景 强隔离、异构系统 微服务、快速交付

容器核心技术:

  • namespace:资源隔离
    • PID
    • Network
    • Mount
    • UTS
    • IPC
    • User
  • cgroups:资源限制
    • CPU
    • Memory
    • Block IO
    • PIDs
  • UnionFS:镜像分层和联合挂载
  • Capabilities:细粒度权限控制
  • seccomp:限制系统调用
  • SELinux / AppArmor:强制访问控制

安全性不能简单说容器一定更好:

  • 虚拟机通常隔离更强
  • 容器通常性能更好、密度更高
  • 多租户场景更偏向虚拟机或安全容器
  • 微服务和云原生场景更适合容器

12. 最后复习总结

12.1 Redis

  • Sentinel:1 主多从,读扩展,故障切换
  • Cluster:多主多从,数据分片,读写扩展
  • Sentinel 和 Cluster 都不等于强一致性
  • 异步复制可能丢失最近写入

12.2 Nginx

  • 无状态服务
  • 反向代理和负载均衡
  • Keepalived 提供 VIP 和故障切换
  • Sentinel 不属于 Nginx 高可用

12.3 MySQL

  • Binlog 用于复制和恢复
  • GTID 简化主从管理
  • 单纯主从不会自动故障切换
  • 需要 MHA、Orchestrator、MGR 等工具

12.4 备份

  • 复制不是备份
  • 快照不是备份
  • RDB/AOF 不是完整的容灾方案
  • 必须做恢复演练

12.5 云计算

  • OpenStack 更偏向虚拟化云
  • Kubernetes 更偏向容器云
  • 虚拟机隔离更强
  • 容器更轻量、更适合微服务

12.6 最终口诀

text 复制代码
高可用:
冗余 + 健康检查 + 自动切换 + 数据一致性
有状态服务:
主从 + 复制 + 持久化 + 故障切换 + 备份
排错:
先止损,再看范围,再看变更,最后查日志和指标
备份:
备份成功不算成功,能恢复才算成功
相关推荐
szephyr3 小时前
Nginx 反向代理实战:从 502、跨域到 HTTPS,一次打通
运维·nginx·https·部署·反向代理
迷茫的大专生3 小时前
服务器部署与 MySQL 运维学习笔记:从 Ansible 到高可用与性能优化
mysql·nginx·ansible·mysql优化·keepalive
辉灰笔记3 小时前
Redis6.0.10升级迁移至Redis7.4.6(修复CVE‑2025‑49844,业务无需重启)
redis·redis7·漏洞修复·数据库迁移·redis平滑升级·cve-2025-49844
Lyra_Infra3 小时前
从 MySQL 到达梦:一次信创隔离环境里的数据库迁移踩坑实录
数据库·后端·mysql
真上帝的左手4 小时前
10. 软件设计&架构-经典架构问题-高可用
系统架构·高可用
泡茶喝茶写代码4 小时前
量化数据开发实战系列(第 25 篇):基金基础接口实战:基金列表、ETF-LOF 分类、基金概况、净值数据
java·数据库·人工智能·python·mysql
sdm0704275 小时前
Linux 中安装 Redis 5
redis
worilb5 小时前
Win下使用同一套MySQL创建第二个独立实例
mysql
A心有千千结5 小时前
Nginx网关可观测建设:打通流量入口,加速线上故障诊断
nginx·prometheus·devops