【问题标题】:java batch insertion methodjava批量插入方法
【发布时间】:2018-01-06 00:06:06
【问题描述】:

在基于 Spring 的应用程序服务器上下文中运行的应用程序有时需要处理对一张大表的高速数据库插入。当前实现在底层使用 Spring Data 和 OpenJPA,并连接到 Amazon RDS (Postgresql 9.6) 数据库。当它需要持久化某些东西时,它只调用 Spring 提供的 save 方法。在测量性能后,我们发现它每秒可以写入大约 4000 条记录。

我们构建了一个虚拟应用程序来测试几种方法,并发现通过使用 4 个并行连接每批执行 1000 次插入可以产生最佳性能,大约每秒 13500 条记录。

现在,我们需要更改应用程序的代码以将其持久对象最多缓冲 1000 个(或以其他方式配置),当这些缓冲区已满或在某个超时时间后或服务器关闭时在这些缓冲区上运行批量插入过程。

有人遇到过这样的问题吗?有关线程问题、同步、数据结构的任何建议?

提前致谢, 阿德里安。

【问题讨论】:

  • 要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,describe the problem 以及迄今为止为解决它所做的工作。
  • @JoeC 有时我们想要固执己见的答案。在得到十个这样的答案后,我们可以自己进行比较并做出决定。现在,我们被一个通用的答案和使用一些巨型怪物库的提示所困。那不是很有用。将问题标记为已回答...

标签: java sql spring performance


【解决方案1】:

听起来你需要在后面写,例如对每个数据更改进行排队,让这个队列受制于可配置的持续时间(也称为“延迟写入”)和最大大小。当数据发生变化时,它会被添加到 write-behind 队列中(如果它还没有在队列中),并且只要满足以下条件之一,它就会被写入底层存储:

  • 延迟写入过期
  • 队列超出了可配置的大小
  • 系统进入关机模式,您要确保没有数据丢失

如果是这样,那么这个领域有很多现有技术。例如,Spring 的 Cache Abstraction 允许您添加缓存层,它支持符合 JSR-107 的缓存,例如提供 write behind 缓存写入器的 Ehcache 3.x。 Spring 的缓存服务是一种抽象而非实现,其理念是它会在您继续提供 store 和与 store 交互的代码时为您处理缓存逻辑。

关于您问题的具体部分:

关于线程问题、同步、数据结构的任何建议?

缓存抽象和选择的缓存实现(例如 Ehcache)将关注线程和同步,并为您提供队列大小、并发级别、批处理大小、最大写入延迟等杠杆,以允许您配置其行为。而且由于它只会包装您现有的代码,因此您无需更改现有的数据结构;只需将现有类型写入缓存,并在决定需要后写时让缓存在委派给现有存储/存储库实现后进行处理。

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    相关资源
    最近更新 更多