-4

我有一个计费守护进程,它必须以非常快速的方式处理数十万条数据。我实现ExecutorSerivce了并行处理。它确实提高了速度,但不是很多。处理 1,00,000 条记录大约需要 2.5-3 小时。我怎样才能让它更快,比如在半小时内处理这些数据?

我为执行设置编写了以下内容:

-Xms2048M -Xmx2048M -XX:MaxPermSize=256m

我试图用 1 个生产者和 4 个消费者来实现一个生产者消费者模型。每个列表可以包含 10,000 条记录。

ArrayBlockingQueue<BillableList> list =new ArrayBlockingQueue<BillableList>(10);

ExecutorService threadPool = Executors.newFixedThreadPool(5);
threadPool.execute(new Consumer("pool1", list)); 
threadPool.execute(new Consumer("pool2", list));
threadPool.execute(new Consumer("pool3", list));
threadPool.execute(new Consumer("pool4", list));
Future producerStatus = threadPool.submit(new Producer("Producer", list)); 
producerStatus.get(); 
threadPool.shutdown(); 

在将记录更新到数据库时,我还会收到很多“超出数据库锁定等待超时”异常。是不是因为不同的消费者同时尝试为同一个用户?如何让不同的消费者从ArrayBlockingQueue列表中获取不同的数据?

4

2 回答 2

10

对此唯一可能的答案是“使用分析器并找出它为什么慢”。当你不知道问题出在哪里时,你就无能为力。你打算做什么,选择一个随机函数并对其进行微优化?探查器数据或什么都不会发生。

于 2013-05-04T18:16:03.113 回答
1

我怎样才能让它更快,比如在半小时内处理这些数据?

如果添加线程没有帮助,那么您可能受到的限制不是我的 CPU,而是其他一些因素。很可能是磁盘或网络 IO。如前所述,分析您的代码应该向您展示罪魁祸首。

在将记录更新到数据库时,我还会收到很多“超出数据库锁定等待超时”异常。

这就是你的大线索。无论有多少线程正在处理一项工作,如果它们都在等待数据库,那么添加线程并不会使其更快。

这里有一些想法:

  • 提高数据库盒的物理速度。SSD 可以为 IO 密集型操作提供惊人的改进。由于磁盘缓存,增加内存也可以带来很大的好处。
  • 考虑将数据分片并写入多个数据库实例。鉴于您的架构,这可能是不可能的。
  • 考虑在每 100 次左右的操作后关闭自动提交并手动提交。
  • 注意索引。如果您正在执行某种批量加载,通常如果您关闭索引,您的插入将运行得更快。最后添加索引需要一段时间,但仍然是一个胜利。
  • 此外,如果您正在执行查询,请确保在需要的地方有良好的索引。检查您的数据库日志以查看哪些查询花费的时间太长,以查看您是否在关键位置丢失了某些索引。
于 2013-05-04T18:29:50.160 回答