vm.max_map_count

Elasticsearch는 파일을 메모리에 매핑하고 해당 Lucene MMapDirectory을 통하여 인덱스 샤드가 저장됩니다. 이러한 동작 과정에서 많은 데이터를 처리하기 위해 어느 정도 크기의 가상 주소 공간이 필요합니다. 그러나 기본적으로 대부분의 운영체제에서는 65,630 만큼의 mmap 개수로 설정되어 있는데 이 수치는 elasticsearch를 운영하는데 매우 작은 양입니다. 그래서 별도로 설정을 하지 않고 Elasticsearch를 실행시키면 bootstrap에 의해 해당 vm.map_map_count의 값이 매우 작다는 Error가 발생하면서 Elasticsearch가 종료합니다. 이러한 문제를 해결하기 위해 vm.max_map_count의 값을 262,144 값으로 수정하여 사용하시면 됩니다.

수정 방법

# 명령어로 변경하면 재부팅 시 유지되지 않는다.
$ sudo sysctl -w vm.max_map_count = 262144

# 파일 수정으로 영구적으로 값 유지 vm.max_map_count 수정
$ vim /etc/sysctl.conf

# max_map_count 값 확인
$ sysctl vm.max_map_count

Kubernetes 환경에서 설치된 Elasticsearch는?

kubernetes 환경에서 helm을 통하여 elasticsearch를 설치하셨다면 해당 설정을 굳이 하실 필요가 없는데요 그 이유는 Elasticsearch StatefulSet의 initcontainer의 "configure-sysctl"이라는 컨테이너가 Elasticsearch가 구동되기 전에 해당 설정을 적용하고 Elasticsearch가 동작하기 때문입니다.

 

elasticsearch/template/statefulset.yaml

      - name: configure-sysctl
        securityContext:
          runAsUser: 0
          privileged: true
        image: "{{ .Values.image }}:{{ .Values.imageTag }}"
        imagePullPolicy: "{{ .Values.imagePullPolicy }}"
        command: ["sysctl", "-w", "vm.max_map_count={{ .Values.sysctlVmMaxMapCount}}"]

참고

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-store.html

 

Store | Elasticsearch Guide [8.10] | Elastic

This is a low-level setting. Some store implementations have poor concurrency or disable optimizations for heap memory usage. We recommend sticking to the defaults.

www.elastic.co

https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html

 

Virtual memory | Elasticsearch Guide [8.10] | Elastic

Elasticsearch uses a mmapfs directory by default to store its indices. The default operating system limits on mmap counts is likely to be too low, which may result in out of memory exceptions. On Linux, you can increase the limits by running the following

www.elastic.co


메모리 스와핑 비활성화

대부분의 운영체제에서는 메모리 관리를 효율적으로 하기 위해서 메모리 스와핑이라는 기술을 사용합니다. 메모리 스와핑은 메모리가 부족하거나 현재 사용되지 않거나 우선순위가 낮은 프로세스의 데이터를 메모리 스와핑을 통하여 디스크에 이동시켜 메모리를 효율적으로 사용하는 방법인데 Elasticsearch에서는 이러한 메모리 스와핑이 치명적인 성능 저하의 원인이 될 수 있습니다.

Elasticsearch는 메모리를 많이 사용하는 특성을 가지고 있는데 메모리 스와핑 작업에 의해 가비지 컬렉션이 비정상적으로 느려지며 노드가 데이터를 디스크로 쓰이고 읽어지는 과정에서 데이터를 처리하는데 응답속도가 매우 느려지고 이러한 문제로 인하여 클러스터와의 연결이 끊어지는 문제가 발생하게 됩니다. 그래서 Elasticsearch 공식 문서에서는 메모리 스와핑을 비활성화하는 것을 권장하고 있습니다.

메모리 스왑핑 비활성

# 명령어로 일시적으로 스와핑 비활성화
$ sudo swapoff -a

# 파일 수정으로 영구적으로 비활성화
$ vi /etc/fstab


# 스왑 상태 확인 명령어
$ free
# 스왑 디렉토리 확인
$ cat /proc/swaps
# 스왑 통계 확인
$ sar -B 2 5

메모리 스와핑을 비활성화하기 때문에 Elasticsearch가 동작하는 노드에 다른 애플리케이션이 같이 동작하는 것은 권장하지 않습니다.

메모리 스와핑 비활성을 할 수 없는 상황이라면?

환경 특성상 메모리 스와핑을 비활성화할 수 없는 상황이라면 최대한 스와핑 주기를 낮춰 발생 빈도를 줄이는 방법이 있습니다.

# 명령어로 설정
$ sudo sysctl vm.swappiness=1

# 설정 확인
$ cat /proc/sys/vm/swappiness

memory_lock 설정

만약에 현제 root 권한이 없어 메모리 스와핑 설정이 불가능한 경우에는 bootstrap.memory_lock 설정을 통하여 메모리 스와핑을 최소화할 수 있습니다. 커널 수준에서 제공되는 함수 중에 mlockall()가 있는데 이 함수는 프로세스의 페이징을 금지하고 모든 메모리가 램에 상주하는 것을 보장해 줍니다. memory_lock을 이용하여 애플리케이션에서 메모리를 강제로 스와핑 하지 못하도록 설정합니다.

memory_lock 설정

# memory_lock 설정하기
$ vi ./elasticsearch.yml
bootstrap.memory_lock: true

# Request를 보내 memory_lock 설정 여부 확인하기
curl -XGET http://localhost:9200/_nodes?filter_path=**.mlockall

Kubernetes 환경에서 설치된 Elasticsearch는?

kubelet에서는 메모리 스왑이 기본적으로 off된 환경이라고 합니다. 그렇기 때문에 메모리 스왑핑에 대해서는 kubernetes 환경에서는 굳이 고민을 안 해도 될 것 같습니다. (https://github.com/elastic/helm-charts/issues/7)

참고

https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration-memory.html

 

Disable swapping | Elasticsearch Guide [8.10] | Elastic

mlockall might cause the JVM or shell session to exit if it tries to allocate more memory than is available!

www.elastic.co


Max open file 설정

Elasticsearch에서는 클러스터의 노드끼리 소켓을 사용해 통신을 하며, 루씬 인덱스에서 데이터를 색인 처리하는데 많은 수의 파일을 사용하고 있습니다. 그렇기 때문에 파일을 열람할 수 있는 크기가 매우 작으면 문제가 될 수 있기 때문에 설정을 통하여 max open file의 수를 지정해 주어야 합니다.

max open file 설정

# 명령어를 통하여 일시적인 적용
$ sudo su
$ ulimit -n 81920

# 파일 수정을 통하여 영구적인 적용
$ vim /etc/security/limits.conf
irterm  softnofile  81920
irterm  hardnofile  81920

max file 설정 값 확인

curl -XGET http://localhost:9200/_nodes/stats/process

위 Request를 통해 open_file_descriptors로는 현재 열려 있는 파일 디스크립트의 개수를 알 수 있으며, max_file_descriptors를 통하여 최대 사용 가능한 파일 디스크립터의 개수를 확인할 수 있습니다.

참고

https://www.elastic.co/guide/en/elasticsearch/reference/current/setting-system-settings.html

 

Configuring system settings | Elasticsearch Guide [8.10] | Elastic

Ubuntu and limits.conf Ubuntu ignores the limits.conf file for processes started by init.d. To enable the limits.conf file, edit /etc/pam.d/su and uncomment the following line: # session required pam_limits.so

www.elastic.co

 

+ Recent posts