简体   繁体   English

Docker 中的 OOM 与 Spring Boot + H2 + JPA 和批处理

[英]OOM in Docker with Spring Boot + H2 + JPA and Batch Processing

The java application is running inside a docker container. Java 应用程序在 docker 容器内运行。

Documents received by rest controller and from another microservice are temporarly stored in internal H2 database (in memory).休息控制器和另一个微服务收到的文档暂时存储在内部 H2 数据库中(在内存中)。 These are then processed with help of tika and sent to next microservice.然后在 tika 的帮助下处理这些并发送到下一个微服务。 At the end documents are deleted in internal database.最后文件在内部数据库中被删除。

This all works as intended.这一切都按预期工作。 Document size in database is increasing and decreasing during processing (controlled with help of H2 web-console).数据库中的文档大小在处理过程中会增加和减少(在 H2 网络控制台的帮助下进行控制)。

Class of Persisted Document looks as follow:持久化文档类如下所示:

@Entity
@Table(name = "Document")
public class Document {
@Id
@GeneratedValue
Long id = 0L;
@Lob
private String content;
@Lob
private String contentHtml = "";
@ElementCollection
@MapKeyColumn(name = "name")
@Column(length=1000, name = "value")
@CollectionTable(name = "meta_attributes", joinColumns = @JoinColumn(name = "meta_id"))
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, String> metadata;
@Enumerated(EnumType.STRING)
private DocStatus status;

public Document() {
}

But problem is increasing memory consumption of docker container.但问题是增加了 docker 容器的内存消耗。 We tried with a MEMORY_MAX of 3 and 6GB.我们尝试使用 3GB 和 6GB 的 MEMORY_MAX。 In both cases, memory usage slowly increased until container exited with Status 137 (Killed).在这两种情况下,内存使用量缓慢增加,直到容器以状态 137(已终止)退出。

After processing of about 50'000 files, state of tables is as follows:处理了大约 50'000 个文件后,表的状态如下:

在此处输入图片说明

A dump of regarding jvm inside container made with help of jmap shows that most memory is consumed by MVMap (PageReferences) which seems to be used from H2 for storing data:在 jmap 的帮助下制作的关于容器内 jvm 的转储显示,大部分内存被 MVMap(PageReferences)消耗,它似乎从 H2 用于存储数据:

在此处输入图片说明

在此处输入图片说明

My questions:我的问题:

Is this more likely to be a kind of memory leak inside H2 or is it more likely to be a configuration thing?这更可能是 H2 内部的一种内存泄漏还是更可能是配置问题? What I tried was to change used JPARepository method from .save() to .saveAndFlush() whicht did not change anything.我尝试的是将使用过的 JPARepository 方法从 .save() 更改为 .saveAndFlush() ,这没有任何改变。 I cannot imagine that this has something to do with Entity Manager as this is all managed by Spring Boot.我无法想象这与实体管理器有关,因为这一切都由 Spring Boot 管理。

最可能的原因是您没有调用 commit(),这意味着旧版本的数据永远不会被刷新

Update: Cause was not in H2 or JPA but in a bad docker-compose configuration.更新:原因不在 H2 或 JPA 中,而是在糟糕的 docker-compose 配置中。 We did allocate same amount of memory for JVM running inside container (-Xmx$MEMORY_MAX) as well as for docker itself (mem_limit).我们确实为容器内运行的 JVM (-Xmx$MEMORY_MAX) 以及 docker 本身 (mem_limit) 分配了相同数量的内存。

After setting MEMORY_MAX for JVM to a maximum of 80% of mem_limit everything worked fine.将 JVM 的 MEMORY_MAX 设置为 mem_limit 的最大 80% 后,一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM