【发布时间】:2010-12-24 02:01:29
【问题描述】:
我这样做是为了说明我是一个相对的 Java/Scala 新手,所以我不排除有一些明显的事情我没有做。
我有一个 Scala 应用程序,它通过 Hibernate 连接到 MySQL 数据库。该应用程序旨在处理大量数据,大约 2,750,000 条记录,因此我尝试尽可能优化它。
它在我的工作站上运行,该工作站是配备 6Gb RAM(1033Mhz)的 QuadCore Intel Xeon,它在前 70k 条记录中运行良好且快速,大约在 15 分钟内完成。到了 90k 时,它花了大约 25 分钟,所以有些东西让它变得缓慢。
我检查了 Hibernate 代码上的计时器,并且数据库检索的时间与往常一样。我什至尝试过强制手动垃圾收集来尝试这样做,但这也不起作用。
有问题的代码类似于:
val recordCount = repo.recordCount
val batchSize = 100
val batches = (0 to recordCount by batchSize).toList
val batchJobs = {
for (batchStart <- batches) yield {
future(new RecordFormatter().formatRecords(new Repo(sessionFactory.openSession),batchStart,batchSize)
}
awaitAll(100000,batchJobs: *_)
在 RecordFormatter 内部(它实际上并没有被命名,以防你对我的命名方案感到疑惑),它会查询接下来的 100 条记录,然后另一个查询来拉回实际记录(在开始和结束值)然后将它们以 CSV 格式写入文本文件。查看计时器输出,记录格式化程序中的每个操作大约需要 5 秒来拉回记录,然后需要 0.1 秒来将其输出到文件。
尽管速度变慢了,但它每分钟只处理大约 12 批 100 条记录,而不是在流程刚开始时每分钟 40 批 100 条记录。
它会定期刷新 Session 并在每次 RecordFormatter 运行结束时关闭它(每个 RecordFormatter 都有自己的会话)。
我主要在寻找 Scala 和 Futures 的任何已知问题。我注意到,当它变慢时,它似乎并没有使用所有八个可能的线程,这当然可以解释速度下降,但对我来说,为什么它会突然停止并始终保持在 75k 记录标记附近是个谜。
谢谢!
编辑:更新代码以显示它使用 yield 和 awaitAll 以防万一。
【问题讨论】:
标签: scala concurrency