在现代电信行业中,订单中心作为核心业务系统之一,承担着处理客户订单、管理订单状态、与各个业务系统进行交互等重要职责。其订单中心的高效运作直接关系到客户体验和业务连续性。为了满足不断增长的业务需求和日益复杂的运营环境,运营商需要自身的订单中心架构具备高可用性及强大的容灾能力。 双活架构作为常见的高可用方案,允许两个数据中心同时提供服务并实现数据的实时同步。当一个数据中心发生故障时,另一个数据中心能够无缝接管其工作,确保业务不中断。这种架构不仅提高了系统的稳定性和可靠性,还能大幅减少灾难恢复的时间和成本。 本文将着重分享某头部运营商订单中心在实现双活架构过程中的最佳实践,提供详细的技术细节和实际案例。通过介绍项目实施过程中的技术细节,提供类似场景需求的方案参考。
需求背景
架构说明
工作模式
场景说明:
当 DC A 不可用时,Tapdata 集群也不可用
需要人工干预恢复:
风险:
机器角色 | CPU | 内存 | 磁盘 | 数量 |
---|---|---|---|---|
MongoDB主集群 - 主节点 | 56C | 256GB | SSD - 4.8TB | 10 |
MongoDB主集群 - 从节点SSD | 56C | 128GB | SSD - 4.8TB | 10 |
MongoDB主集群 - 从节点HDD | 40C | 256GB | HDD - 2.4TB | 10 |
MongoDB备集群 | 15 | |||
Tapdata集群 | 40C | 256GB | HDD - 4.8TB | 13 |
机器角色 | CPU | 内存 | 磁盘 | 数量 |
---|---|---|---|---|
MongoDB主集群(10分片) | 2 * 32C/2.0GHz | 512GB | SSD - 960GB*12 | 30 |
MongoDB备集群(5分片) | 2 * 32C/2.0GHz | 512GB | SSD - 960GB*12 | 15 |
use admin
db.createUser({
"user" : "tapdata",
"pwd" : "my_password",
"roles" : [
{
"role" : "clusterMonitor",
"db" : "admin"
},
{
"role" : "read",
"db" : "order"
},
{
"role" : "read",
"db" : "local"
},
{
"role" : "read",
"db" : "config"
}
]
}
use admin
db.createUser({
"user" : "tapdata",
"pwd" : "my_password",
"roles" : [
{
"role" : "clusterMonitor",
"db" : "admin"
},
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
| 详情参见文档:MongoDB | Tapdata 文档中心
use admin
> db.createUser({
"user" : "tapdata",
"pwd" : "my_password",
"roles" : [
{
"role" : "clusterMonitor",
"db" : "admin"
},
{
"role" : "readWrite",
"db" : "order"
},
{
"role" : "read",
"db" : "local"
}
]
}
/home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongo --host 10.173.2.115:20000
use order
db.dropDatabase()
use order
// 表order.oc_order创建索引
db.oc_order.createIndex({ "ORDER_ID" : "hashed"})
// 表order.oc_order_dispatch创建索引
db.oc_order_dispatch.createIndex({ "ORDER_ID" : "hashed"})
// 表order.oc_order_low_efficientcy创建索引
db.oc_order_low_efficientcy.createIndex({ "ORDER_ID" : "hashed"})
// 表order.oc_order_pic创建索引
db.oc_order_pic.createIndex({ "PIC_KEY" : "hashed"})
// 表order.oc_order_activate创建索引
db.oc_order_activate.createIndex({ "ORDER_ID" : "hashed"})
use order
// 实现数据库order分片功能
mongos> sh.enableSharding("order")
// 以"ORDER_ID"作为分片键对集合oc_order进行分片
mongos> sh.shardCollection("order.oc_order",{"ORDER_ID":"hashed"})
// 以"ORDER_ID"作为分片键对集合oc_order_low_efficientcy进行分片
mongos> sh.shardCollection("order.oc_order_low_efficientcy",{"ORDER_ID":"hashed"})
// 以"PIC_KEY"作为分片键对集合oc_order_pic进行分片
mongos> sh.shardCollection("order.oc_order_pic",{"PIC_KEY":"hashed"})
// 以"ORDER_ID"作为分片键对集合oc_order_activate进行分片
mongos> sh.shardCollection("order.oc_order_activate",{"ORDER_ID":"hashed"})
// 以"ORDER_ID"作为分片键对集合oc_order_dispatch进行分片
mongos> sh.shardCollection("order.oc_order_dispatch",{"ORDER_ID":"hashed"})
/home/mongodb/app/mongodb-linux-x86_64-enterprise-rhel70-3.4.24/bin/mongo --host 10.191.241.218:20000
sh.stopBalancer()
sh.isBalancerRunning()
sh.getBalancerState()
/home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongo --host 10.173.2.115:20000
sh.stopBalancer()
sh.isBalancerRunning()
sh.getBalancerState()
5. [陕西]检查集群状态
sh.status()
6. [陕西]回滚操作
use orderdb.dropDatabase()
北京中心集群数据导出
1. 小于20210901--10.173.2.108服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongodump --host 10.191.241.128:20000 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin -q '{"CREATE_DATE": {"$lt":"2021-09-01"}}' --readPreference='{mode: "secondary", tagSets: [ { "type": "ssd" } ]}' -o /data/oc_order/ > dumpbf0901.log &
2. 大于等于20210901小于20220201--10.173.2.110服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongodump --host 10.191.241.128:20000 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin -q '{"CREATE_DATE": {"$gte":"2021-09-01"},"CREATE_DATE": {"$lt":"2022-02-01"}}' --readPreference='{mode: "secondary", tagSets: [ { "type": "ssd" } ]}' -o /data/oc_order/ > dumpbf220201.log &
3. 大于等于20220201小于20220801--10.173.2.112服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongodump --host 10.191.241.128:20000 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin -q '{"CREATE_DATE": {"$gte":"2022-02-01"},"CREATE_DATE": {"$lt":"2022-08-01"}}' --readPreference='{mode: "secondary", tagSets: [ { "type": "ssd" } ]}' -o /data/oc_order/ > dumpbf20220801.log &
4. 大于等于20220801小于20230201--10.173.2.113服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongodump --host 10.191.241.128:20000 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin -q '{"CREATE_DATE": {"$gte":"2022-08-01"},"CREATE_DATE": {"$lt":"2023-02-01"}}' --readPreference='{mode: "secondary", tagSets: [ { "type": "ssd" } ]}' -o /data/oc_order/ > dumpbf230201.log &
5. 大于等于20230201--10.173.2.114服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongodump --host 10.191.241.128:20000 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin -q '{"CREATE_DATE": {"$gte":"2023-02-01"}}' --readPreference='{mode: "secondary", tagSets: [ { "type": "ssd" } ]}' -o /data/oc_order/ > dumpaf230201.log &
陕西中心集群数据导入
1. 小于20210901--10.173.2.108服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongorestore --host 10.173.2.115:20000 --numInsertionWorkersPerCollection=8 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin /data/oc_order/order/oc_order.bson > restorebf210901.log 2>&1 &
2. 大于等于20210901小于20220201--10.173.2.110服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongorestore --host 10.173.2.115:20000 --numInsertionWorkersPerCollection=8 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin /data/oc_order/order/oc_order.bson > restorebf220201.log 2>&1 &
3. 大于等于20220201小于20220801--10.173.2.112服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongorestore --host 10.173.2.115:20000 --numInsertionWorkersPerCollection=8 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin /data/oc_order/order/oc_order.bson > restorebf220801.log 2>&1 &
4. 大于等于20220801小于20230201--10.173.2.113服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongorestore --host 10.173.2.115:20000 --numInsertionWorkersPerCollection=8 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin /data/oc_order/order/oc_order.bson > restorebf230201.log 2>&1 &
5. 大于等于20230201--10.173.2.114服务器上操作
nohup /home/mongodb/app/mongodb-linux-x86_64-3.4.24/bin/mongorestore --host 10.173.2.115:20000 --numInsertionWorkersPerCollection=8 -u monit -p 'Monit#3' --db order -c oc_order --authenticationDatabase admin /data/oc_order/order/oc_order.bson > restoreaf230201.log 2>&1 &
6. 集群状态检查
sh.status()
db.printSlaveReplicationInfo()
7. 回滚操作
use order
db.dropDatabase()
3. 实时同步
初始化同步完成后,可以配置 TapData 进行实时数据同步,以确保两个数据中心之间的数据实时一致。在此阶段,TapData 将实时捕获并同步 A 中心和 B 中心的 MongoDB 数据库中的数据变更,确保两个数据中心之间的数据持续保持一致。
实时同步是确保源数据库和目标数据库之间数据一致性的重要步骤,尤其是在高并发和复杂业务场景下。通过实时同步,订单中心的数据能够在不同的数据中心之间进行及时传输和更新,确保所有业务系统使用的都是最新的数据。TapData 在实时同步中发挥了核心作用,通过创建数据复制任务并设置增量同步点,系统能够实现数据的无缝同步。在执行实时同步时,还需要考虑可能出现的流量过大问题,并制定相应的应对措施,确保系统的稳定性和数据同步的连续性。
接下来将详细介绍如何配置和管理实时同步任务,以及应对流量过大情况的操作步骤。
操作步骤
1. 创建 TapData 数据复制任务
2. 任务设置:增量
3. 设置增量同步时间点为最后一次初始化导出的数据时间点
4. 保存任务
5. 启动任务
流量过大处理
#登录到服务器查看状态
cd /data/tapdata_v1.51.1
./tapdata status
#强制停止所有服务
./tapdata stop -f
./tapdata status
登录到tapdata服务器
ps -ef|grep tapdata
kill -9 $pid
4. 数据校验
在实时同步运行过程中,定期进行数据校验,确保两个数据中心的数据库始终保持一致。数据校验的目的是检测和修复因网络延迟、系统故障等原因导致的数据不一致问题,是确保数据同步任务成功执行的关键步骤,通过对比源数据库与目标数据库的数据,验证同步的准确性和完整性。
在 TapData 实施方案中,数据校验功能可以帮助用户快速检测并解决可能出现的数据不一致问题。特别是在双活架构中,数据的实时同步任务上,数据校验能够确保两个数据中心的数据保持一致,避免因数据不一致导致的业务中断。以下是具体操作示例:
基于此,该运营商成功实现了订单中心的高可用、高性能双活架构,确保业务的连续性和数据的一致性,为客户提供更加稳定和高效的服务。
双活架构在确保系统高可用性和数据一致性方面扮演着关键角色,但在实际运行中,可能会遇到各种数据同步和写入的挑战。为了验证和优化双活架构的稳定性,必须进行多种场景演练。这些测试不仅有助于发现潜在的问题,还可以通过配置和功能调整来优化系统的响应和恢复能力。
下面将通过对多种典型场景的分析和演练,帮助团队识别潜在问题,并通过合理的配置和机制优化,确保系统在不同情况下都能保持业务的连续性和数据的一致性。
1. 业务成功写入数据库,TapData 未正确同步到目标
中心 A:DCA
中心 B:DCB
同步任务 A:JobA,A -> B
同步任务 B:JobB,B -> A
业务 A 向 DCA 写入数据:DataA
业务 B 向 DCB 写入数据:DataB
10:00,启动 JobA,JobB
10:30,有一笔订单 Order1(oid=1,status=create) 向 DCA 写入,且成功写入。
10:31,JobA 由于某种原因未将 Order1 正确同步到 DCB 中。
10:32,业务 B 在 DCB 查询不到 Order1
这里可以通过 tapdata 的“任务自动重试”及“断点续传”来避免因为某种原因未同步到目标数据库的情况。
可能原因
验证
1 分钟查询 1 次 DCB,最终可以在 DCB 查询到 Order1
2. 正常双活运行情况下
中心 A:DCA
中心 B:DCB
同步任务 A:JobA,A -> B
同步任务 B:JobB,B -> A
业务 A 向 DCA 写入数据:DataA
业务 B 向 DCB 写入数据:DataB
10:00, 启动 JobA,JobB
10:30, 有一笔订单 Order1(oid=1,status=create) 写入 DCA,通过 JobA 同步到 DCB
10:31,业务 B 可以在 DCB 访问到 Order1
10:32,业务 B 在 DCB 对 Order1 进行数据更新,修改 status=active
10:33,业务 A 在 DCA 可以查询到 Order1(status=active)
在本案例中,我们详细探讨了双活架构在实现高可用性和数据一致性方面的最佳实践。关键要点包括:
最佳实践
1. 数据同步策略设计
在双向数据同步的设计中,建议采用数据标识机制,确保每条数据的变更都有明确的来源标识,防止数据循环同步问题。同步任务的设计应包括清晰的逻辑判断,确保同步过程中的数据一致性。
2. 断点回放和容错机制
同步任务应具备断点回放功能,以确保在任务中断后可以从中断点继续执行,避免数据不一致问题。容错机制的设计对于提高系统的可靠性至关重要,应在设计初期予以充分考虑。
3. 高并发场景下的性能优化
在高并发业务场景中,建议采用多线程和批处理技术提高同步效率。系统应具备动态调优能力,能够根据实际业务负载情况进行调整,确保同步任务的高效执行。
4. 实时监控与预警
建立全面的实时监控系统,对数据同步过程中的各项性能指标进行监控,及时发现和处理异常情况。预警机制应能够在问题发生前发出警报,提前进行干预,确保系统的稳定运行。
5. 系统测试和演练
定期进行系统测试和演练,模拟各种故障场景,验证系统的高可用性和容灾能力。通过不断的测试和演练,及时发现和解决潜在问题,提高系统的可靠性和稳定性。
6. 文档和知识分享
在项目实施过程中,及时记录各种问题和解决方案,形成详细的文档。通过知识分享和经验总结,不仅提升团队的整体技术水平,也为后续项目提供宝贵的参考。
该方案的成功实施不仅提升了该订单中心的业务连续性和数据可靠性,还为更多构建高可用性和容灾能力的系统架构的类似需求提供了经验和参考。未来,我们将继续优化和提升双活架构的性能和稳定性,以应对更加复杂和多变的业务需求。