我有一个Java主应用程序,它将逐行读取文件。每一行代表订阅者数据。
name, email, mobile, ...
为正在处理的每一行创建一个subscriber对象,然后使用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的,可以用于这种情况。
发布于 2016-06-15 06:24:43
persistSub(sub)
不应立即访问数据库。相反,它应该将sub
存储在长度为500-1000的数组中,并且仅当数组已满或输入文件终止时,才将其包装在Runnable
中并提交到线程池。然后,就像JDBC Batching with PrepareStatement Object中描述的那样,Runnable
通过jdbc访问数据库。
更新
如果写入数据库的速度较慢,而读取输入文件的速度较快,则可能会创建许多包含等待写入数据库的数据的数组,并且系统可能会耗尽内存。因此,persistSub(sub)
应该跟踪已分配数组的数量。最简单的方法是使用允许的数组数量初始化的Semaphore。在分配新数组之前,persistSub(sub)
会生成Semaphore.aquire()
。每个Runnable
任务在结束之前都会生成Semaphore.release()
。
https://stackoverflow.com/questions/37817746
复制相似问题