我目前正在一个有十个节点的集群中针对 mysql 编写 java 项目。该程序只是从数据库中提取一些信息并进行一些计算,然后将一些数据推回数据库。但是,表中有数百万行。有什么方法可以拆分工作并利用集群架构?如何在不同的节点上进行多线程?
5 回答
除非您的计算非常复杂,否则大部分时间将用于从 MySql 检索数据并将结果发送回 MySQl。
由于您只有一个数据库,因此应用程序端的并行性或集群不会有太大的不同。
因此,如果可能的话,最好的选择是在纯 SQL 中进行更新,或者使用存储过程,以便所有处理都可以在 MySql 服务器中进行,并且不需要数据移动。
如果这还不够快,那么您将需要将数据库拆分为多个 MySql 实例,并提出一些模式来根据某些应用程序键对数据进行分区。
假设您要处理的表 (A) 有 1000 万行。在数据库中创建表 B 以存储节点处理的行集。因此,您可以编写 Java 程序,使其首先获取其他节点处理的最后一行,然后在同一个表中添加一个条目,通知其他节点它将处理的行范围(您可以决定这个数字)。在我们的例子中,假设每个节点一次可以处理 1000 行。节点 1 获取表 B 并发现它是空的。然后节点 1 插入一行 ('Node1', 1000) 通知它正在处理,直到 A 的主键 <=1000 (假设表 A 的主键是数字并且它是按升序排列的)。节点 2 来了,发现 1000 个主键正在由其他节点处理。因此它插入一行('Node2',
我会考虑在数据库服务器上的存储过程中进行该计算,并将数百万行传递到中间层。您将在网络上节省大量字节。根据计算的性质、架构、索引等,您可能会发现数据库服务器可以很好地执行该计算,而无需求助于多线程。
我可能是错的,但值得一看原型。
由于您只有一个 mysql 服务器,因此请确保您使用 innodb 引擎来减少更新时的表锁定。
此外,即使您必须运行更多查询,我也会尽量让您的查询保持简单。这可以增加查询缓存命中的机会,并减少后端的总体工作量,将一些查询匹配和工作转移到前端(您拥有更多资源的地方)。它还将减少持有行锁的时间,从而减少争用。
建议的 Gearman 解决方案可能是完成这项工作的正确工具。因为它将允许您透明地将批处理从 mysql 卸载回集群。
您可以在每台机器上使用 mysql 设置分片,但与 gearman 解决方案相比,设置时间、维护和对数据库访问层的更改可能需要大量工作。您可能还想查看可以让您同时使用多个 mysql 的实验性蜘蛛引擎。