출처 : https://if.kakao.com/session/25
if(kakao)2021
함께 나아가는 더 나은 세상
if.kakao.com
Flink와 Kubernetes 기반 실시간 로그 처리 플랫폼의 구축 경험을 소개합니다.
먼저, Flink가 무엇인지 간단하게 소개 드리고, Kubernetes 환경에서 Flink를 배포하고 운영할 때 도움이 될만한 부분들을 공유드리고자 합니다.
이를 통해 Kubernetes에서 Flink를 시작하시는 분들에게 조금이나마 도움이 되었으면 좋겠습니다.
리뷰 포인트
- Flink를 선택한 이유
- Flink on Kubernetes 구축과정
- Flink 운영
Flink를 선택한 이유
- 기존에는 Apache Storm을 기반으로 실시간 로그 처리를 수행했다.
- 카카오 서비스의 증가와 사용자의 증가로 수집되는 로그의 양이 점차 늘어나고 있다. 그런데 기존 방식으로는 증가하는 부하를 감당하기 위해 컴퓨팅 리소스를 더 투입하면서 대응하였다.
- 이러한 부하 증가에 대응하고자 신규 실시간 로그 처리 플랫폼 준비
- 고려 요소
- 고성능 - 대량의 로그가 유입되어도 버틸 수 있는가?
- 호환성 - 카카오에서 서비스중인 수많은 서비스와 호환될 수 있는가?
- 안정성 - 최대한 지연/장애가 발생하지 않도록할 수 있는가?
- 비교
- Apache Storm
- Native Stream Support : 가능
- Delivery Guarantees : At-least-once
- Stream data를 처리할 때 유실없이 적어도 한 번은 간다. 하지만 중복이 발생해 두 번이상 같은 데이터가 처리될 수도 있다.
- Kubernetes Support : -
- Apache Flink DataStream API
- Native Stream Support : 가능
- Delivery Guarantees : Exactly-one
- 반드시 한 번만 처리됨 (유실, 중복 없음)
- Kubernetes Support : 가능
- Apache Spark Streaming
- Native Stream Support : 불가능, 기본적으로 배치 처리이므로 실시간 처리는 불가하지만 마이크로 배치를 사용해 유사하게 동작시킬 수는 있음
- Delivery Guarantees : At-least-once
- Kubernetes Support : -
- Apache Storm
- Apache Flink의 특징
- Stream : 실시간성
- Async : 비동기
- Exactly-once : 반드시 한 번만 보장. 중복/유실은 없음
- Master/slaves 구조 : JobManager(Master)/TaskManagers(slaves)
- unified stream and batch process : stream과 batch 처리를 통합하여 데이터를 처리할 수 있어 다양한 비즈니스 로직 개발시 유연하게 대응 가능
- 주기적인 State Snapshot을 통한 Fault-tolerance(내결함성)
Flink on Kubernetes 구축과정
- Flink on Kubernetes는 Kafka를 통해 입력된 Log를 실시간 처리한 후 하둡 HDFS, ElasticSearch, Kafka로 저장하는 역할을 한다.
- Application Claster VS. Session Cluster (클러스터 모드 선택)
- Application Cluster
- 여러 개의 Flink Cluster 즉 master/slaves 그룹이 여러 개
- 각 Job 별로 하나의 Flink Cluster를 가지고 처리됨
- 3개의 Job중 하나가 완료되면 해당 Flink Cluster는 놀게 됨
- 특정 Job에 문제가 발생하면 해당 Job을 실행하는 Flink Cluster만 장애가 발생하므로 다른 Job에는 영향이 없음 -> 안정성을 고려하여 Application Cluster 선택
- Session Cluster
- 하나의 Flink Cluster
- 각 Job들이 slaves(Task Manager)속 slot에 나누어 할당 처리됨
- 3개의 Job중 하나가 완료되어도 Flink Cluster는 여전히 동작함
- 특정 Job에 문제가 발생하면 모든 Job에 영향을 미친
- Application Cluster
- Kubernetes 리소스 설정(Yaml 작성)
- Object (kind)
- Job : 실행이 완료되면 종료되는 성격의 작업(프로세스), 실패시 주어진 정책에 따라 재실행하는 Object이다.
- JobManager(Master)
- Deployment : Pod의 확장된 Object이다., Pod(container 모음)+ReplicaSet(replica 수 만큼 Pod 유지)+history(기록)
- TaskManagers(slaves, replica 수 만큼 뜨게 된다.)
- Service : 어떤 애플리케이션이 Pod에서 실행될 때 사용되는 경우 해당 Pod의 IP는 알 수 없다. 하지만 Service의 경우 고정된 IP와 DNS 주소를 가지며, Service를 통해 Pod에 접근할 수 있고, 만약 여러 Pod를 통해 애플리케이션이 트래픽을 분산 처리한다면 로드밸런싱 역할도 하는 Object이다.
- Rest
- UI Port Open
- ConfigMap : container 환경 설정
- Log4j configuration
- Flink configuration
- Job : 실행이 완료되면 종료되는 성격의 작업(프로세스), 실패시 주어진 정책에 따라 재실행하는 Object이다.
- Object (kind)
Flink 운영
- 모니터링해야 하는 성능 지표
- Flink Checkpoint
- Checkpoint는 Exactly-once를 보장하기 위해 사용하는 알고리즘으로 오류로 인한 잡 복구 시 사용하기 위해 주기적으로 생성하는 Snapshot을 말한다.
- Flink는 기본적으로 분산처리이기 때문에 하나의 data stream이 여러 개의 data stream으로 분산처리된다. 이때 어떠한 이유로 data stream 간 속도차이가 발생할 수 있기 때문에 data stream을 나누기 전에 data stream에서 흘러가는 각 element 사이사이에 checkpoint barrier를 섞고, data stream 분산되어 처리될 때 해당 checkpoint barrier를 기준으로 동기화를 진행한다.
- 동기화 과정은 설정된 duration 안에 완료되어야 하는데 만약 완료되지 않는다면 checkpoint 실패가 발생한다.
- checkpoint 실패는 곧 이전 checkpoint와 실패한 checkpoint 사이의 작업들 실패를 의미하기 때문에 이전 checkpoint로 복구를 수행한다. -> 성능 저하 발생
- 즉, checkpoint 실패가 없어야 Flink가 최상의 성능으로 동작한다는 것을 의미한다.
- Backpressed
- 출력 버퍼가 가득찬 상태
- 이 상태로 시간이 지나면 입력 버퍼도 가득차게 됨 -> 성능 저하 발생
- Busy
- 입력 버퍼가 가득찬 상태
- 이 상태로 시간이 지나면 전 단계의 출력 버퍼도 가득차게 됨 -> 성능 저하 발생
- Flink Checkpoint
- 성능 개선 방법
- TaskManager를 늘린다. -> 리소스 한계에 직면, 배포 성능 저하
- Flink Async I/O
- Helm을 활용한 배포 환경 개선
- Helm(헬름)을 이용하면 서로다른 Job들을 손쉽게 관리하고 배포할 수 있다.
- Flink에서 제공하는 다양한 Metric Reporter 중 Prometheus(모니터링 시스템 + 시계열 데이터베이스)와 Grafana(대쉬보드 시각화 도구)사용
마무리
- 실시간 처리를 위한 기술 스택을 비교할 수 있었다.
- Flink on kubernetes를 활용한 실시간 처리 구축 과정에서 안정성에 장점이 있는 Application cluster와 자원 효율성에 장점이 있는 Session cluster를 비교할 수 있었다.
- 실시간 처리 운영 시 모니터링해야 하는 지표들을 알 수 있었다.