异地容灾与多活架构 学习笔记(第 7 部分)
3.2 数据库层容灾
技术方案:数据库复制技术
plaintext
数据库层容灾架构:
主数据中心 备数据中心
┌──────────────┐ ┌──────────────┐
│ 应用服务器 │ │ 应用服务器 │
└──────┬───────┘ └──────┬───────┘
│ │
↓ ↓
┌──────────────┐ ┌──────────────┐
│ MySQL 主库 │ ────────→ │ MySQL 从库 │
│ (A厂存储) │ Binlog │ (B厂存储) │
└──────────────┘ 同步 └──────────────┘
特点:
- 存储异构支持
- 占用网络带宽
- 占用应用资源
- 配置灵活优势与劣势:
| 优势 | 劣势 |
|---|---|
| 支持异构存储 | 占用网络带宽 |
| 配置灵活 | 占用应用资源 |
| 成本相对较低 | 复制延迟问题 |
| 技术成熟 | 可能影响性能 |
主流数据库容灾技术:
javascript
// 数据库容灾技术对比
const databaseDR = {
// MySQL
mysql: {
replication: {
async: '异步复制',
semiSync: '半同步复制',
group: '组复制(MGR)'
},
tools: ['MySQL Replication', 'MySQL Router', 'MHA', 'Orchestrator'],
features: [
'开源免费',
'配置简单',
'支持异构存储',
'延迟监控方便'
]
},
// Oracle
oracle: {
technologies: {
dataguard: 'Data Guard(物理/逻辑备库)',
rac: 'RAC(集群)',
goldengate: 'Golden Gate(逻辑复制)'
},
features: [
'功能强大',
'企业级支持',
'数据一致性保证',
'成本高昂'
]
},
// PostgreSQL
postgresql: {
replication: {
streaming: '流复制',
logical: '逻辑复制',
cascading: '级联复制'
},
features: [
'开源免费',
'功能丰富',
'性能优秀',
'社区活跃'
]
},
// MongoDB
mongodb: {
replication: {
replicaSet: '副本集',
sharding: '分片集群'
},
features: [
'自动故障转移',
'支持跨机房部署',
'配置简单',
'性能优秀'
]
}
}MySQL 数据库容灾实现:
javascript
// MySQL 主从复制管理
class MySQLReplicationManager {
constructor() {
this.master = {
host: 'master.db.example.com',
port: 3306,
status: 'active'
}
this.slaves = [
{ host: 'slave1.db.example.com', port: 3306, status: 'active' },
{ host: 'slave2.db.example.com', port: 3306, status: 'active' }
]
}
// 监控复制状态
async monitorReplication() {
const replicationStatus = []
for (const slave of this.slaves) {
const status = await this.getSlaveStatus(slave)
replicationStatus.push({
slave: slave.host,
ioRunning: status.Slave_IO_Running,
sqlRunning: status.Slave_SQL_Running,
secondsBehindMaster: status.Seconds_Behind_Master,
lastError: status.Last_Error
})
// 检查延迟
if (status.Seconds_Behind_Master > 10) {
this.sendAlert({
type: 'replication_lag',
slave: slave.host,
delay: status.Seconds_Behind_Master
})
}
}
return replicationStatus
}
// 获取从库状态
async getSlaveStatus(slave) {
// 实际实现:执行 SHOW SLAVE STATUS
return {
Slave_IO_Running: 'Yes',
Slave_SQL_Running: 'Yes',
Seconds_Behind_Master: 0,
Last_Error: ''
}
}
// 主从切换
async failover(failedMaster) {
console.log('开始主从切换...')
// 1. 选择新的主库
const newMaster = this.selectNewMaster()
// 2. 停止所有从库复制
await this.stopAllSlaves()
// 3. 提升新主库
await this.promoteToMaster(newMaster)
// 4. 重新配置其他从库
await this.reconfigureSlaves(newMaster)
// 5. 更新应用配置
await this.updateApplicationConfig(newMaster)
console.log(`主从切换完成,新主库: ${newMaster.host}`)
}
// 选择新主库
selectNewMaster() {
// 选择延迟最小的从库
const sortedSlaves = this.slaves.sort((a, b) => {
return a.delay - b.delay
})
return sortedSlaves[0]
}
// 停止所有从库复制
async stopAllSlaves() {
for (const slave of this.slaves) {
// 执行 STOP SLAVE
console.log(`停止从库 ${slave.host} 复制`)
}
}
// 提升为主库
async promoteToMaster(slave) {
// 执行 RESET SLAVE ALL
console.log(`提升 ${slave.host} 为主库`)
}
// 重新配置从库
async reconfigureSlaves(newMaster) {
for (const slave of this.slaves) {
if (slave !== newMaster) {
// CHANGE MASTER TO ...
console.log(`重新配置从库 ${slave.host}`)
}
}
}
// 更新应用配置
async updateApplicationConfig(newMaster) {
// 更新数据库连接配置
console.log('更新应用数据库连接配置')
}
// 发送告警
sendAlert(alert) {
console.log('发送告警:', alert)
}
}