일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- tcp
- ip
- Vision
- JavaScript
- zookeeper
- EC2
- jvm
- docker
- airflow
- Kafka
- Packet
- log
- CSV
- PostgreSQL
- kubectl
- Trino
- AWS
- Python
- aws s3
- Network
- Spring
- grafana
- java
- Operating System
- kubeadm
- kubernetes
- CVAT
- helm
- MAC address
- OS
- Today
- Total
JUST WRITE
Doc에 있는 JVM 설정 파헤치기 본문
Doc에 있는 JVM 설정 파헤치기
Kafka를 운영하다 보면 설정해야 될게 한두 가지가 아닙니다.
Broker, Partition, Retention, Compression 등 이외에도 신경 써야 할 게 너무 많습니다.
저도 운영을 하다 보니 점점 Kafka의 사용도가 커지고 데이터 처리량이 많아지고 있습니다.
Kafka 데이터 처리 성능과 관련된 설정을 찾아보게 되었습니다.
여러 가지가 있었지만 저의 눈에 띄었던 거는 Java 관련 설정이었습니다.
이번 포스팅에서는 Kafka Document에 있는 JVM 설정 Argument를 하나하나 살펴보겠습니다.
Kafka Java
Kafka는 JVM 위에서 동작하는 Java와 Scala로 개발되었습니다.
그래서 Kafka 설치에 앞서 JVM 설치가 필수적입니다.
현재 Java 8, 11, 17까지 지원하고 있으며, Main 버전 4부터는 Java 8을 지원하지 않는다고 합니다.
jps command로 Kafka Process를 확인할 수 있습니다.
$ jps -v
5428 QuorumPeerMain -Xmx512M -Xms512M -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.awt.headless=true -Xlog:gc*:file=/home/ec2-user/kafka/bin/../logs/zookeeper-gc.log:time,tags:filecount=10,filesize=100M -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/home/ec2-user/kafka/bin/../logs -Dlog4j.configuration=file:bin/../config/log4j.properties
7961 Kafka -Xmx1G -Xms1G -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.awt.headless=true -Xlog:gc*:file=/home/ec2-user/kafka/bin/../logs/kafkaServer-gc.log:time,tags:filecount=10,filesize=100M -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/home/ec2-user/kafka/bin/../logs -Dlog4j.configuration=file:bin/../config/log4j.properties
9803 Jps -Dapplication.home=/home/ec2-user/jdk-11.0.2 -Xms8m -Djdk.module.main=jdk.jcmd
JVM
JVM은 Java Virtual Machine의 약자입니다.
Java의 큰 장점 중 하나인 OS에 종속되지 않는 것은 JVM 덕분입니다.
- Java Source Code(.java)를 compile해서 Byte Code(.class) 생성
- JVM을 통해 Memory에 Load
- Java Process 실행
위 과정을 통해서 Java Program을 실행합니다.
JVM 위에서 Java Program이 실행되기 때문에 JVM을 어떻게 설정하는가가 굉장히 중요합니다.
JVM에 대한 자세한 설명한 따로 포스팅을 하도록 하겠습니다.
Kafka Document
Kafka Document에 JVM에 관련된 Reference를 제시하고 있습니다.
대규모 서비스인 LinkedIn에서 설정했던 방식이라고 합니다.
-Xmx6g -Xms6g -XX:MetaspaceSize=96m -XX:+UseG1GC
-XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M
-XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80 -XX:+ExplicitGCInvokesConcurrent
지금부터 하나하나 살펴보도록 하겠습니다.
Xmx, Xms
Xmx와 Xms는 Java Heap 크기를 세팅하는 옵션입니다.
Java Process를 실행할 때 Memory를 3가지 영역으로 나눠서 사용합니다.
그중에 한 영역을 Java Heap이라고 하며 인스턴스 변수(객체)들이 저장되는 영역입니다.
Xms는 Java Process 시작 시 Java Heap 크기이며,Xmx는 최대로 할당되는 Java Heap 크기입니다.
Kafka에서는 default로 Xmx 1G, Xms 1G로 세팅되어 있습니다.
아래는 kafka-server-start.sh 파일입니다.
if [ "x$KAFKA_LOG4J_OPTS" = "x" ]; then
export KAFKA_LOG4J_OPTS="-Dlog4j.configuration=file:$base_dir/../config/log4j.properties"
fi
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
fi
EXTRA_ARGS=${EXTRA_ARGS-'-name kafkaServer -loggc'}
MetaspaceSize
Metaspace는 Java 8부터 생겼습니다.
이전에는 Permenet Generation이었지만 Metaspace가 이를 대체하게 되었습니다.
Java Class들의 Metadata가 저장되는 공간입니다.
Heap 영역이 아닌 Native Memory에 저장됩니다.(OutofMemoryError 발생률 ↓)
--XX:MetaspaceSize=96m은 Metaspace의 초기 Size를 96Megabyte로 설정한다는 것입니다.
설정한 Size에 도달하면 GC가 일어나 오래된 class metadata를 청소합니다.
-XX:MetaspaceSize=size
Sets the size of the allocated class metadata space that will trigger a garbage collection the first time it is exceeded. This threshold for a garbage collection is increased or decreased depending on the amount of metadata used. The default size depends on the platform.
--XX:MinMetaspaceFreeRatio는 GC이후에 Memory에서 Class Metadata를 사용할 수 있는 최소 비율입니다.
--XX:MaxMetaspaceFreeRatio는 GC이후에 Memory에서 Class Metadata를 사용할 수 있는 최대 비율입니다.
UseG1GC
Java에서 Garbage Collector의 종류는 아래와 같이 있습니다.
- Serial Garbage Collector
- Parallel Garbage Collector
- CMS Garbage Collector
- G1 Garbage Collector
해당 옵션은 G1 Garbage Collector를 사용하겠다고 세팅합니다.
Oracle에서 G1 GC를 Multi Processor, large Memory(4GB ↑)에 적합하다고 안내하고 있습니다.
위 4개 중에서는 G1 GC의 성능이 가장 좋다고 알려져 있습니다.
Kafka에서도 이미 G1 GC를 default로 사용하도록 설정되어 있습니다.
아래는 kafka-run-class.sh 파일 내용 중 일부입니다.
if [ -z "$KAFKA_JVM_PERFORMANCE_OPTS" ]; then
KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.awt.headless=true"
fi
InitiatingHeapOccupancyPercent
최초로 해당 값만큼 Heap 공간을 차지하고 있을 때 Concurrent GC가 시작하는 옵션입니다.
default값은 45로 Document에는 더 작은 35로 세팅합니다.
이렇게 해서 Full GC가 되는 비율을 줄이려는 전략 같습니다.
G1HeapRegionSize
Heap 하나의 Region의 크기를 설정하는 옵셥입니다.
1M에서 32M까지 설정할 수 있습니다.
G1은 Heap을 동일한 크기로 나눠서 하나의 집합으로 사용합니다.
ExplicitGCInvokesConcurrent
해당 옵션을 사용하면 System GC대신 Concurrent GC를 수행합니다.
"System.gc()" Request가 들어오면 Concurrent GC를 수행해서 Full GC를 피할 수 있습니다.
-XX:+UseConcMarkSweepGC 이나 -XX:+UseG1GC 옵션과 같이 사용해야 합니다.
정리
이번 Kafka JVM 설정 포스팅을 작성하면서 많은 개념을 배울 수 있었습니다.
Document에 있는 설정의 핵심은 Full GC, Stop the world를 최대한 안 하게 하기 위한 설정이라 생각됩니다.
다음 포스팅에서 좀 더 JVM, G1GC, Heap에 대해서 정리하는 포스팅을 준비하도록 하겠습니다.
[참고사이트]
'MLOps > Kafka' 카테고리의 다른 글
Consumer야 살았니?! 죽었니?! - Kafka Consumer Heartbeats (0) | 2023.11.27 |
---|---|
1개로 부족해, 2개의 IP로 접근하기 (0) | 2023.09.05 |
큰일 났다! Out of Sync다?!?! (0) | 2023.07.27 |
Kafka야?!? 데이터 잘 처리하고 있니?! (0) | 2023.06.21 |
Kafka 재시작 후 UNKNOWN_TOPIC_ID 에러?! (0) | 2023.06.14 |