Time Series OLAP - Druid Trouble Shooting(6)

Druid - 오른손이 하는 일을 왼손이 모르게 하라

길고 길었던 Druid 시리즈 연재의 마무의리...이렇게 오래 걸릴줄은..... 그사이 Druid는 2018년 2월에 Apache Incubator Project가 되었다.

실시간 Index Task

1. tranquility를 사용해야 하냐?  supervisor(kafka-index-service)를 사용해야 하나?

tranquility의 경우 실시간 데이터에 대한 push 방식, supervisor의 경우 input source로 부터 데이터를 가져오는 pull 방식이다. tranquility의 경우 기존 Steaming Framework에 tranquility library를 추가하여 구현할 수 있다. 즉, Spark/Flink/Storm등의 코드에서 실시간 처리 후 결과 셋을 druid로 sink 할 수 있다. 단, 이 경우 windowPeriod 내에서의 데이터만 처리하기 때문에 late message의 경우는 drop된다.  이미 데이터가 정제된 형태로 kafka에 들어있는 경우라면  ingestion spec을 통해 수집하는 supervisor방식의 수집을 이용하자.

supervisor에서 task개수는 replicas와 taskCount에 의해서 결정되며 workerCapacity = 2*replias * taskCount 이다. 만약 taskCount > {numKafkaPartitions} 라면 {numKafkaPartition} tasks가 생기데 된다. taskDuration이 지나면 새로운 task 수행하게 되며 총 task개수는 replicas * taskCount 이다. supervisor persistence는 metadata database에서 관리하게 된다. 즉, overlord가 재수행 되더라도 직전까지 처리한 index정보는 druid meta database로부터 읽게 된다.

2. real-time index task가 안떠요~

supervisor에 index json은 submit은 되지만 indexing task가 동작하지 않는 경우, kafka broker 접속이 overlord, middle manager에서 제대로 되는지 확인해 보아야 한다.  supervisor는 meta db에 offset을 저장하게 되어있다. metadb에 접속하여 druid_dataSource테이블을 조회해 보자. 다음과 같이 등록된 offset정보가 없으면 kafka로부터 데이터를 못 읽어온 것이다.

1
| datasource_name     | 2018-06-05T00:50:49.017Z | {"type":"kafka","partitions":{"topic":"topic_name","partitionOffsetMap":{"0":11076358,"1":15803623,"2":14405618,"3":10999443,"4":15688862,"5":14323317,"6":11039514,"7":16214317,"8":14754624,"9":11340887}}} | 2EDD772548A34F83B7ACFB10FF67DB211A0C7174 |

3.  kafka offset 처음부터 읽고 싶어요

supervisor의 경우 offset을 reset하는 명령어가 있다. 혹은 ingestion spec에 useEarliestOffset을 줄 수도 있다.

curl -X POST -H 'Content-Type: application/json' http://{overload-host}:8090/druid/indexer/v1/supervisor/{datasource_name}/reset

Performance Tuning

1. batch ingestion 에서 hadoop을 ingestion하는 경우 mapreduce에 대한 옵션을 추가해 주어야 한다.

"mapreduce.map.java.opts" : "-server -Xmx4096m -Duser.timezone=UTC -Dfile.encoding=UTF-8 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps", "mapreduce.reduce.java.opts" : "-server -Xmx4096m -Duser.timezone=UTC -Dfile.encoding=UTF-8 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"

2. library conflict 문제

druid extension을 로딩하다보면(필자의 경우 parquet extension추가시 발생) 참조하는 library중에 druid에서 사용하는 library가 conflict나는 경우가 있다. 이 경우에는 jobProperties 에 다음과 같이 설정한다.

"mapreduce.job.user.classpath.first":"true",

3. Component node memory할당

http://druid.io/docs/latest/operations/performance-faq.html 를 참조하길 바란다.

druid.processing.buffer.sizeBytes * (druid.processing.numMergeBuffers + druid.processing.numThreads + 1

위의 공식을 참고한다.

Druid Q&A

아래 내용은 2016년 "데이터야 놀자"에서 아래 주제로 발표 했을때  나왔던 질문 리스트이다

Link: https://www.slideshare.net/jerryjung7/data-analytics-with-druid

Q1. dimension이나 aggregator개수에 따라 성능 차이가 심하지 않느냐?

A1)  dimension의 cardinality가 중요하다. aggregator의 개수에 따라 저장되는 용량이 달라질 수 있다. 질문하신 분은 cardinality가 높은 userId를 예로 들었는데, 그런 경우는 summary할때 count만 세는 방법이 낫다.

Q2. L2 cache로 memcached만 지원하냐? In-memory인데 왜 L2 cache를 또 썼냐? redis는 왜 안썼냐

A2) memcached는 특정 쿼리에 대해 multi-broker에 대한 빠른 응답을 위해 썼다. (topN, search query) 현재 redis는 지원하지 않는 것으로 알고있다. 찾아보니 관련 이슈는 있음(https://github.com/druid-io/druid/issues/1927­)

Q3. Data Lake를 위해서 elastic search는 고려해보지 않았느냐? 왜 Druid냐?

A3) 다루고자 하는 데이터 속성이 timestamp기반이였고 무엇보다 numeric 데이터에 대한 aggregation이 필요했다. 머신러닝에 input데이터 속성이기에 aggregator에 대한 빠른 응답도 필요했다.

Q4. 수집시 중간에 스키마가 바뀌는 경우 이전 세그먼트와 머지할때 conflict가 나지 않냐?

A4)  schemaless구조이고 스키마가 바뀌어도 최종 스냅샷을 갖고 있는 구조이다. 추가로 설정하지 않는 한 기존 저장된 segment와 별도의 merge과정은 거치지 않는다.

Q5. openTSDB는 고려해 보지 않았느냐?

A5)  Hbase에 대한 경험이 없고 관리가 용이하지 않다고 생각한다. sparse한 데이터를 다루기 위해서 고려해 볼수도 있겠지만 druid로 numeric데이터에 대한 빠른 응답은 만족스럽다.

Q6. 실시간 수집시 서로 다른 timestamp에 대한 처리는 어떻게 해야 하는가?

A6) tranquility를 통해 pre-processing이 필요하다. 다른 timezone에 대해 시간을 동일하게 convert 하는 작업이 필요하다.

Q7.  druid를 OLAP/BI로 쓰는가?

A7) OLAP/BI용도로 사용하기도 하고 분석용 데이터를 빠르게 질의하기 위해서도 이용된다.

Q8. 별도 UI가 있는가?

A8) 오픈된것은 pivot, superset등이 있다.

Q9. elastic search의 경우 jvm에러가 많은데 druid도 그런가?

A9) 내부에서 off-heap을 사용하기 때문에 큰 문제는 없다. 그러나 groupBy Query같은 경우에는 broker에서 결과를 merge하기 때문에 broker의 jvm 메모리를 충분히 할당해 주어야 한다.

마치며

이 글의 연재 순서는 다음과 같습니다.

THE END


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.