在基于Spring的应用程序服务器上下文中运行,有时需要 来处理一个大表中的高速数据库插入。当前的实现使用Spring Data与OpenJPA,并连接到Amazon RDS(Postgresql 9.6)数据库。当它需要持久化时,它只需调用Spring提供的save
方法。在测量性能后,我们发现它能够每秒写入大约4000条记录。
我们构建了一个虚拟应用程序来测试几种方法,并发现通过并行使用4个连接每批进行1000次插入,可以获得最佳性能,大约每秒13500条记录。
现在,我们需要更改应用程序的代码以将其持久对象缓冲到1000(或以其他方式配置),在这些缓冲区已满或在某个超时期限之后或在服务器关闭时运行批量插入过程。
之前有人遇到过这样的问题吗?有关线程问题,同步,数据结构的任何建议吗?
提前致谢, 阿德里安。
答案 0 :(得分:1)
听起来你需要写一个例如对每个数据更改进行排队,让这个队列服从可配置的持续时间(又称“后写延迟”)和最大大小。当数据发生更改时,会将其添加到后写队列(如果它尚未在队列中),只要满足以下条件之一,就会将其写入底层存储:
如果是这样,那么这个领域就有很多现有技术。例如,Spring的Cache Abstraction允许您添加缓存层,它支持符合JSR-107的缓存,例如Ehcache 3.x,它提供write behind缓存写入器。 Spring的缓存服务是一个抽象而不是一个实现,它的想法是,当你继续提供商店和代码与商店交互时,它将为你提供缓存逻辑。
重新提出问题的这一部分:
有关线程问题,同步,数据结构的任何建议吗?
缓存抽象和选择的缓存实现(例如Ehcache)将关注线程和同步,并将为您提供诸如队列大小,并发级别,批量大小,最大写入延迟等的杠杆,以允许您配置其行为。因为它只包装您现有的代码,所以您不需要更改现有的数据结构;只需将现有类型写入缓存,并在委托给现有的商店/存储库实现后将缓存看作是/当它决定需要后写时。