본문 바로가기

Spark

[부록] Performance Tuning of an Apache Kafka/Spark Streaming System

원문글

 - https://www.javacodegeeks.com/2017/01/performance-tuning-apache-kafkaspark-streaming-system.html



이 글은 Kafka 같은 MapR 과 같은 시스템으로 확장해 나갈때 도움이 되는 글입니다.

( 말을 아주 매력적으로 잘 쓰심.. ㅋㅋ )


Goal of the system

이제 이 글은 telecom company 를 예시로 들고 있는데, 고객의 데이터를 받아서 바로 고객이 가지고 있는 불만사항의 원인과 해결책을 대응해줘야 하는 시스템을 구축하는데 있어 빠르게 로그 수집 및 분석이 이루어 져여 하는 상황이 있었다. 보통의 Batch job 보다 이런 시스템을 이용해서 Realtime Working 을 가능하게 한다는건 고객 서비스 입장에서 매우 중요한 것이었다. ( 생각해 보라. 뽑은 데이터가 6시간 전꺼라면 고객응대를 어떻게 하겠는가? ) 그래서 최근에는 ETL Batch Job 이 아닌 streaming distributed architecture가 각광을 받는 것이다.


그래서 이와 같이  distributed cluster 에서 데이터를 뽑고 cleaning 하고, argumetation 하고, 다른 로그와 join 을 거는 등의 작업을 통해 우리가 원하는 데이터 테이블로 뽑아낸다.



 

The application architecture


Log 를 Kafka Producer 로 빨아서  Spark streaming 으로 Consume 하고 각 데이터를  unnecessary data 들을 filter 하고, 정리한다음에 Ignite 에 넣어서 Secondary Spark Application 이 join 을 걸어 사용할 데이터로 만들어 HBase 에 넣는다. ( 내가 Ignite 용도는 잘 몰라서 ... Spark Job 중간에 왜 Ignite 를 넣어야 하는 구조인지는 공부좀 해야 겠다! ) 여튼 이런식이면 유실없는 스트리밍 처리가 가능한 Architecture 가 된다.


여기서 사용한 Kafka 의 노드 구성이나 물리 장비 Spec 은 해당글 상기 링크에서 확인하도록 하자.



Performance tuning

First target: Improve Spark Streaming performance

  1. Fix RPC timeout exceptions
    • reference : SPARK-14140 in JIRA
    • 증가시키기~!!  spark.executor.heartbeatInterval from 10s => 20s
  2. Increase driver and executor memory
    • spark-submit option 변경 : 메모리 증가시키기 20g per executor -> 40g per executor
  3. Increase parallelism: increase number of partitions in Kafka
    • produce 하는 곳에서 spent processing 이 쏠린 topic 을 여러개의 topic 으로 나누고 각 topic 에 partition 을 분할하여 paralleism 처리가 가능하도록 한다. 이렇게 함으로써 produce 하는 곳에서는 각 로그를 여러개로 분할된 topic 으로 produce 하는 로직만 수정을 하고 consume 하는 곳에서는 코드를 수정할 필요가 없게 된다. 그리고 병행 처리가 가능하니 성능이 더 빨라질 것이다. 
  4. Right-size the executors
    • EXECUTOR_CORES = x
    • NUM_EXECUTORS = x
    • Cluster Node 수와 Core 수 그리고 기타 다른 Application 의 실행을 감안해서 excecutor 수를 잘 잡아야 한다.
  5. Increase the batch window from 30s to 1m
    • 이건 서비스마다 다를것 같은데 위 링크에서는 micro batch time 을 30초로 잡은 상태였음
    • 이는 데이터를 처리하는 시간을 30초에서 1분으로 줌으로써 좀더 smooth 한 데이터 처리가 될 수 있다. ( 단 30초의 latency 가 늘어나는 trade-off 가 있겠지.. ㅠ ㅠ )
  6. Drop requirement to save to Hive, only use Ignite
    • Hive 는 사실 streaming 데이터에서는 필요하지 않다. 바로 저장하고 바로 빼서 쓸수 있도록 되는 것이 중요하다. 즉, 분석에 필요한 또는 application context 내에서 필요한 데이터는 HBase 로만 저장해서 빠르게 저장 및 분석이 가능하도록 하는 것이 좋다.


Second target: Improve System Stability

  1. Make the Spark Streaming application stable
    • 너무 당연한거라 생략... ㅋㅋ 적당한 크기의 데이터로 적당히 써라라는 말임
  2.  Remove Mesos and use Spark Standalone
    • 이건... 검증좀 해봐야 할거 같은데... Spark Standalone 보다는 yarn 과 같은 Resource management platform 을 깔아 쓰는게 맞지 않나..? 하는 생각이 든다.
  3. Change the Ignite memory model
    • 힙에 48GB 가 캐시된 ONHEAP_TIERED memory model 설정에서 12GB 의 overflow 데이터가 off-heap memory 로 떨어졌다. 그래서 memory model 을 OFFHEAP_TIERED model로 변경!
    • 이는 big GC 를 발생시키지 않아, 비록 직렬화 cost 로 인해 조금 느리지만 더 좋은 성능을 낼것이라 기대!
    • 변경하니 배치 실행은 약 30초 -> 25초로, 5~10초 걸리는 연속적 배치의 경우 1~3초로 성능 향상이 있었습니다.
  4. Update the Ignite JVM settings
  5. Improve the Spark code
    • ㅋㅋㅋㅋㅋ 스파크 코드 잘짜기!! 고럼고럼 매우 중요하지!!
  6. Reassign ZooKeeper to nodes 10-12
    • ㅋㅋㅋ 하나의 node 에 application 이 쏠리게 하지 말자는 거다. 기존의 그림이 어떤지 한번 보면 이해가 될것 같다 ( 아래 참조! )



Conclusion

위처럼 튜닝하는데 1주일정도의 시간이 걸렸고... 응(?) 대단한데... ㅋㅋ 몇명이서 한건가 갑자기 궁금... ㅋㅋ spark-UI 랑 spark logs 를 썼고, .. 이걸 잘써라 여튼 그런 내용이네



What I learned

  • AWS 에서 프로토 타이핑 무조건 해라! tesing 이 없는 상태의 반영은 Big mistake 를 유발한다.
  • OSS componets 는 다 해결해줄것처럼 광고하지만 실제로는 그렇지 않다 ㅋㅋㅋㅋㅋㅋㅋ
  • 좋은 아키텍처는 시스템 전체를 매우 심플하게 만들어준다
  • Kafka랑 Spark 는 전체 시스템에 대한 이해가 없이는 제대로 다루기 힘들다
  • MapR 집중된 Data Platform 은 개발 시간, 복잡함, 비용을 매우 단축시켜 준다! 


Migrating a streaming application from a prototype on AWS to an on-premise cluster requires schedule time for testing

Not testing the AWS prototype with realistic data was a big mistake

Including many “bleeding-edge” OSS components (Apache Ignite and Mesos) with expectations of very high reliability is unrealistic

A better architecture design could have simplified the system tremendously

Tuning a Kafka/Spark Streaming application requires a holistic understanding of the entire system. It’s not simply about changing the parameter values of Spark; it’s a combination of the data flow characteristics, the application goals and value to the customer, the hardware and services, the application code, and then playing with Spark parameters.

MapR Converged Data Platform would have cut the development time, complexity, and cost for this project.


The need for a converged big-data platform is now

나온 플랫폼을 잘 선정해서 잘 써라! 이미 당신들이 필요해 하는 아키텍처는 많은 것들이 이 안에 녹아들어가 있으니!! ㅎㅎ