如何通过 Web 服务对数据进行排队以批量插入数据库?
How can I queue data via a web service for bulk insert to DB?
这是我目前的情况:
我有一堆客户端应用程序当前正在向中央数据库一次插入一条记录。这当然会导致数据库的大量开销,以及客户端应用程序在等待数据库操作完成时潜在的 "pausing" 问题。
所以我想做的是:
我希望每个客户端应用程序都与网络服务对话以写入每条记录,而不是直接与数据库对话。然后,Web 服务会将数据写入文件,然后以给定的时间间隔对其进行处理。我认为这样我可以每 5 分钟左右批量插入 X 条记录,而不是在同样的 5 分钟内插入数千次。如果 Web 服务不可用,客户端应用程序将写入本地计算机上的文件,然后一旦它再次可用,它将发送本地文件中的每条记录。如果数据库出现故障,Web 服务将继续写入文件,直到它可以成功执行批量插入。因此,客户端应用程序可以继续运行,即使其中任何一个出现故障,它也会在事情恢复时赶上来。
问题:
所以我假设如果我有 Web 服务尝试写入同一个文件,这将是一个问题,因为我将有数百个实例同时尝试这样做。我考虑过将每条记录写入其自己的文件,然后将所有现有文件移动到另一个目录以按给定的时间间隔进行处理,但是我不得不处理数百甚至数千个单独的文件,我对此并不是特别兴奋.
那么有更好的方法来处理这个问题吗?是否可以锁定 Web 服务本地文件而不会导致严重的瓶颈或死锁情况?
谢谢,
安德鲁
我建议不要一开始就写文件。让本机(例如 C++)程序侦听这些客户端与之交谈的端口,并且该程序使用多生产者单消费者队列来聚合内存中接收的所有记录,直到达到某个阈值,这并不是非常困难。您可以将其设置为在有 1000 条记录时,或者自上次提交后 5 分钟,它会自动执行批量插入。
写入文件需要太多的锁定和状态管理来处理卷,如果你将它限制为每个 IP 一个文件(正如你所指出的)成千上万的文件是 read/written 不会太多更好。
这是一个疯狂的想法:随着记录的到来,将它们序列化为 JSON 并将它们放入一个单独的 NoSQL 数据库中。你可以随心所欲地扩展它。
有一个服务 运行ning 监视 NoSql 数据库,时不时地,比如说每小时,获取所有记录,批量插入主 sql 数据库并删除从 NoSQL 源插入记录。
这里的重点是避免对您的主要生产数据库施加压力。
您也可以使用消息队列而不是 NoSQL 数据库,同样的原则适用。记录进入队列,队列建立,服务选择所有消息并做它的事情。尽管使用第二种数据库方法,它确实感觉更安全。如果您的消息系统出现故障,您将丢失所有未处理的记录。
-- 在此处添加了更多信息
NoSQL 数据库可以很好地处理并发插入,并且它们也可以轻松扩展,这方面无需担心。
尝试同时写入一个文件很快会给您带来麻烦,您需要考虑如何处理。等到你真正去做的时候,你还不如坚持使用数据库方法。此外,您还可以通过数据库获得所有好东西,如果需要的话,您可以备份数据,或者可以同步它,您可以处理大量数据。基本上你有很多选择。我强烈建议甚至不要尝试用这样的东西写入文件。
现在,对于批量插入,我会避免使用像 Entity Framework 这样的 ORM。如果您的数据相对简单,我会使用该服务创建一个 SQl 脚本,其中包含所有插入内容,并且仅 运行 它针对数据库。拥有这样的脚本化方法实际上非常容易。这里的优点是多方面的:
- 执行速度
- 数据备份和完整性检查 - 您可以比较数据库中的内容和脚本中的内容。
下面是如何从命令行 运行 这样的脚本的示例:https://msdn.microsoft.com/en-us/library/ms170572.aspx
您有多种选择,只需使用更适合您的方法即可。首先尝试使用 ORM 批量插入,计时,如果您不满意,那么您可以使用其他脚本方法或者我什至还没有考虑过的方法。
这是我目前的情况:
我有一堆客户端应用程序当前正在向中央数据库一次插入一条记录。这当然会导致数据库的大量开销,以及客户端应用程序在等待数据库操作完成时潜在的 "pausing" 问题。
所以我想做的是:
我希望每个客户端应用程序都与网络服务对话以写入每条记录,而不是直接与数据库对话。然后,Web 服务会将数据写入文件,然后以给定的时间间隔对其进行处理。我认为这样我可以每 5 分钟左右批量插入 X 条记录,而不是在同样的 5 分钟内插入数千次。如果 Web 服务不可用,客户端应用程序将写入本地计算机上的文件,然后一旦它再次可用,它将发送本地文件中的每条记录。如果数据库出现故障,Web 服务将继续写入文件,直到它可以成功执行批量插入。因此,客户端应用程序可以继续运行,即使其中任何一个出现故障,它也会在事情恢复时赶上来。
问题:
所以我假设如果我有 Web 服务尝试写入同一个文件,这将是一个问题,因为我将有数百个实例同时尝试这样做。我考虑过将每条记录写入其自己的文件,然后将所有现有文件移动到另一个目录以按给定的时间间隔进行处理,但是我不得不处理数百甚至数千个单独的文件,我对此并不是特别兴奋.
那么有更好的方法来处理这个问题吗?是否可以锁定 Web 服务本地文件而不会导致严重的瓶颈或死锁情况?
谢谢,
安德鲁
我建议不要一开始就写文件。让本机(例如 C++)程序侦听这些客户端与之交谈的端口,并且该程序使用多生产者单消费者队列来聚合内存中接收的所有记录,直到达到某个阈值,这并不是非常困难。您可以将其设置为在有 1000 条记录时,或者自上次提交后 5 分钟,它会自动执行批量插入。
写入文件需要太多的锁定和状态管理来处理卷,如果你将它限制为每个 IP 一个文件(正如你所指出的)成千上万的文件是 read/written 不会太多更好。
这是一个疯狂的想法:随着记录的到来,将它们序列化为 JSON 并将它们放入一个单独的 NoSQL 数据库中。你可以随心所欲地扩展它。
有一个服务 运行ning 监视 NoSql 数据库,时不时地,比如说每小时,获取所有记录,批量插入主 sql 数据库并删除从 NoSQL 源插入记录。
这里的重点是避免对您的主要生产数据库施加压力。
您也可以使用消息队列而不是 NoSQL 数据库,同样的原则适用。记录进入队列,队列建立,服务选择所有消息并做它的事情。尽管使用第二种数据库方法,它确实感觉更安全。如果您的消息系统出现故障,您将丢失所有未处理的记录。
-- 在此处添加了更多信息
NoSQL 数据库可以很好地处理并发插入,并且它们也可以轻松扩展,这方面无需担心。
尝试同时写入一个文件很快会给您带来麻烦,您需要考虑如何处理。等到你真正去做的时候,你还不如坚持使用数据库方法。此外,您还可以通过数据库获得所有好东西,如果需要的话,您可以备份数据,或者可以同步它,您可以处理大量数据。基本上你有很多选择。我强烈建议甚至不要尝试用这样的东西写入文件。
现在,对于批量插入,我会避免使用像 Entity Framework 这样的 ORM。如果您的数据相对简单,我会使用该服务创建一个 SQl 脚本,其中包含所有插入内容,并且仅 运行 它针对数据库。拥有这样的脚本化方法实际上非常容易。这里的优点是多方面的:
- 执行速度
- 数据备份和完整性检查 - 您可以比较数据库中的内容和脚本中的内容。
下面是如何从命令行 运行 这样的脚本的示例:https://msdn.microsoft.com/en-us/library/ms170572.aspx
您有多种选择,只需使用更适合您的方法即可。首先尝试使用 ORM 批量插入,计时,如果您不满意,那么您可以使用其他脚本方法或者我什至还没有考虑过的方法。