单向数据库同步

7
经常需要将一个数据库中的主表数据同步到其他数据库的克隆表,通常是在其他服务器上。例如,考虑这样一种情况,后端系统管理库存数据,而这些库存数据最终必须被推送到一个或多个属于网站应用程序的数据库中。
后端系统中的源数据经过了大量规范化处理,有着数十个表和外键约束。它是一个设计良好的 OLTP 关系型数据库系统。其中许多表包含数百万行数据。需要定期将这些数据推送到其他数据库中。尽可能频繁;可以容忍延迟。最重要的是,后端和远程数据库的最大正常运行时间是至关重要的。
我正在使用 SQL Server,并熟悉更改跟踪、rowversion、触发器等技术。我知道 Microsoft 强烈推荐使用复制、SyncFx 和 SSIS 来解决这些问题。然而,供应商的白皮书和概述推荐技术与实际实现、部署和维护方案之间存在相当大的差异。在 SQL Server 的世界中,复制通常被视为成套的解决方案,但我试图探索替代方案。(有些人担心,复制难以管理,使得更改架构变得困难,在需要重新初始化时,关键系统将会有大量的停机时间。)
有许多需要注意的地方。由于大量表之间存在复杂的外键关系,确定执行捕获或应用更新的顺序并不是简单的。由于唯一索引,两行数据可能会以这样的方式相互锁定,以至于逐行更新甚至都不起作用(需要在最终更新之前对每行进行中间更新)。虽然这些问题不一定是无法解决的,因为唯一索引通常可以更改为普通索引,外键可以被禁用(尽管禁用外键是极不可取的)。通常你会听到,“只需要”使用 SQL 2008 更改跟踪和 SSIS 或 SyncFx。这种回答真的没有充分考虑实际困难。(当然,客户们真的很难理解复制数据为什么会如此困难,这使得本来就困难的情况更加糟糕!)
这个问题最终非常通用:对许多密切相关的数据库表进行单向同步,这些表具有大量的行。几乎所有涉及数据库的人都需要处理这种问题。白皮书很常见,实际专业知识很难找到。我们知道这可能是一个困难的问题,但工作必须完成。让我们听听您的经验(以及要避免的问题)。告诉我们您使用 Microsoft 产品或其他供应商产品的经验。但是如果你个人没有在大量密切相关的表和行上进行过实战测试,请不要回答。让我们保持实际 - 不要理论化。
1个回答

7

最好在serverfault.com上询问(我无法发表评论,SO中的脚本已经损坏,所以我必须发布完整的答案)

更新:(切换到Safari后,脚本再次正常工作,我可以正确发布了)

没有万能解决方案。为了使用方便和“一键部署”,没有什么比复制更好的了。它是唯一的解决方案,涵盖了深层次的冲突检测和解决方案,并支持推送模式更改,并配备了全面的设置和监视工具。在这个“议程”被.Net群体接管之前,它一直是数据同步的MS明星孩子。在我看来,复制有两个根本问题:

  • 用于推送更改的技术是原始的、缓慢的和不可靠的。它需要文件共享来启动副本,并且依赖于T-SQL来实际复制数据,导致各种可扩展性问题:复制线程使用服务器工作线程,它们与任意表和应用程序查询交互会导致阻塞和死锁。我听说过的最大部署约为400-500个站点,由超级MVP和高价顾问完成。这在其轨道上阻止了许多从1500个站点开始的项目(远远超出最大部署的复制项目)。如果我错了,您知道有超过500个站点的SQL Server复制解决方案,请告诉我。
  • 复制隐喻过于数据中心化。它没有考虑到分布式应用程序的要求:需要版本化和形式化的契约、数据封闭性、从可用性和安全性角度松散耦合。因此,基于复制的解决方案解决了“使数据在那里可用”的即时需求,但未能解决“我的应用程序需要与您的应用程序通信”的真正问题。
在另一方面,您会发现真正解决应用程序通信问题的解决方案,例如基于排队消息的服务。但是它们要么非常缓慢且存在与通信机制(Web服务和/或MSMQ)以及数据存储(comm和db之间的DTC事务,没有通用的高可用性故事,没有通用的可恢复性故事等等)相关的问题,要么就是在 MS 栈中存在着与 DB 完全集成且速度极快的解决方案,但没有人知道如何使用它们。在这些解决方案和复制之间,您会发现各种中间解决方案,例如 OCS / Synch 框架和基于 SSIS 的自定义解决方案。它们都无法提供复制的设置和监视的便利性,但可能具有更好的扩展性和性能。
我参与了几个需要大规模“数据同步”的项目(+1200个站点,+1600个站点),我的解决方案是将问题转化为“应用程序通信”问题。一旦思维方式改变,数据流不再被视为“表Y中键X的记录”,而是被视为“客户Y购买商品X的消息”,解决方案就更容易理解和应用。你不再考虑“按照顺序X-Y-Z插入记录,以避免外键关系破裂”,而是考虑“按照消息XYZ描述的方式处理购买”。
在我看来,复制及其衍生技术(如数据跟踪和数据包装)是基于“80年代技术和数据/应用程序观点”的解决方案。它们已经过时了(绝不会变成鸟类)。
我知道这甚至没有开始解决您所有(非常合理的)担忧,但是写出我要说/抱怨/讲述这个主题的全部内容将填满数卷平装书...

谢谢,但我是从数据库开发者的角度来看待这个问题,而不是服务器管理员。从软件设计的角度来看,这一点非常重要,不仅仅是一个操作问题。 - Jason Kresowaty
感谢您的见解。请注意,与您完成的项目相比,我特别关注的目标站点数量非常少(1-3个数据库)。意图是在每个节点上运行相同的软件逻辑,因此所涉及的表的数据库模式将是相同的。我理解您所说的“应用程序通信”,这是在涉及不同系统时必须考虑的问题,但我正在寻找一种更通用的解决方案,通过利用模式相同而需要很少的代码。 - Jason Kresowaty
你正在描述复制。如果它符合您的需求,包括所有陷阱,请不要费心重新发明它。在“开箱即用”的复制中已经积累了多年的经验和反馈。您看到的陷阱是在解决更多问题后剩下的,您只需要自己克服这些问题。 - Remus Rusanu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接