繁体   English   中英

从具有多个线程的单个数据库表中获取数据的最佳方法?

[英]Best way to fetch data from a single database table with multiple threads?

我们有一个系统,我们每秒在多个网站上收集有关用户活动的数据。 我们将该数据转储到数据库X中(例如MS SQL Server)。 现在,我们需要从daatbase X的单个表中获取数据,并将其插入数据库Y(例如mySql)。

我们想通过多个线程从数据库X中获取基于时间的数据,以便我们能够尽快获取数据。 一旦获取并存储在数据库Y中,我们将从数据库X中删除数据。

这种设计是否有最佳实践? 餐桌设计上有什么特别要注意的地方,例如共享之类的东西? 还有其他需要注意的事情,以确保从多台计算机上运行的线程以最快的速度获取它吗?

提前致谢! 拉维

如果要将数据从一个数据库移动到另一个数据库,那么让多个线程来工作将不会获得任何优势。 这只会增加争用。

如果两个数据库的类型相同,则应研究供应商特定的复制工具。 从根本上讲,这将永远胜过本地解决方案。

如果数据库不同(供应商),则必须决定一种有效的机制

  1. 识别新/更新/删除的行(触发器,基于范围的查询,完整转储)
  2. 传输数据(卸载到文件和FTP,从程序中拉/推)
  3. 将数据加载到另一个数据库上(导入,批量插入)

如果没有更多细节,再没有比这更具体的了。 哦,影响您选择的两个最重要的注意事项是:

  1. 预期数据量是多少?
  2. 源数据库中的行创建与目标数据库中的可用性之间的最长可接受延迟

我将测试(通过测量)您的假设,即多个slurper线程将加快处理速度。 在您的问题中没有更具体的说明,您似乎想对数据库执行ETL(提取转换负载)过程,当您让特定于数据库的技术来处理它时,这些过程非常有效,特别是如果您对聚合等感兴趣的话。

您的问题有两个关注级别:

  1. 这两个数据库之间的事务:

    这很重要,因为您将从源数据库中删除数据库。 您必须确保仅在数据库成功存储到Y时才从X删除数据。 另一方面,您必须确保必须成功从X删除数据,以防止将相同数据重新插入Y。

  2. 传输数据的性能:

    如果X数据库每时每刻都有传入数据(这是一个联机数据库),则不建议仅收集数据,存储到Y并将其删除。 计划批次的大小后,程序将开始该批次的事务。 重复运行该程序,直到X中的数据数量小于批处理大小为止。

在这两个数据库中,您应该添加一个表来记录要处理的批次。 处理中有三种状态。

INIT - The start of batch, this value should be synchronized between two databases
COPIED - In database Y, the insertion of data and the update of this status should be in one transaction.
FINISH - In database X, the deletion of data and the update of this status should be in on transaction.

编程运行时,它将首先检查处于“ INIT”或“ COPIED”状态的批处理,然后重新启动要处理的会话。

  • 如果X具有“ INIT”记录,而Y没有,则只需将相同的INIT记录插入Y,然后再插入Y。
  • 如果Y中的记录是“ COPIED”,而X是“ INIT”,则只需将X的状态更新为“ COPIED”,然后将其删除为X。
  • 如果X中的记录为“ FINISH”,而Y中的对应记录为“ COPIED”,则只需将Y的状态更新为“ FINISH”。

总之,批量处理数据将使您有机会优化两个数据库之间的传输。 批处理大小的数量决定着转换的效率,它取决于两个因素:其他操作如何同时使用那些数据库以及数据库的调整参数。 在一般情况下,Y的写吞吐量可能是处理的瓶颈。

线程不是要走的路。 数据库是这里的瓶颈。 多个线程只会增加竞争。 即使有10个进程将数据阻塞到SQL Server中,单个线程(而不是多个线程)也可以更快地将其拔出。 对此毫无疑问。

SELECT本身可能会在主表中引起锁定,从而降低INSERT的吞吐量,因此我将尽可能快地“进出”。 如果是我,我会:

  1. 根据范围查询(日期,renoo等)选择行,将其转储到文件中,然后关闭结果集(光标)。
  2. 根据相同的范围查询删除行。
  3. 然后处理转储。 如果可能,转储格式应适合于批量装入MySQL。

我不想破坏您的体系结构,但是总体而言,设计听起来很成问题。 从插入率很高的表中选择和删除行将产生巨大的锁定问题。 我将查看“双缓冲” SQL Server中的数据。

例如,插入每分钟在两个表之间切换。 例如,在第一分钟,INSERT进入TABLE_1,但是当分钟过去时,它们开始INSERT插入TABLE_2,第二分钟又回到TABLE_1,依此类推。 当INSERTS进入TABLE_2时,从TABLE_1中选择所有内容,并将其转储到MySQL中(尽可能有效),然后对表进行TRUNCATE(删除所有行,零罚金)。 这样,读者和作家之间就不会发生争用锁。

协调TABLE_1和TABLE_2之间的转换点是棘手的部分。 但是,可以通过巧妙地使用SQL Server分区视图来自动完成此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM