我有一个很大的SQLite数据库要处理,所以我想使用MPI进行并行化以加快速度。我想要做的是从root发送数据库到每个slave,并在slave从中添加一些表后将修改后的数据库发送到root。我想使用MPI_Type_create_struct
创建一个数据类型来存储数据库,但数据库太复杂了。有没有其他方法来处理这种情况?先感谢您!
答案 0 :(得分:0)
我最近处理过类似的问题 - 我有一个使用SQLite作为配置存储的大型MPI应用程序。处理多进程写入是嵌入式SQL数据库的挑战。我对此的体验涉及使用共享文件系统的大规模并行应用程序(运行高达65,535个级别)。
基于SQLite的FAQ和数据库引擎的一些经验,有几种方法可以解决这个问题。我假设您正在使用共享分布式文件系统和多个单独的计算机(标准HPC群集设置)。
由于SQLite将阻止多个进程写入数据库(但未读取),因此读取很可能不是问题。每个进程可以同时运行多个SELECT命令而不会出现问题。
挑战将在于写作。磁盘I / O比计算慢几个数量级,因此通常这将成为瓶颈。话虽如此,网络通信也可能是一个显着的减速,所以你如何处理问题实际上取决于你的运行环境最薄弱的环节。
如果你的网络速度很快,磁盘速度很慢,或者你想以最简单的方式实现这一点,最好的办法是让单 MPI级别负责写入数据库。您的计算进程将独立运行SELECT命令,直到计算完成,然后将新数据发送到MPI数据库进程。然后,数据库控制进程将新数据写入磁盘。我不会尝试通过网络发送数据库的结构,而是发送应该写入的数据,以及(可能)一个标志,该标志将标识应该写入数据的表/插入查询。这种技术类似于RDBMS的工作方式 - 虽然RDBMS服务器确实支持并发写入,但是有一个" central"控制写操作顺序的过程。
需要注意的一点是,如果进程写入SQLite数据库,则该文件将被锁定,以便所有进程尝试读取或写入该进程。您需要在工作进程中处理SQLITE_BUSY返回代码,注册回调以处理此问题,更改繁忙行为或使用替代技术。在我的应用程序中,我发现将数据库作为内存数据库加载(https://www.sqlite.org/inmemorydb.html)为读者提供了一个很好的解决方法。读者访问内存数据库,但将结果发送到控制进程进行写入。缺点是您将在内存中拥有多个数据库副本。
可能网络密集程度较低的另一个选项是同时执行读取并让每个工作进程写入自己的文件。您可以写出来分离SQLite数据库文件,甚至可以导出像CSV这样的东西(取决于数据的复杂性)。写入完成后,您将有一个进程将各个文件合并到一个结果数据库文件中 - 请参阅How can I merge many SQLite databases?。这种方法有其自身的问题,但根据您的瓶颈所在以及整个系统的布局方式,这种技术可能会有效。
最后,您可以考虑从SQLite数据库中读取并将数据保存为适当的分布式文件格式,例如HDF5(或使用MPI IO)。一旦完成计算,编写一个可以从这种外来文件格式创建新SQLite数据库的脚本将非常简单。