**摘要:**本文围绕高可用体系建设展开,重点澄清高可用不等于强一致性、集群不等于备份、复制也不等于容灾。内容涵盖 Redis Sentinel 与 Cluster 高可用方案、开发测试生产环境一致性、Syslog 日志级别、容器时间同步、Ansible 自动化管理、Nginx 与 Keepalived 高可用、MySQL 主从复制、备份体系以及日志排错等核心知识点,并结合常见误区进行纠偏和复习总结。
0. 先建立整体认识
高可用不是简单地把服务部署成集群,而是同时考虑:
- 服务是否可以持续访问
- 单节点故障后是否能自动切换
- 数据是否可靠、是否会发生丢失
- 故障发生后能否快速定位和恢复
- 是否有备份、监控、告警和应急流程
常见指标:
- 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 的主要工作:
- 监控 Master 和 Replica
- 判断 Master 是否真实故障
- 选举一个 Sentinel 作为故障切换领导者
- 将一个 Replica 提升为新的 Master
- 更新其他 Replica 的复制关系
- 通知客户端新的 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
理解:
- 代码提交后自动构建
- 自动执行单元测试和静态检查
- 构建不可变镜像
- 推送镜像到镜像仓库
- 测试环境自动部署
- 生产环境经过审批后发布
- 同一镜像在不同环境逐级晋级
生产环境不应该重新编译一份代码,而应该:
同一个构建产物,经过测试后晋级到生产。
Kubernetes Namespace 可以隔离资源,但它不是天然的安全边界。生产环境还需要:
- RBAC
- NetworkPolicy
- ResourceQuota
- LimitRange
- 独立密钥
- 独立镜像仓库权限
- 必要时使用独立集群
3. Syslog 日志级别
数字越小,级别越高,越严重。
| 级别 | 名称 | 含义 | 典型场景 |
|---|---|---|---|
| 0 | emerg | 系统不可用 | 内核崩溃、系统无法继续运行 |
| 1 | alert | 必须立即处理 | 数据库损坏、核心服务不可用 |
| 2 | crit | 严重错误 | 磁盘即将故障、关键资源耗尽 |
| 3 | err | 一般错误 | 请求处理失败、服务异常 |
| 4 | warning | 警告 | 磁盘使用率偏高、连接数接近上限 |
| 5 | notice | 正常但重要 | 用户登录成功、服务启动 |
| 6 | info | 一般信息 | 请求日志、正常状态变化 |
| 7 | debug | 调试信息 | 最详细,仅排障时开启 |
生产环境日志建议:
- 正常运行使用
info或warning - 排障时临时开启
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 Collectionnetwork_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:配置变化时触发 handlerhandlers:通常用于重启或 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_schemasys库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 崩溃恢复
- 逻辑备份可使用
mysqldump、mysqlpump等
8.3 Redis 备份
- RDB:周期快照,恢复速度快,但可能丢失部分数据
- AOF:记录写命令,数据更完整,但文件更大
- 混合持久化:RDB + AOF,生产中较常见
- 主从复制不能替代备份
8.4 备份原则
- 3 份数据
- 2 种介质
- 1 份异地
- 备份加密
- 定期恢复演练
- 监控备份是否成功
- 明确 RPO 和 RTO
9. 日志与排错
排错基本顺序:
- 确认影响范围
- 确认故障开始时间
- 查看最近变更
- 查看监控指标
- 查看应用日志
- 查看系统日志
- 查看网络和磁盘
- 查看数据库和中间件
- 进行复现和验证
- 修复后观察一段时间
- 记录复盘和改进项
常用命令:
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
高可用:
冗余 + 健康检查 + 自动切换 + 数据一致性
有状态服务:
主从 + 复制 + 持久化 + 故障切换 + 备份
排错:
先止损,再看范围,再看变更,最后查日志和指标
备份:
备份成功不算成功,能恢复才算成功