将分布式数据收集到中央数据库

Gathering distributed data into central database

我被指派更新现有系统,该系统从销售点收集数据并将其插入中央数据库。现在正在运行的是基于FTP/SFTP传输,每天发送一次信息,通常是在晚上。不幸的是,由于连接链路不稳定(低质量的 2G/3G 调制解调器),一些文件似乎已损坏。只有几家商店以这种方式连接,一切都运行顺利,但随着商店数量的增加,错误变得更加频繁。更糟糕的是,将数据插入中央数据库所需的时间最多需要 12 - 14 小时(包括等待从所有商店下载数据),而且这不会发生在工作日,因为它会阻塞进程使用数据库创建销售报告和其他活动 - 所以我们这里的处理时间真的很紧。

我的经理建议的想法是在白天连续发送数据。数据包会小得多,因此它们的传输和插入会快得多,中央服务器将包含实际(几乎实时)数据,夜间可用于长时间 运行ning 数据库活动,如创建备份、重建索引等.

翻了很多网站,我发现:

这就是我感到困惑的地方。有这么多选择,你对这些技术有什么优缺点吗? 我们使用带有 Windows Forms 和 SQL Server 的 .NET,但如果有必要,我们可以更改为更合适的东西。我也有点担心服务器效率。经过一些计算,服务器每秒将接收大约 15 个数据包(峰值)。很多吗?我知道有很多网站没有严格的服务器基础设施,可以处理数百个在线访问者并且仍然运行流畅,但是该网站主要是将数据上传到客户端,这里我们从客户端下载。

我也发现了一些类似的问题:Middleware to build data-gathering and monitoring for a distributed system 提到 DDS 的地方。您如何看待引入一些中间件服务器来处理低质量的销售点链接,这样主服务器就不会被 1KB/s 的传输阻塞?

如果你能提供帮助,我将不胜感激。提前致谢!

Rabbitmq 可以轻松应对每秒数千条 1kb 的消息。

由于您的用例与处理实时数据无关,我认为您应该合并几条消息并将它们作为批次发送。这足以在一天内分散负载。

由于这里的动机不是实时处理数据,因此任何传输层都可以完成这项工作。甚至ftp/sftp。由于 rabbitmq 在这里可以正常工作,所以这不是它的典型用例。

正如您提到的,您担心的问题之一是 slow/unreliable 网络,我建议在发送文件之前压缩文件,并在接收端立即验证其完整性。 Rsync 或类似的工具可能会在这方面做得很好。

据我了解,你基本上有两个问题:

  1. 通话数据 loss/corruption 的潜力
  2. 数据库写入性能

潜在的 loss/corruption 呼叫数据是由于从客户端到服务的数据传输缺乏可靠性造成的。

目前还不清楚是什么导致了数据库 contention/performance 问题,除了对高容量的模糊引用之外,所以这个答案将更倾向于解决第一个问题。

您已经正确地确定了对可靠异步通信传输的需求,以此作为解决当前设置中可靠性问题的一种方式。

查看 MSMQ 来交付这是有效的第一步。 MSMQ 通过 store and forward 开箱即用的消息语义提供可靠的通信,几乎不需要配置。

不幸的是,尽管 MSMQ 适合您的需求,但它依赖于两件事:

  1. 可靠的网络协议,并且
  2. 发送和接收机器上的客户端服务运行。

从你上面的描述来看,我认为 1 不存在(互联网不是可靠的网络),你可能很难接受 2 - MSMQ 只附带 Windows 服务器或 business/enterprise 版本的 Windows 在桌面上。(*见下文...)

作为网络可靠性问题的可能解决方案,您可以使用 WCF 或 RESTful 端点(使用 Nancy or WebApi)来公开通过 HTTP 公开的服务操作,这将接受来自客户端机器的来电。这些技术截然不同,因此您需要确保尽早做出正确的选择。

WCF 开箱即用地支持 SOAP 1.2 规范中的 WS-ReliableMessaging,这允许通过 http 进行可靠的 Web 服务调用,但是它的配置非常繁重,通常不是一个很好的框架。

REST 比.Net 中的WCF 简单得多,非常轻量级且易于使用。但是,为了可靠地交付,您将不得不公开某种 GET 操作(除了 POST 以允许客户端发送数据)被调用(在合理的时间范围内)以验证数据已提交.如果 GET "acknowledgement" 的结果是否定的,客户端将不得不实现某种重试语义。

尽管 WCF 路由需要两个操作而不是一个操作,但我更喜欢 REST 方法。我已经做了很多,并且发现 REST 服务更好用。

(*) 这并不是说 MSMQ 在您的最终解决方案中不起作用,只是它不会用于解决传输可靠性问题。然而,它仍然可以用来解决您的另一个问题,即数据库写入争用。如果您要在传入请求进入服务器后对其进行排队,那么这些请求可以由 "offline" 进程处理,然后该进程可以以可靠的方式执行所需的数据库操作。这可以通过使用 MSMQ 事务队列来完成。

回复评论:

99% messages are passed from shop to main server, but if some change is needed (price correction, discounts etc.), that data has to be sent to shop.

这种变化。如果我从一开始就明白您有双向需求,并且看到您是如何设法建立 msmq 通信的,我会把您推向 NServiceBus,这是一个非常非常酷的 MSMQ 包装器。我会这样做的原因是你似乎既有一种方式,也有一种发布-订阅的要求,NServiceBus 很好地支持了这一点。