定义:High Availability Architecture(高可用架构),是一种系统设计方法,目标是确保系统在大部分时间都能正常运行,即使在出现硬件故障、系统升级或其他潜在问题时,也能保持运行。
核心目标:
高可用目标:
"没日没夜都能正常运行"
├── 减少停机时间(计划内 + 意外)
├── 应对硬件故障
├── 应对系统升级
└── 应对其他潜在问题可用性等级:
| 可用性等级 | 可用性百分比 | 年停机时间 | 典型应用场景 |
|---|---|---|---|
| 1个9 | 90% | 36.5天 | 个人博客 |
| 2个9 | 99% | 3.65天 | 内部系统 |
| 3个9 | 99.9% | 8.76小时 | Web服务 |
| 4个9 | 99.99% | 52.6分钟 | 企业应用 |
| 5个9 | 99.999% | 5.26分钟 | 金融系统 |
| 6个9 | 99.9999% | 31.5秒 | 核心基础设施 |
计算公式:
// 可用性计算
const availabilityCalculation = {
formula: '可用性 = (总时间 - 停机时间) / 总时间 × 100%',
example: {
totalTime: 365 * 24 * 60, // 一年总分钟数
downtime: 8.76 * 60, // 停机时间(分钟)
availability: ((365 * 24 * 60 - 8.76 * 60) / (365 * 24 * 60) * 100).toFixed(3)
// 结果:99.9%
},
// 不同等级的年停机时间
levels: {
'99%': 3.65 * 24 * 60, // 3.65天
'99.9%': 8.76 * 60, // 8.76小时
'99.99%': 52.6, // 52.6分钟
'99.999%': 5.26, // 5.26分钟
'99.9999%': 0.526 // 31.5秒
}
}高可用三大保障场景:
┌─────────────────────────────────────────┐
│ 1. 本地高可用 │
│ ├── 消除系统故障、硬件故障 │
│ └── 生产环境内部故障 │
├─────────────────────────────────────────┤
│ 2. 业务逻辑保护 │
│ ├── 人为失误 │
│ └── 软件错误 │
├─────────────────────────────────────────┤
│ 3. 容灾多活 │
│ ├── 区域性灾难 │
│ └── 天然灾害 │
└─────────────────────────────────────────┘生产环境内部故障:
本地高可用故障类型:
硬件层面
├── 服务器故障(主板、CPU、内存)
├── 硬盘故障(坏道、损坏)
├── 网络适配器故障
└── 电源故障
网络层面
├── 交换机故障
├── 路由器故障
└── 网线断裂
存储层面
├── 存储阵列故障
├── SAN 故障
└── NAS 故障| 特点 | 说明 | 示例 |
|---|---|---|
| 恢复快 | 可快速恢复 | 磁盘RAID阵列,单盘故障不影响系统 |
| 实施简单 | 单点故障易更换 | 更换故障硬件 |
| 影响范围小 | 仅局部受影响 | 单个服务节点故障 |
1. 磁盘阵列(RAID)
// RAID 级别对比
const raidLevels = {
// RAID 0: 条带化(无冗余)
raid0: {
name: 'RAID 0',
minDisks: 2,
capacity: 'n × 单盘容量',
reliability: '低(任一盘故障,数据全丢)',
performance: '读/写性能最高',
useCase: '临时数据、缓存'
},
// RAID 1: 镜像
raid1: {
name: 'RAID 1',
minDisks: 2,
capacity: '单盘容量',
reliability: '高(允许1盘故障)',
performance: '读性能提升,写性能略降',
useCase: '操作系统盘、重要数据'
},
// RAID 5: 分布式奇偶校验
raid5: {
name: 'RAID 5',
minDisks: 3,
capacity: '(n-1) × 单盘容量',
reliability: '较高(允许1盘故障)',
performance: '读写性能均衡',
useCase: '数据库、文件服务器'
},
// RAID 10: RAID 1 + RAID 0
raid10: {
name: 'RAID 10',
minDisks: 4,
capacity: 'n/2 × 单盘容量',
reliability: '高(允许每组1盘故障)',
performance: '读/写性能高',
useCase: '数据库、高I/O应用'
}
}RAID 10 实现示例:
RAID 10 架构:
数据写入
↓
┌───────┴───────┐
│ RAID 0 条带化 │
└───────┬───────┘
│
┌───────┴───────┐
│ │
┌───┴───┐ ┌───┴───┐
│RAID 1 │ │RAID 1 │
│ 镜像1 │ │ 镜像2 │
└───┬───┘ └───┬───┘
│ │
┌───┴───┐ ┌───┴───┐
│磁盘1 │ │磁盘3 │
│磁盘2 │ │磁盘4 │
└───────┘ └───────┘
特点:
- 磁盘1和磁盘2互为镜像
- 磁盘3和磁盘4互为镜像
- 允许每组镜像中1块磁盘故障
- 读性能提升,写性能略降2. 网络冗余
网络冗余架构:
互联网
↓
┌───────┴───────┐
│ 主路由器 A │
└───────┬───────┘
│ HSRP/VRRP
┌───────┴───────┐
│ 备路由器 B │
└───────┬───────┘
↓
┌───────┴───────┐
│ 核心交换机 │
└───────┬───────┘
│
┌───────┴───────┐
│ │
┌───────┴───────┐ ┌───┴───────┐
│ 服务器集群 │ │ 服务器集群 │
└───────────────┘ └───────────┘
关键技术:
- HSRP (Hot Standby Router Protocol)
- VRRP (Virtual Router Redundancy Protocol)
- 链路聚合 (LACP)3. 电源冗余
电源冗余方案:
主电源 ──────┐
├──→ 服务器(双电源模块)
备用电源 ─────┘
UPS(不间断电源)
├── 稳压
├── 停电后持续供电
└── 给发电机启动预留时间
发电机
└── 长时间停电时供电人为失误 + 软件错误:
业务逻辑保护故障类型:
人为失误
├── 误删除数据
├── 错误配置
├── 发布错误应用
└── 操作失误
软件错误
├── 操作系统 bug
├── 数据库 bug
├── 应用 bug
└── 第三方库 bug
安全事件
├── 数据泄露
├── 恶意攻击
└── 商户跑路(数据丢失)| 特点 | 说明 | 解决方案 |
|---|---|---|
| 需要数据恢复 | 数据误删、篡改 | 快照、备份 |
| 需要决策干预 | 人为判断处理 | 监控告警、人工介入 |
| 需要问题追溯 | 查找原因 | 审计日志、追踪系统 |
1. 数据快照
// 数据快照实现
class DataSnapshot {
constructor() {
this.snapshots = new Map()
}
// 创建快照
createSnapshot(database, snapshotName) {
const timestamp = Date.now()
const snapshot = {
name: snapshotName,
timestamp,
data: this.cloneData(database),
size: this.calculateSize(database)
}
this.snapshots.set(snapshotName, snapshot)
console.log(`快照 ${snapshotName} 创建成功`)
console.log(`时间: ${new Date(timestamp).toLocaleString()}`)
console.log(`大小: ${snapshot.size} MB`)
return snapshot
}
// 恢复快照
restoreSnapshot(snapshotName, database) {
const snapshot = this.snapshots.get(snapshotName)
if (!snapshot) {
throw new Error(`快照 ${snapshotName} 不存在`)
}
// 恢复数据
Object.assign(database, snapshot.data)
console.log(`快照 ${snapshotName} 恢复成功`)
console.log(`快照时间: ${new Date(snapshot.timestamp).toLocaleString()}`)
return database
}
// 列出所有快照
listSnapshots() {
const list = []
this.snapshots.forEach((snapshot, name) => {
list.push({
name,
timestamp: new Date(snapshot.timestamp).toLocaleString(),
size: snapshot.size
})
})
return list
}
// 克隆数据
cloneData(data) {
return JSON.parse(JSON.stringify(data))
}
// 计算大小
calculateSize(data) {
const json = JSON.stringify(data)
return (Buffer.byteLength(json, 'utf8') / 1024 / 1024).toFixed(2)
}
}
// 使用示例
const snapshotManager = new DataSnapshot()
const database = {
users: [
{ id: 1, name: '张三', balance: 1000 },
{ id: 2, name: '李四', balance: 2000 }
]
}
// 创建快照
snapshotManager.createSnapshot(database, 'before_update')
// 模拟数据误操作
database.users[0].balance = 0
console.log('误操作后:', database.users[0])
// 恢复快照
snapshotManager.restoreSnapshot('before_update', database)
console.log('恢复后:', database.users[0])2. 审计日志
// 审计日志系统
class AuditLogger {
constructor() {
this.logs = []
}
// 记录操作日志
log(action, userId, details) {
const logEntry = {
timestamp: new Date().toISOString(),
action,
userId,
details,
ip: this.getClientIP(),
userAgent: this.getUserAgent()
}
this.logs.push(logEntry)
// 持久化存储
this.saveToFile(logEntry)
return logEntry
}
// 查询日志
query(filters) {
return this.logs.filter(log => {
if (filters.userId && log.userId !== filters.userId) return false
if (filters.action && log.action !== filters.action) return false
if (filters.startTime && new Date(log.timestamp) < new Date(filters.startTime)) return false
if (filters.endTime && new Date(log.timestamp) > new Date(filters.endTime)) return false
return true
})
}
// 保存到文件
saveToFile(logEntry) {
const logLine = JSON.stringify(logEntry) + '\n'
fs.appendFileSync('audit.log', logLine)
}
// 获取客户端 IP
getClientIP() {
return '192.168.1.100'
}
// 获取 User Agent
getUserAgent() {
return 'Mozilla/5.0 ...'
}
}
// 使用示例
const auditLogger = new AuditLogger()
// 记录用户操作
auditLogger.log('DELETE_USER', 'admin001', {
deletedUserId: 123,
reason: '违规操作'
})
auditLogger.log('UPDATE_BALANCE', 'admin002', {
userId: 456,
oldBalance: 1000,
newBalance: 500
})
// 查询日志
const logs = auditLogger.query({
userId: 'admin001',
startTime: '2024-01-01'
})3. 灰度发布
// 灰度发布系统
class CanaryDeployment {
constructor() {
this.versions = {
stable: { weight: 90, version: 'v1.0.0' },
canary: { weight: 10, version: 'v2.0.0' }
}
}
// 路由请求
route(userId) {
const hash = this.hashUserId(userId)
const percentage = hash % 100
if (percentage < this.versions.canary.weight) {
return this.versions.canary.version
} else {
return this.versions.stable.version
}
}
// 调整灰度比例
adjustWeight(canaryWeight) {
if (canaryWeight < 0 || canaryWeight > 100) {
throw new Error('权重必须在 0-100 之间')
}
this.versions.canary.weight = canaryWeight
this.versions.stable.weight = 100 - canaryWeight
console.log(`灰度比例调整: 稳定版 ${this.versions.stable.weight}%, 灰度版 ${this.versions.canary.weight}%`)
}
// 监控灰度版本
monitorCanary() {
const metrics = {
errorRate: this.getErrorRate('canary'),
latency: this.getAverageLatency('canary'),
throughput: this.getThroughput('canary')
}
// 自动回滚
if (metrics.errorRate > 0.05) {
console.log('灰度版本错误率过高,自动回滚')
this.rollback()
}
return metrics
}
// 回滚
rollback() {
this.versions.canary.weight = 0
this.versions.stable.weight = 100
console.log('已回滚到稳定版本')
}
// 哈希用户 ID
hashUserId(userId) {
let hash = 0
for (let char of String(userId)) {
hash = (hash << 5) - hash + char.charCodeAt(0)
}
return Math.abs(hash)
}
// 获取错误率
getErrorRate(version) {
// 模拟数据
return Math.random() * 0.1
}
// 获取平均延迟
getAverageLatency(version) {
return Math.random() * 100 + 50
}
// 获取吞吐量
getThroughput(version) {
return Math.floor(Math.random() * 1000 + 500)
}
}
// 使用示例
const canary = new CanaryDeployment()
// 路由用户请求
const version1 = canary.route('user123')
console.log(`用户 user123 路由到版本: ${version1}`)
// 逐步扩大灰度范围
canary.adjustWeight(20) // 20% 流量到灰度版本
// 监控灰度版本
const metrics = canary.monitorCanary()
console.log('灰度版本指标:', metrics)大面积机房设备故障:
容灾多活故障类型:
架构失效
├── 高可用架构失效
├── 主站点失效
└── 备站点失效
自然灾害
├── 地震
├── 火灾
├── 洪水
└── 台风
区域性故障
├── 大面积停电
├── 网络骨干故障
└── 数据中心损毁| 特点 | 说明 | 示例 |
|---|---|---|
| 恢复时间长 | 需要重建基础设施 | 机房火灾需要重建 |
| 手动切换 | 需要人工决策和干预 | 确认灾备中心接管 |
| 允许数据丢失 | 极端情况下可能丢失部分数据 | 非实时同步的数据 |
| 成本高 | 需要异地数据中心 | 维护多个数据中心 |
容灾等级分类:
Tier 0: 无异地备份
├── 无异地数据
├── 恢复时间: 数天到数周
└── 数据丢失: 全部
Tier 1: 本地磁带备份,异地保存
├── 每日备份,异地存储
├── 恢复时间: 数天
└── 数据丢失: 1天
Tier 2: 异地热备
├── 实时数据复制
├── 恢复时间: 数小时
└── 数据丢失: 数分钟
Tier 3: 异地双活
├── 两地同时服务
├── 恢复时间: 数分钟
└── 数据丢失: 秒级
Tier 4: 异地多活
├── 多地同时服务
├── 恢复时间: 秒级
└── 数据丢失: 01. 主备架构
主备架构:
┌─────────────────┐
│ 北京主数据中心 │
│ ├── 应用服务 │
│ ├── 数据库主 │
│ └── 存储主 │
└────────┬────────┘
│ 异步复制
↓
┌─────────────────┐
│ 上海备数据中心 │
│ ├── 应用服务 │
│ ├── 数据库从 │
│ └── 存储从 │
└─────────────────┘
特点:
- 成本较低
- 恢复时间: 数小时
- 数据丢失: 分钟级
- 适用: 中小型企业2. 双活架构
双活架构:
用户请求
↓
DNS 负载均衡
↓
┌────────┴────────┐
│ │
↓ ↓
┌─────────┐ ┌─────────┐
│ 北京中心 │ │ 上海中心 │
│ (活跃) │ │ (活跃) │
├─────────┤ ├─────────┤
│ 应用集群 │ │ 应用集群 │
│ 数据库主 │←─→│ 数据库主 │
└─────────┘ └─────────┘
│ │
└──────┬──────┘
↓
数据同步层
特点:
- 两地同时提供服务
- 恢复时间: 分钟级
- 数据丢失: 秒级
- 适用: 大型企业3. 多活架构
多活架构:
用户请求
↓
全局负载均衡 (GSLB)
↓
┌────────┬────────┬────────┐
│ │ │ │
↓ ↓ ↓ ↓
┌────┐ ┌────┐ ┌────┐ ┌────┐
│北京│ │上海│ │广州│ │深圳│
│中心│ │中心│ │中心│ │中心│
└────┘ └────┘ └────┘ └────┘
│ │ │ │
└──────┼──────┼──────┘
│ │
数据同步层 (分布式数据库)
特点:
- 多地同时提供服务
- 恢复时间: 秒级
- 数据丢失: 0
- 适用: 金融、互联网巨头多活架构实现示例:
// 多活数据中心管理
class MultiDataCenter {
constructor() {
this.datacenters = {
beijing: {
region: 'cn-north',
status: 'active',
weight: 30,
latency: { shanghai: 20, guangzhou: 50 }
},
shanghai: {
region: 'cn-east',
status: 'active',
weight: 30,
latency: { beijing: 20, guangzhou: 30 }
},
guangzhou: {
region: 'cn-south',
status: 'active',
weight: 40,
latency: { beijing: 50, shanghai: 30 }
}
}
}
// 路由用户请求
route(userLocation) {
const activeDCs = this.getActiveDataCenters()
// 按延迟排序
const sorted = activeDCs.sort((a, b) => {
return this.datacenters[a].latency[userLocation] -
this.datacenters[b].latency[userLocation]
})
// 返回最近的活跃数据中心
return sorted[0]
}
// 获取活跃数据中心
getActiveDataCenters() {
return Object.keys(this.datacenters).filter(
dc => this.datacenters[dc].status === 'active'
)
}
// 健康检查
healthCheck() {
Object.keys(this.datacenters).forEach(dc => {
const isHealthy = this.checkHealth(dc)
if (!isHealthy && this.datacenters[dc].status === 'active') {
this.failover(dc)
}
})
}
// 故障转移
failover(failedDC) {
console.log(`数据中心 ${failedDC} 故障,开始转移流量`)
// 将故障数据中心的权重分配给其他数据中心
const failedWeight = this.datacenters[failedDC].weight
const activeDCs = this.getActiveDataCenters()
// 标记为故障
this.datacenters[failedDC].status = 'failed'
this.datacenters[failedDC].weight = 0
// 重新分配权重
const weightPerDC = failedWeight / activeDCs.length
activeDCs.forEach(dc => {
this.datacenters[dc].weight += weightPerDC
})
console.log('流量转移完成:', this.datacenters)
}
// 健康检查
checkHealth(dc) {
// 模拟健康检查
return Math.random() > 0.01 // 99% 可用性
}
}
// 使用示例
const multiDC = new MultiDataCenter()
// 路由用户请求
const dc1 = multiDC.route('shanghai')
console.log(`上海用户路由到: ${dc1}`)
// 健康检查
multiDC.healthCheck()
// 模拟故障
console.log('\n模拟北京数据中心故障...')
multiDC.datacenters.beijing.status = 'failed'
multiDC.failover('beijing')CAP 理论:分布式系统最多只能同时满足三个要素中的两个
CAP 三要素:
C - Consistency (一致性)
所有节点在同一时间看到的数据是一致的
A - Availability (可用性)
每个请求都能在合理时间内得到响应
P - Partition Tolerance (分区容错)
系统在网络分区发生时仍能继续运行CAP 组合方案:
┌─────────────────────────────────────┐
│ CA (无 P) │
│ 一致性 + 可用性 │
│ 数据强一致 │
│ 高可用 │
│ 不支持网络分区 │
│ │
│ 适用: 单机数据库、集群架构 │
│ 示例: MySQL 主从、Oracle RAC │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ CP (无 A) │
│ 一致性 + 分区容错 │
│ 数据强一致 │
│ 支持网络分区 │
│ 网络分区时不可用 │
│ │
│ 适用: 分布式数据库 │
│ 示例: MongoDB、HBase、Redis Cluster │
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
│ AP (无 C) │
│ 可用性 + 分区容错 │
│ 高可用 │
│ 支持网络分区 │
│ 数据可能不一致 │
│ │
│ 适用: 分布式存储、缓存 │
│ 示例: Cassandra、DynamoDB、CouchDB │
└─────────────────────────────────────┘CP 方案:强一致性优先
// CP 系统: 一致性优先
class CPSystem {
constructor() {
this.nodes = ['node1', 'node2', 'node3']
this.data = {}
this.lock = new DistributedLock()
}
// 写入数据 (保证一致性)
async write(key, value) {
// 1. 获取分布式锁
const lockAcquired = await this.lock.acquire(key)
if (!lockAcquired) {
throw new Error('无法获取锁,写入失败')
}
try {
// 2. 写入所有节点
const writePromises = this.nodes.map(node =>
this.writeToNode(node, key, value)
)
// 3. 等待所有节点写入成功
await Promise.all(writePromises)
// 4. 释放锁
await this.lock.release(key)
return { success: true }
} catch (error) {
// 任何节点写入失败,整个操作失败
await this.lock.release(key)
throw new Error('写入失败,数据不一致')
}
}
// 读取数据
async read(key) {
// 从任意节点读取 (数据一致)
const node = this.nodes[0]
return this.readFromNode(node, key)
}
async writeToNode(node, key, value) {
// 模拟节点写入
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.1) {
this.data[key] = value
resolve()
} else {
reject(new Error(`节点 ${node} 写入失败`))
}
}, 10)
})
}
async readFromNode(node, key) {
return this.data[key]
}
}
// 分布式锁
class DistributedLock {
async acquire(key) {
// 使用 Redis 实现分布式锁
return true
}
async release(key) {
return true
}
}AP 方案:可用性优先
// AP 系统: 可用性优先
class APSystem {
constructor() {
this.nodes = ['node1', 'node2', 'node3']
this.data = {
node1: {},
node2: {},
node3: {}
}
}
// 写入数据 (保证可用性)
async write(key, value) {
const successfulNodes = []
const failedNodes = []
// 尝试写入所有节点,但不等待全部成功
for (const node of this.nodes) {
try {
await this.writeToNode(node, key, value)
successfulNodes.push(node)
} catch (error) {
failedNodes.push(node)
console.log(`节点 ${node} 写入失败,但继续`)
}
}
// 只要有至少一个节点成功,就返回成功
if (successfulNodes.length > 0) {
// 异步同步到失败的节点
this.syncToFailedNodes(failedNodes, key, value)
return {
success: true,
writtenNodes: successfulNodes.length
}
} else {
throw new Error('所有节点写入失败')
}
}
// 读取数据
async read(key) {
// 从最近的节点读取
for (const node of this.nodes) {
try {
const value = await this.readFromNode(node, key)
if (value !== undefined) {
return value
}
} catch (error) {
continue
}
}
return null
}
// 异步同步到失败的节点
async syncToFailedNodes(nodes, key, value) {
// 后台任务:最终一致性
setTimeout(async () => {
for (const node of nodes) {
try {
await this.writeToNode(node, key, value)
console.log(`节点 ${node} 同步成功`)
} catch (error) {
console.log(`节点 ${node} 同步失败,稍后重试`)
}
}
}, 1000)
}
async writeToNode(node, key, value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.3) {
this.data[node][key] = value
resolve()
} else {
reject(new Error())
}
}, 10)
})
}
async readFromNode(node, key) {
return this.data[node][key]
}
}| 对比维度 | 集群架构 | 分布式架构 |
|---|---|---|
| CAP 特性 | CA (一致性 + 可用性) | CP 或 AP |
| 部署方式 | 多节点部署相同应用 | 多节点部署不同服务 |
| 数据一致性 | 强一致性 | 最终一致性 |
| 扩展性 | 水平扩展为主(复制相同应用) | 垂直拆分为主(按业务拆分服务) |
| 故障影响 | 单节点故障影响小 | 服务间故障可能传播 |
| 复杂度 | 相对简单 | 较复杂 |
集群架构技术:
集群架构应用层:
系统层面
├── Unix/Linux 集群
├── Windows Server 集群
└── 虚拟机集群
容器编排
├── Docker Swarm
├── Kubernetes (单集群)
└── Mesos(已于 2023 年进入 Apache Attic,停止维护)
负载均衡
├── Nginx
├── HAProxy
└── F5分布式架构技术:
分布式架构应用层:
容器编排
├── Kubernetes (多集群)
├── Istio (服务网格)
└── Consul (服务发现)
微服务框架
├── Spring Cloud
├── Dubbo
├── gRPC
└── GraphQL
API 网关
├── Kong
├── Zuul
└── APISIX集群架构中间件:
const clusterMiddleware = {
// Web 服务器
webServer: {
11-Nginx基础概述: '负载均衡、反向代理',
tomcat: 'Java 应用服务器',
weblogic: '企业级应用服务器',
websphere: 'IBM 应用服务器'
},
// 消息队列
mq: {
activemq: 'JMS 规范实现',
rabbitmq: 'AMQP 协议'
},
// 缓存
cache: {
redis: '单机/主从 Redis',
memcached: '分布式缓存'
}
}分布式架构中间件:
const distributedMiddleware = {
// 消息队列
mq: {
kafka: '高吞吐量、分布式',
rocketmq: '阿里开源、事务消息',
pulsar: '云原生、多租户'
},
// 缓存
cache: {
redisCluster: 'Redis 集群',
codis: 'Redis 代理集群',
twemproxy: 'Redis/Memcached 代理'
},
// 协调服务
coordination: {
zookeeper: '分布式协调',
etcd: 'Kubernetes 存储',
consul: '服务发现、配置中心'
},
// 分布式事务
transaction: {
seata: '阿里分布式事务',
dtm: 'Go 分布式事务'
}
}集群架构数据层:
集群架构数据层:
数据库集群
├── MySQL 主从复制
├── Oracle RAC
└── SQL Server AlwaysOn
存储
├── SAN (存储区域网络)
├── NAS (网络附加存储)
└── RAID 磁盘阵列分布式架构数据层:
分布式架构数据层:
分布式数据库
├── TiDB (NewSQL)
├── OceanBase (阿里)
├── CockroachDB
└── MongoDB (分片)
分布式存储
├── HDFS
├── Ceph
├── MinIO
└── 对象存储 (S3/OSS)主从复制架构:
MySQL 主从复制:
写入请求 → MySQL 主库
↓
Binlog 同步
↓
┌────┴────┐
↓ ↓
MySQL 从库1 MySQL 从库2
↑ ↑
读取请求 读取请求
配置步骤:
1. 主库开启 binlog
2. 从库配置主库信息
3. 启动复制线程
4. 监控复制延迟配置示例:
-- 主库配置 (my.cnf)
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
sync_binlog = 1
-- 从库配置 (my.cnf)
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read-only = 1
-- 主库创建复制账号
CREATE USER 'repl'@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 从库启动复制(MySQL 8.0.22+ 推荐语法;CHANGE MASTER TO / START SLAVE 已在 8.4 中移除)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='master-ip',
SOURCE_USER='repl',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0;
START REPLICA;Redis Sentinel 哨兵架构:
Redis Sentinel 架构:
┌──────────────┐
│ Sentinel 1 │
└──────┬───────┘
│ 监控 & 故障转移
┌──────┴───────┐
│ │
↓ ↓
┌────────┐ ┌────────┐
│ Redis │ │ Redis │
│ 主库 │ │ 从库 │
└────────┘ └────────┘配置示例:
# sentinel.conf
port 26379
sentinel monitor mymaster 192.168.1.100 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
# 启动 Sentinel
redis-sentinel /path/to/sentinel.confRedis Cluster 集群架构:
Redis Cluster 集群:
┌─────────────────────────────────┐
│ Redis Cluster │
├─────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ │
│ │ Master1 │ ←→ │ Master2 │ │
│ │ 0-5460 │ │ 5461-10922 │
│ └────┬────┘ └────┬────┘ │
│ ↓ ↓ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Slave1 │ │ Slave2 │ │
│ └─────────┘ └─────────┘ │
│ │
│ ┌─────────┐ │
│ │ Master3 │ │
│ │10923-16383│ │
│ └────┬────┘ │
│ ↓ │
│ ┌─────────┐ │
│ │ Slave3 │ │
│ └─────────┘ │
└─────────────────────────────────┘
特点:
- 数据分片存储
- 自动故障转移
- 水平扩展微服务高可用架构:
微服务高可用架构:
用户请求
↓
┌───────────────┐
│ API 网关集群 │ ← 多实例部署
└───────┬───────┘
│
┌───────┴───────────────────┐
│ │
↓ ↓
┌─────────┐ ┌─────────┐
│用户服务 │ │订单服务 │
│(3实例) │ │(5实例) │
└────┬────┘ └────┬────┘
│ │
┌────┴────┐ ┌────┴────┐
│用户 DB │ │订单 DB │
│主 + 从 │ │主 + 从 │
└─────────┘ └─────────┘
保障措施:
1. 服务多实例部署
2. 数据库主从复制
3. 服务注册发现
4. 熔断降级
5. 限流保护服务降级实现:
// 服务降级示例
class ServiceDegradation {
constructor() {
this.circuitBreaker = new CircuitBreaker()
}
// 调用远程服务
async callRemoteService(serviceName, params) {
// 检查熔断器状态
if (this.circuitBreaker.isOpen(serviceName)) {
// 服务熔断,执行降级逻辑
return this.fallback(serviceName, params)
}
try {
// 调用远程服务
const result = await this.invoke(serviceName, params)
// 成功,重置熔断器
this.circuitBreaker.recordSuccess(serviceName)
return result
} catch (error) {
// 失败,记录失败
this.circuitBreaker.recordFailure(serviceName)
// 执行降级逻辑
return this.fallback(serviceName, params)
}
}
// 降级逻辑
fallback(serviceName, params) {
switch (serviceName) {
case 'recommendation':
// 推荐服务降级:返回热门商品
return this.getHotProducts()
case 'comment':
// 评论服务降级:返回缓存评论
return this.getCachedComments(params.productId)
case 'payment':
// 支付服务不可降级:返回错误
throw new Error('支付服务暂时不可用,请稍后重试')
default:
return null
}
}
async invoke(serviceName, params) {
// 模拟服务调用
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.3) {
resolve({ data: 'success' })
} else {
reject(new Error('服务调用失败'))
}
}, 100)
})
}
async getHotProducts() {
return [
{ id: 1, name: '热门商品1' },
{ id: 2, name: '热门商品2' }
]
}
async getCachedComments(productId) {
return [
{ id: 1, content: '缓存评论1' },
{ id: 2, content: '缓存评论2' }
]
}
}
// 熔断器
class CircuitBreaker {
constructor() {
this.states = new Map()
this.threshold = 5 // 失败阈值
this.timeout = 60000 // 熔断超时时间
}
isOpen(serviceName) {
const state = this.states.get(serviceName)
if (!state) return false
if (state.status === 'open') {
// 检查是否超过超时时间
if (Date.now() - state.lastFailureTime > this.timeout) {
// 进入半开状态
state.status = 'half-open'
return false
}
return true
}
return false
}
recordSuccess(serviceName) {
const state = this.states.get(serviceName) || {
status: 'closed',
failureCount: 0
}
state.status = 'closed'
state.failureCount = 0
this.states.set(serviceName, state)
}
recordFailure(serviceName) {
const state = this.states.get(serviceName) || {
status: 'closed',
failureCount: 0
}
state.failureCount++
state.lastFailureTime = Date.now()
if (state.failureCount >= this.threshold) {
state.status = 'open'
console.log(`服务 ${serviceName} 熔断器打开`)
}
this.states.set(serviceName, state)
}
}
// 使用示例
const service = new ServiceDegradation()
// 正常调用
service.callRemoteService('recommendation', {})
.then(result => console.log('推荐结果:', result))
// 服务降级
for (let i = 0; i < 10; i++) {
service.callRemoteService('recommendation', {})
.then(result => console.log(`第${i+1}次调用:`, result))
}// 高可用监控指标
const monitoringMetrics = {
// 系统层指标
system: {
cpu: 'CPU 使用率',
memory: '内存使用率',
disk: '磁盘使用率',
network: '网络流量'
},
// 应用层指标
application: {
qps: '请求吞吐量',
latency: '响应时间',
errorRate: '错误率',
availability: '可用性'
},
// 数据层指标
database: {
connections: '连接数',
queryTime: '查询时间',
replicationLag: '复制延迟',
diskIO: '磁盘 I/O'
},
// 中间件指标
middleware: {
mqLag: '消息队列延迟',
cacheHitRate: '缓存命中率',
serviceHealth: '服务健康状态'
}
}// 告警配置
const alertConfig = {
// CPU 告警
cpu: {
warning: {
threshold: 70,
duration: 300, // 持续 5 分钟
severity: 'warning'
},
critical: {
threshold: 90,
duration: 60, // 持续 1 分钟
severity: 'critical'
}
},
// 可用性告警
availability: {
critical: {
threshold: 99.9,
duration: 300,
severity: 'critical'
}
},
// 错误率告警
errorRate: {
warning: {
threshold: 1, // 1%
duration: 180,
severity: 'warning'
},
critical: {
threshold: 5, // 5%
duration: 60,
severity: 'critical'
}
}
}| 问题 | 原因 | 解决方案 |
|---|---|---|
| 单点故障 | 关键组件无冗余 | 集群部署、主备切换 |
| 数据不一致 | 异步复制延迟 | 同步复制、最终一致性 |
| 故障转移慢 | 手动干预 | 自动故障检测、自动转移 |
| 雪崩效应 | 服务级联失败 | 熔断、降级、限流 |
| 数据丢失 | 异地容灾缺失 | 异地备份、实时同步 |
| 恢复时间长 | 缺乏预案 | 演练、自动化恢复 |
高可用三大保障场景:
CAP 理论核心:
集群 vs 分布式:
高可用技术方案:
监控与告警:
// 高可用架构设计检查清单
const haChecklist = {
// 硬件层
hardware: [
' 服务器冗余(多台服务器)',
' 磁盘冗余(RAID)',
' 网络冗余(双网卡、双交换机)',
' 电源冗余(双电源、UPS、发电机)'
],
// 数据层
data: [
' 数据库主从复制',
' 数据备份策略(全量 + 增量)',
' 数据快照(快速恢复)',
' 异地容灾(主备/双活/多活)'
],
// 应用层
application: [
' 服务多实例部署',
' 负载均衡',
' 服务注册发现',
' 熔断降级限流'
],
// 监控层
monitoring: [
' 实时监控(系统、应用、数据)',
' 告警通知(邮件、短信、电话)',
' 日志收集(ELK)',
' 链路追踪(Jaeger/Zipkin)'
],
// 运维层
operations: [
' 故障演练(定期演练)',
' 应急预案(详细的处理流程)',
' 自动化运维(Ansible/Terraform)',
' 文档完善(架构图、操作手册)'
]
}笔记整理完成!
这份笔记详细讲解了高可用架构的核心概念、三大保障场景、CAP理论、集群与分布式架构对比,并结合实际案例和代码示例,帮助理解高可用架构设计的核心思想。建议结合实际项目进行高可用架构设计和实践。