我有一个Java主应用程序,它将逐行读取文件。每行代表订户数据。
name, email, mobile, ...
为每个正在处理的行创建一个订阅者对象,然后使用JDBC将该对象保存在数据库中。
PS:输入文件有大约1500万个用户数据,应用程序大约需要10-12个小时来处理。我需要将此减少到大约2-3小时,因为此任务是迁移活动,我们得到的停机时间大约为4-5小时。
我知道我需要使用多个线程/线程池,可能是Java的本机ExecuterService。但我也被要求进行批量更新。假设使用50或100个工作线程的线程池并批量更新500-1000个订户。
我熟悉使用ExecuterService但没有获得可以在其中使用批量更新逻辑的方法。
我的整体应用程序代码如下:
while (null != (line = getNextLine())) {
Subscriber sub = getSub(line); // creates subscriber object by parsing the line
persistSub(sub); // JDBC - PreparedStatement insert query executed
}
需要知道一种方法,我可以使用多个线程更快地处理它,并使用批量更新或任何可用于此类情况的现有框架或Java API。
答案 0 :(得分:1)
persistSub(sub)
不应立即访问数据库。相反,它应该将sub
存储在长度为500-1000的数组中,并且仅当数组已满或输入文件终止时,将其包装在Runnable
中并提交给线程池。然后Runnable
通过jdbc访问数据库,就像在JDBC Batching with PrepareStatement Object中描述的那样。
更新
如果写入数据库很慢并且输入文件读取速度很快,则可以创建许多带有数据的数组,等待在数据库中写入,并且系统可能会耗尽内存。所以persistSub(sub)
应该跟踪分配的数组的数量。最简单的方法是使用允许数量的数组进行Semaphore inbitialized。在分配新数组之前,persistSub(sub)
生成Semaphore.aquire()
。每个Runnable
任务在结束之前生成Semaphore.release()
。