之前的文章MongoDB主备副本集方案:两台服务器使用非对称部署的方式实现高可用与容灾备份中,简单讨论下了mongodb的数据同步,但往往并不只是数据库需要同步。在主备架构中,要求主服务器(包含业务程序和数据库)挂掉后,备用服务器能够自动接管请求,需要实现以下几个核心功能:
- 业务程序和数据库的部署:主备服务器上运行相同的业务程序和数据库实例。
- 实时数据同步:主服务器的数据库和必要数据需要实时或接近实时同步到备服务器。
- 自动切换:在主服务器不可用时,备用服务器能自动接管所有请求。
- 高可用管理:通过负载均衡器或虚拟 IP (VIP) 实现请求动态转发。
以下是完整的实现方案和步骤。
一、架构设计
整体架构:
- 两台服务器:
- 主服务器:运行业务程序和主数据库。
- 备服务器:运行业务程序和备数据库。
- 数据同步:
- 主数据库与备数据库之间通过文件同步工具或数据库复制实现实时同步。
- 高可用管理:
- 配置负载均衡器(如 HAProxy)或虚拟 IP(如 Keepalived),确保主备服务器的自动切换。
二、详细实现步骤
1. 部署业务程序和数据库
在两台服务器上,部署相同的业务程序和数据库:
- 业务程序:确保两台服务器运行相同版本的应用程序,并保持配置一致。
- 数据库:使用 SQLite 或其他轻量级数据库(如 MySQL)。如果使用 SQLite,数据库文件需要同步;如果使用 MySQL,使用主从复制。
2. 数据库同步机制
(1) SQLite 文件同步
SQLite 数据库通过文件级别同步进行数据一致性维护:
-
启用 WAL 模式:
SQLite 的 WAL 模式支持写日志,可以帮助在备库进行增量同步。PRAGMA journal_mode=WAL;
-
使用 rsync:
配置主服务器定时将 SQLite 数据库文件同步到备服务器。脚本示例:rsync -avz /path/to/main.db backup-server:/path/to/main.db
-
注意点:
- WAL 文件 (
.db-wal
) 和共享内存文件 (.db-shm
) 需要同步。 - 主服务器挂掉前,确保数据库已完成 WAL 日志合并。
- WAL 文件 (
(2) MySQL 主从复制
如果使用 MySQL,可以配置主从复制:
- 主库配置:
在主库的my.cnf
中启用二进制日志:[mysqld] log-bin=mysql-bin server-id=1
- 从库配置:
在从库的my.cnf
中配置从服务器 ID 和复制参数:[mysqld] server-id=2 replicate-do-db=your_database
- 启动复制:
执行以下命令将从库与主库同步:CHANGE MASTER TO MASTER_HOST='primary-server', MASTER_USER='replication-user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=4; START SLAVE;
3. 配置负载均衡与高可用切换
为了实现自动切换,可以使用以下两种方式:
(1) 使用 HAProxy
HAProxy 是一种强大的负载均衡工具,可以根据健康检查动态将流量切换到可用的服务器。
-
安装 HAProxy:
在一台独立的服务器上安装 HAProxy,或者在主备服务器上同时运行 HAProxy。 -
配置 HAProxy:
修改/etc/haproxy/haproxy.cfg
,添加主备服务器的后端配置。global log stdout format raw local0 maxconn 4096 defaults log global timeout connect 5s timeout client 10s timeout server 10s frontend http-in bind *:80 default_backend app-backend backend app-backend option httpchk GET / server primary 192.168.1.1:80 check inter 2000 rise 2 fall 3 server secondary 192.168.1.2:80 backup check inter 2000 rise 2 fall 3
- **主服务器(192.168.1.1)**为默认主机。
- **备服务器(192.168.1.2)**为备用,主服务器失效时接管流量。
-
启动 HAProxy:
启动服务并测试访问:sudo systemctl start haproxy curl http://load-balancer-ip/
(2) 使用 Keepalived 实现 VIP 漂移
Keepalived 通过虚拟 IP(VIP)切换实现高可用:
-
安装 Keepalived:
在两台服务器上安装 Keepalived。 -
主服务器配置:
主服务器的配置文件/etc/keepalived/keepalived.conf
:vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 virtual_ipaddress { 192.168.1.100 } track_script { chk_service } } vrrp_script chk_service { script "/path/to/health-check.sh" interval 2 }
-
备服务器配置:
备服务器的配置类似,只需将state
修改为BACKUP
,priority
设置为 50。 -
健康检查脚本:
检查服务是否可用,例如:# /path/to/health-check.sh # 检查业务程序是否运行 if ! systemctl is-active --quiet my-app; then exit 1 fi # 检查数据库是否可用 if ! sqlite3 /path/to/main.db "SELECT 1;" > /dev/null 2>&1; then exit 1 fi exit 0
-
启动 Keepalived:
启动 Keepalived 服务,VIP 会自动漂移到健康的服务器上。
4. 流量切换与恢复
(1) 主服务器挂掉时的行为
- HAProxy 自动检测主服务器的不可用状态,将流量切换到备服务器。
- 或者 Keepalived 使 VIP 漂移到备服务器,用户的请求透明地转发到备服务器。
(2) 主服务器恢复后的处理
- 重新启动主服务器的业务程序和数据库同步。
- 等待数据库与备库完成数据同步。
- 恢复主服务器为流量主节点。
三、完整架构流程图
┌───────────────┐ ┌───────────────┐
│ 主服务器 │ │ 备服务器 │
│ (业务+数据库)│ │ (业务+数据库)│
└──────┬────────┘ └──────┬────────┘
│ │
数据库同步│ rsync 或主从复制 │
└────────┬─────────────────┘
▼
┌─────────────┐
│ 负载均衡器 │ (HAProxy 或 Keepalived)
└─────────────┘
│
▼
用户请求入口
四、总结
通过以上步骤,可以构建一个包含业务程序和数据库的主备高可用系统:
- 主备服务器部署:主备服务器均运行业务程序和数据库实例。
- 数据实时同步:使用 SQLite 文件同步或 MySQL 主从复制保持数据一致。
- 高可用切换:利用 HAProxy 或 Keepalived 实现主备服务器的自动切换。
此架构适合中小型应用,能够显著提高系统的容灾能力。如果需求更复杂(如高并发、高吞吐量),可以结合分布式数据库和更高级的负载均衡方案。