OOM в Docker с Spring Boot + H2 + JPA и пакетной обработкой - PullRequest
1 голос
/ 05 марта 2020

Приложение java выполняется внутри контейнера docker.

Документы, полученные контроллером остатка и от другого микросервиса, временно хранятся во внутренней базе данных H2 (в памяти). Затем они обрабатываются с помощью тика и отправляются в следующий микросервис. В конце документы удаляются во внутренней базе данных.

Это все работает как задумано. Размер документа в базе данных увеличивается и уменьшается во время обработки (управляется с помощью веб-консоли H2).

Класс сохраняемого документа выглядит следующим образом:

@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() {
}

Но проблема заключается в увеличении потребления памяти docker контейнер. Мы попробовали с MEMORY_MAX 3 и 6 ГБ. В обоих случаях использование памяти медленно увеличивалось до тех пор, пока контейнер не вышел со статусом 137 (уничтожено).

После обработки около 50'000 файлов состояние таблиц выглядит следующим образом:

enter image description here

Дамп относительно JVM внутри контейнера сделано с помощью jmap показывает, что большая часть памяти используется MVMap (PageReferences), который, кажется, используется из H2 для хранения данных:

enter image description here

enter image description here

Мои вопросы:

Скорее всего, это утечка памяти внутри H2 или это скорее конфигурация? Я попытался изменить используемый метод JPARepository с .save () на .saveAndFlu sh (), который ничего не изменил. Я не могу представить, что это как-то связано с Entity Manager, поскольку все это управляется Spring Boot.

1 Ответ

0 голосов
/ 06 марта 2020

Наиболее вероятной причиной является то, что вы не вызываете commit (), что означает, что старые версии данных никогда не сбрасываются

...