提高数据库访问的性能

时间:2012-06-19 13:10:37

标签: java performance asynchronous database-performance spring-integration

我有一个应用程序,它侦听UDP数据报的端口。我使用UDP入站通道适配器来侦听此端口。我的UDP通道适配器配置为使用ThreadPoolTask​​Executor来分派传入的UDP数据报。在UDP通道适配器之后,我使用直接通道。我的频道只有一个用户,即服务激活器。

该服务将传入消息添加到存储在内存中的同步列表中。然后,我有一个线程,每5秒检索一次列表内容,并对MySQL数据库进行批量更新。

我的问题:

  1. 第一批消息到达。我的ThreadPoolExecutor的线程从UDP通道适配器获取传入消息并将它们添加到同步列表中。假设已收到并插入了10000条消息。
  2. 后台线程检索10000条消息并进行批量更新(JdbcTemplate.update(String [])。
  3. 此时,后台线程等待来自数据库的响应。但是,现在,因为数据库执行10000 INSERT需要时间,所以已收到20000条消息,并且这些消息已存在于列表中。
  4. 后台线程从数据库接收响应。然后,它检索20000条消息并进行批量更新(JdbcTemplate.update(String [])。
  5. 数据库执行INSERT需要更多时间,在此期间,已收到35000条消息并存储在列表中。
  6. 堆大小不断增长,并在一段时间后导致内存执行。

    我正在尝试找到提高应用程序性能的解决方案。

    由于

4 个答案:

答案 0 :(得分:3)

每5秒存储10,000条记录对于任何数据库来说都是很多。

您需要考虑其他选项

  • 使用不同的数据存储,例如NoSQL数据存储或平面文件。
  • 确保您在磁盘上具有良好的写入性能,例如使用写入缓存。
  • 使用带有多个磁盘或SSD驱动器的磁盘子系统。

答案 1 :(得分:2)

建议

一个。你真的需要一个同步列表吗?难道你不能拥有一组列表,让我们说在这些列表之间分配工作,假设通过对数据的键运行hashCode?

湾你可以使用从列表中读取信息的线程线程池(顺便说一下,我会在这里使用队列),这样,当一个线程由于批量插入很多而“卡住”时,其他线程仍然可以读取“作业” “从队列中执行它们?

℃。您的数据库是否与应用程序共存于同一台计算机上?这可以提高性能

d。你可以发布你的插入查询吗?也许有人可以为您提供优化方法?

答案 2 :(得分:2)

使用数据库连接池,这样您就不必在任何一个线程上等待提交。只需抓住下一个可用的连接并进行并行插入即可。

答案 3 :(得分:1)

我在SQLServer表上每秒获得5.000次插入,但这需要相当多的优化。没有使用下面的所有提示,有些可能对您有用。

  • 查看MySQL插入速度文档提示 http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html
  • 并行化插入过程
  • 尽可能汇总邮件。而不是存储所有消息,而是插入一行,其中包含某个类型的时间范围内的已接收消息的信息等。
  • 将表更改为除主键
  • 外没有索引或外键
  • 切换到写入文本文件(如果你真的想在数据库中插入,那么在夜间导入loaddata批量文件中)
  • 使用单独的数据库实例仅提供表格
  • ...