brunch

You can make anything
by writing

C.S.Lewis

by 정주홍 Jun 19. 2018

빅 데이터 프레임워크, 솔루션들의 목적과 역할

여러 프레임워크와 솔루션의 목적과 역할을 알아봅니다

데이터 엔지니어링을 시작하면서 굉장히 많은 프레임워크와 솔루션들을 접했다. Hadoop과 같이 사실상 표준으로 쓰이는 것들도 있고, 경우에 따라 다른 솔루션을 쓰는 것도 있다. 이미 어느 정도 경험이 있었던 백엔드 서버 개발을 할 때는 이런 저런 웹 애플리케이션 서버 프레임워크와 함께 쓰이는 라이브러리들을 알아가는데 큰 문제가 없었지만, 데이터 웨어하우스 구축을 위해 프레임워크나 솔루션들을 알아보려니 이름만 들어봤을 뿐 실제로는 어떻게 작동하는지, 무엇을 위해 쓰는지 거의 알지 못해 어려움을 겪었다. 그 기억을 살려 데이터 엔지니어링을 시작하려는 사람들에게 도움이 될 만한 글을 써보려 한다.

출처: https://hortonworks.com/blog/modern-data-architecture-applied-hadoop/


왜 관계형 데이터베이스를 벗어나는가

먼저 관계형 데이터베이스에 대해 생각해보자. 익숙한 SQL로 여러가지 집계 질의를 할 수 있고, Partial Update도 가능하고, 심지어 트랜잭션도 잘 지원하기 때문에 매우 매력적이다. 문제는 비용이다. 대용량 데이터에 대해 어려운 질의를 할 경우 처리 속도가 충분히 빠르지 않기 때문에 매우 좋은 성능의 데이터베이스 서버를 쓰지 않으면 질의 응답 속도가 현실적으로 이용할 수 없는 수준으로 떨어진다. 말도 안 되는 수준의 스토리지와 CPU, RAM을 장착한 데이터베이스 서버를 쓰면 만족스러운 속도가 나오겠지만 이것이 비용 효율적이냐는 질문을 하면 그렇다고 답하기 어렵다. 게다가 서비스에서 사용중인 DB에 어려운 질의를 실행시키면 동시성을 떨어뜨리게 된다. 무거운 질의가 수행될 경우 스토리지에 엄청난 IO가 발생하면서 서비스 제공을 위한 다른 질의들에도 영향을 끼치기 때문이다.

빅 데이터 분석을 위한 여러가지 프레임워크와 솔루션들을 이용해야만 하는 이유를 납득하려면 위 문제를 먼저 인식해야만 한다. 빅 데이터 분석을 관계형 데이터베이스에서 못하는 것이 아니다. 관계형 데이터베이스를 이용하는 것이 비용 효율적이지 않은 것이다.



핵심은 수평적 확장(Scale Out)

관계형 데이터베이스가 비용 효율적이지 않은 이유는 결국 수직적 확장을 할 수 밖에 없는 구조이기 때문이다. 샤딩을 할 순 있지만 한 질의의 응답 속도를 빠르게 하기 위해서는 결국 수직적 확장을 할 수 밖에 없다. 대체로 수직적 확장은 점점 더 많은 비용을 요구(지수적으로 요구)하는 반면 수평적 확장은 그렇지 않다.

출처: https://www.starwindsoftware.com/scale-out-page

정말 좋은 마더보드를 이용해서 많은 CPU와 RAM, 스토리지를 꽂아도 결국 한계는 온다. 수직적 확장이 필요하다면 선형적으로 확장 가능(Linearly Scalable)하다고 보기 어렵다. 처리해야할 데이터가 늘어남에 따라 선형적으로 인프라를 확장할 수 없다는 것은 큰 비용을 초래할 수 밖에 없는 것이다. 즉, 비용 효율을 위해서는 수평적 확장이 가능하도록 하는 것이 선택이 아니라 필수이다.



수평적 확장이 가능한 Hadoop 클러스터

Hadoop은 빅 데이터 분석을 위해 사실상 표준으로 쓰이는 프레임워크이다. Hadoop의 각 컴포넌트에 대한 자세한 설명은 잘 설명된 글들이 이미 너무 많기 때문에 이 글에서는 생략한다. 핵심은 Name Node를 제외하고 수평적 확장이 가능하다는 것이다. 빅 데이터를 저장하기 위해서는 빅 데이터를 저장할 수 있을만큼의 스토리지를 요구한다. Hadoop HDFS에서는 스토리지가 부족할 경우 Data Node를 추가함으로써 수평적으로 스토리지를 늘릴 수 있다. 빅 데이터를 처리하기 위해서 더 많은 컴퓨팅 자원이 필요할 수 있다. Hadoop YARN에서는 MapReduce Job을 더 빠르게 수행하기 위해 CPU, RAM과 같은 컴퓨팅 자원이 더 필요할 경우 Node Manager를 추가함으로써 수평적으로 컴퓨팅 자원을 늘릴 수 있다.

출처: https://hortonworks.com/blog/deploying-long-running-services-on-apache-hadoop-yarn-cluster/

비록 Name Node나 Resource Manager와 같은 컴포넌트는 수직적 확장을 할 수 밖에 없긴 하지만, 말도 안 되는 규모가 아니라면 Name Node나 Resource Manager를 구동하는 서버가 매우 높은 수준의 성능을 요구하지는 않는다. 그렇기 때문에 Hadoop을 이용하면 비교적 낮은 비용으로 수평적 확장을 할 수 있는 클러스터가 된다. Hadoop과 같은 저변이 준비됨으로써 다음으로 이야기할 프레임워크와 도구들이 수평적 확장이 가능하게 된다.



분산 컴퓨팅 프레임워크 Spark

Hadoop과 마찬가지로 사실상 표준으로 쓰이는 프레임워크인 Spark에 대해 이야기해보자. Spark는 컴퓨팅에 대해 수평적 확장을 적용할 수 있는 분산 컴퓨팅 프레임워크이다. Spark는 단일 머신에서 실행(Standalone)할 수도 있지만 Hadoop YARN, Mesos, Kubernetes와 같은 여러가지 클러스터 시스템과 결합되어 자원을 동적으로 할당할 수 있다. 주로 master node를 먼저 실행시킨 뒤, Job을 실행하기 위해 추가적으로 필요한 node들을 클러스터 Manager를 통해 추가로 띄우는 식이지만, 처음부터 일정 양의 node를 선점하고 있도록 할 수도 있다.

출처: https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-architecture.html

Spark가 왜 좋은지 설명하는 것은 오히려 쓸데 없는 짓이라고 생각될 정도이다. Spark로 할 수 있는 일은 Hadoop Mapreduce를 이용해서 다 할 수 있다. 하지만 Spark를 사용하는 것만큼 효율적인 Mapreduce 애플리케이션을 개발하는 것은 어려울 것이다. Spark를 이용하면 Hadoop HDFS 또는 연동된 파일 시스템에 저장된 다양한 포맷의 데이터에 대해 분산 컴퓨팅을 수행할 수 있다. Hahoop Mapreduce의 단순 예제인 Word Count를 따라해보기만 해도 알겠지만 Hadoop Mapreduce 애플리케이션을 개발하여 분산 컴퓨팅을 하는 것은 상당히 괴로운 일이다. Spark를 쓰면 분산 컴퓨팅이 필요한 애플리케이션을 (비교적)매우 쉽게 개발할 수 있다. 심지어 일반적으로 이용하던 표준 SQL을 자동으로 분산 컴퓨팅하여 실행해주기까지 한다! 빠를 뿐만 아니라 장애 허용 시스템(Fault Tolerant System)이기도 하다. 즉, Task에 실패하는 경우 다시 실행해준다.

Spark가 사실상 표준이 된 것에는 그럴만한 이유가 있었던 것이다.



데이터 웨어하우스 Hive

Hive는 방대한 양의 데이터를 SQL(엄밀히 말하면 HiveQL)로 다룰 수 있게 도와주는 시스템이다. 분산 파일 시스템에 저장된 데이터를 SQL로 다룰 수 있게 해준다고 하지만, Hadoop과 연동되는 파일 시스템이라면 거의 다 이용 가능하다고 보면 된다. Hive에 내부 테이블 혹은 외부 테이블로 선언을 해두면 다양한 포맷의 데이터를 SQL로 다룰 수 있게 된다. Hive가 등장하기 전에는 Hadoop Mapreduce 코딩을 하거나 Pig와 같은 나름대로의 고수준 언어를 이용하여 데이터들을 다뤄야 했지만, Hive가 등장한 뒤부터는 SQL과 거의 흡사한 HiveQL로 빅 데이터를 다룰 수 있게 됐다. SQL을 사용할 수 있다는 점에서 접근성의 차이가 어마어마하게 많이 났기 때문에 성능상으로 Pig에 이점이 있는 경우가 있음에도 불구하고 많은 곳에서 Hive를 사용하고 있다.

출처: https://www.edureka.co/blog/hive-tutorial/

Hive에 질의 요청이 들어오면 질의를 분석하여 여러 단계의 MapReduce Task로 분리한다. 각 Task간의 의존 관계를 분석하여 어떤 Task를 먼저 실행해야 하는지, 어떤 Task들은 함께 실행할 수 있을지 파악한다. 이런 Task 관계도를 방향성 비순환 그래프(Directed Acyclic Graph)를 구성한다. 이러한 DAG를 이용하여 Hadoop YARN 위에서 데이터 처리를 쉽게 할 수 있고자 시작된 프로젝트가 바로 Tez이다. Hive CLI를 실행한 뒤 질의를 실행하면 Tez가 YARN 애플리케이션으로 실행된다. Tez는 Hive 뿐만 아니라 Pig에서도 쓰인다. Hadoop YARN 상에서 실행되는 애플리케이션이기 때문에 당연히 수평적으로 확장 가능하다. 쉽게 생각하면 데이터 웨어하우스 상의 데이터 카탈로그는 Hive에서 관리하고, 실제 데이터 처리는 Tez라는 레이어에서 처리된다고 볼 수 있다. 마치 TCP 통신이 여러 레이어로 나뉘어 처리되는 것과 같이 말이다.

필자는 처음 데이터 엔지니어링을 시작하면서 Spark와 Hive가 어떻게 다른 것인지 많이 헷갈렸다. Hive에서 SQL로 할 수 있는 것이면 왜 굳이 Spark를 쓰는 것일까? Hive에서는 SQL을 이용하여 할 수 있는 데이터 처리는 할 수 있지만 그 이상의 일은 어렵다. 예를 들면 Hive에서의 질의 결과를 MySQL과 같은 관계형 데이터베이스에 저장하기 위해서는 Sqoop과 같은 툴들의 도움을 받는 것이 일반적이다. 하지만 Spark를 사용할 경우 결과를 여러 관계형 데이터베이스에 직접 write 할 수 있다. 그렇다고 Spark를 Hive와 완전히 분리되어 사용하는 것도 아니다. Hive에 선언해둔 데이터 카탈로그는 Spark에서 HiveContext를 통해 이용할 수 있다. 예를 들면 Hive에 선언해둔 View를 Spark에서 이용함으로써 Spark 애플리케이션을 개발할 때 데이터 카탈로그와 관련된 코드를 작성하지 않을 수 있다. 



NoSQL 데이터베이스

앞서 관계형 데이터베이스는 수평적 확장이 어렵다는 단점이 있다고 이야기했다. 다음 링크에서도 이야기하고 있듯 CAP 이론에 따르면 일관성, 가용성(유효성), 파티션 허용차 3가지 모두를 만족할 수 없다고 한다. 관계형 데이터베이스에서는 일관성과 가용성을 보장하는 대신 많은 데이터 처리를 하기위한 파티션 허용차를 포기한 것이다.

출처: https://hub.packtpub.com/cassandra-architecture/

NoSQL데이터베이스는 보통 특정 Key에 해당하는 document를 찾아내기만 하면 되는 질의 패턴에 적합하다. 특정 Key를 이용하여 어떤 node에 접근한 뒤 추가적인 질의 처리를 수행하는 방식이라고 이해하면 좀 더 쉬울 것이다. 이렇게 함으로써 병목 현상을 일으키는 지점을 최소화할 수 있다. 또한, 여러 node에 데이터를 분산하여 저장하고, 질의를 처리하도록 하기 때문에 수평적 확장이 용이하다. NoSQL 데이터베이스는 관계형 데이터베이스처럼 전체 데이터에 대해 색인을 타고 쭉 질의 결과를 scan 할 수는 없지만, 많은 질의를 동시에 처리하기 용이하기 때문에 같은 시간 대비 질의 처리량이 더 높은 경우가 많다. HBase와 같은 데이터베이스에서는 데이터 지역성(Locality)에 의해 시간 대비 높은 질의 처리량이 보이기도 한다.

DynamoDB와 같은 솔루션을 이용하는게 나을지, Cassandra 같은 솔루션을 운용하는게 나을지 궁금할 수 있다. 사실 이건 답하기 어려운 질문인데, workload에 따라 답이 달라지기 때문이다. DynamoDB에서는 여러가지 제약 사항과 비용상 고려해야할 점들이 있는데, 만약 workload상 문제가 없다면 DynamoDB를 이용하는게 나을 가능성이 높다. 직접 시스템을 운용한다는 것은 상당한 운용 비용을 요구하기 때문이다. SaaS 솔루션을 이용하는 이유이기도 하다. 그러나 DynamoDB 특유의 비용 청구 방식인 Read Capacity Unit, Write Capacity Unit에 따른 비용과 스토리지 비용을 미리 추산해보지 않으면 비용 폭탄을 맞을 수 있다. workload를 잘 분석해서 의사 결정을 내려야 한다.



자원 코디네이터 Zookeeper

이제 데이터베이스가 아닌 다른 것들을 이야기해보자. 많은 솔루션, 특히 Hadoop ecosystem에서는 Zookeeper를 요구한다. Hadoop ecosystem에는 분산 시스템이 많은데, 분산 시스템에서는 동기화가 매우 중요한 문제 중 하나이다. 단일 머신 상에서 mutex나 semaphore로 동기화 문제를 해결하는 것을 잘 알 것이다. 분산 환경에서는 Zookeeper를 이용하여 mutex, semaphore 같은 역할을 수행한다. 

출처: https://zookeeper.apache.org/doc/r3.1.2/zookeeperOver.html

무엇보다 중요한 것은 신뢰성(Reliability)이다. 분산 환경에서는 매우 다양한 장애가 존재한다. Zookeeper는 여러 node에 중복으로 데이터를 저장하여 높은 신뢰성을 보인다. Zookeeper node를 한 대만 운용하는 경우는 잘 없다. 최소 3대를 운용하고, 한 node에 변경 사항은 다른 node들에 전파되어 반영된다. Zookeeper에 write를 하기 위해서는 클러스터 상의 과반수 이상의 node로부터 가능하다는 응답이 와야 한다. 그렇기 때문에, 질의에 대해 과반수 이상의 node로부터 같은 응답이 오면 그 응답이 올바른 응답이라고 판단할 수 있다.

Hadoop HDFS Namenode의 고가용성 설정을 위해 Zookeeper가 이용된다. 쉽게 생각하면 Namenode의 상태를 Zookeeper에 동기화시키면서 Active Namenode에 문제가 생겼을 때 follow-up 하고 있던 Standby Namenode가 Active Namenode로 승격될 수 있게 하는 것이다. Hadoop HDFS Namenode 뿐만 아니라 HBase, Kafka, NiFi, Druid와 같은 다양한 솔루션에서 동기화 문제를 해결하기 위해 Zookeeper를 이용한다.



높은 신뢰성과 성능의 스트림 Kafka

많은 양의 데이터를 안정적으로 보관하고 처리해야한다면 고민할 것도 없이 Kafka가 답이다. Spark와 비슷하게 대용량 스트림 처리에 있어서는 사실상 표준이라고 보면 된다. 쉽게 생각하면 Publish-subscribe 구조를 고성능으로 제공하는 솔루션이라고 생각하면 된다. Kafka만큼의 높은 throughput을 제공하는 솔루션은 거의 없다. 초당 MB, GB 단위로 데이터가 쏟아지는 시스템이 아니라면 Queue에 비해 Kafka와 같은 스트림이 어떤 장점이 있는지 이해하기 어려울 것이다. Queue를 써도 성능상의 문제가 없다면 그냥 Queue를 쓰면 되지만, 데이터가 점점 더 불어나면 Queue로는 확장성이 부족해지는 때가 온다.

출처: https://kafka.apache.org/intro

무엇보다 Kafka의 강점은 장애 허용 시스템이라는 점이다. Kafka도 Zookeeper와 마찬가지로 단일 node로 구성하지 않는다. Kafka에서는 각각의 node를 broker라고 하는데, 최소 3대 이상의 broker로 구성하고, publish 하는 메세지를 최소 2대 이상의 broker에 중복으로 저장하여 데이터 유실을 막는다. 중복 인자(Replication factor)를 2로 설정할 경우, 한 대의 broker가 장애로 인해 멈췄을 때도 문제 없이 데이터를 subscribe 할 수 있고, 중복 인자를 3으로 설정할 경우 두 대의 broker가 멈춰도 정상 작동 한다. 

어지간해서는 Kafka broker에 장애가 잘 나지 않기 떄문에 일단 데이터를 Kafka에 올리고나면 데이터 잔존(Data Retention)기간 동안은 걱정 없이 데이터가 보관된다. 갖가지 장애가 도사리고 있는 분산 환경에서 데이터 유실 걱정 없이 보관시켜둘 수 있는 시스템이기 때문에 애용된다.

실시간 스트리밍 처리를 위해 이용되기도 한다. 데이터가 들어오면 Kafka에 일단 적재하고, Spark streaming이나 Flink와 같은 스트리밍 처리 프레임워크를 이용하여 스트리밍 처리를 하는 것이 일반적이다. 



비싸지만 만능인 Elasticsearch

Elasticsearch는 상당히 널리 알려진 솔루션이다. 검색, 집계 등 거의 모든 것을 할 수 있는 매우 유용한 솔루션이다. Elasticsearch를 기본으로 사용하고, Logstash로 Elasticsearch에 데이터를 전송하고, Kibana로 시각화 및 관리를 하는 ELK stack이 널리 알려져 있으며, 로그 분석을 할 때 가장 먼저 떠올리는 솔루션이기도 하다. Elasticserach node를 추가하여 수평적 확장이 가능하기 때문에 확장성도 있다. 최근에는 머신 러닝과 관련된 기능을 소개하기까지 했다.

출처: https://logz.io/learn/complete-guide-elk-stack/

정말 좋은데 문제는 비용이다. Elasticsearch 클러스터를 유지하기 위해서는 상당히 많은 비용이 든다. 대용량 데이터를 모두 Elasticsearch에 저장해두기 위해서는 스토리지 뿐만 아니라 인덱스 유지를 위해 메모리가 많이 요구되기 때문에 좋은 성능의 node들을 많이 유지해야만 한다. 그러지 않기 위해서는 데이터 잔존 기간을 짧게 가져가는 수 밖에 없다. 또한, Elasticsearch 클러스터에 문제가 생겼을 때는 데이터 유실이 발생할 수 있는 것으로 알려져있다. 마지막으로 뛰어난 솔루션인만큼 사용자의 운용 능력이 부족하다면 Elasticsearch를 잘 활용하지 못할 수 있다. 여러 회사들이 Elasticsearch stack을 전담하는 팀을 운용할 정도이다.

그러나 어느 정도 비용을 투자하면 몇몇 목적에는 상당히 유용한 솔루션이기도 하다. Logstash를 쓰면 쉽게 거의 유실 없는 데이터 전송을 할 수 있고, Kibana와 같은 훌륭한 시각화 도구를 활용할 수 있다. 검색이라는 요구 사항을 제외하고 생각했을 때, 대용량 데이터 보관을 위해서가 아닌 비교적 적은 양의 데이터를 빠르게 다루기 위해서는 Elasticsearch가 매우 훌륭한 솔루션이라고 볼 수 있다. 모니터링을 위한 데이터는 보통 장기간의 데이터 보존 기간을 요구하지 않기 때문에 비교적 적은 양의 데이터를 다룬다는 요구 사항에도 알맞다. New Relic과 같은 도구를 통해 많은 서버를 모니터링해야한다면 마찬가지로 적지 않은 비용을 요구하는 것을 고려했을 때 꽤 비용 효율적인 솔루션이 될 수 있는 것이다.



빠른 집계를 해주는 Druid

빅 데이터 분석을 통해 알고 싶은 것은 보통 집계 결과인 경우가 많다. 말하자면 Group By 질의를 수행하는 것인데, 데이터에서 통찰을 얻기 위해서는 각각의 데이터 하나하나를 보기보다 다차원 집계 결과가 필요한 것이 보통이다. 문제는 이러한 집계 결과를 얻기 위해 매우 많은 계산이 요구된다는 것이다. Spark를 통해 꽤 빨리 집계 결과 질의를 수행할 수 있지만, 대용량 데이터에 대해 실시간으로 결과를 줄 수 있기 위해서는 아주 대용량의 메모리가 준비된 Spark 클러스터가 필요하다.

출처: https://hortonworks.com/open-source/druid/

Druid는 흔히 데이터 큐브라고 불리는 데이터를 미리 만들어(Indexing) 다차원에 대한 집계 결과나 Top N 질의를 실시간으로 응답해준다. Sub-second ad-hoc query라는 키워드를 내걸고 있는데, 실제로 거의 Sub-second에 근접해서 놀라울 정도이다. 질의를 더 빠르게 수행하게 하기 위해서는 Broker node, Task를 더 빠르게 끝내기 위해서는 Middle manager를 늘리면 되기 때문에 수평적 확장이 가능하다. 또한, 중앙 관리자 역할을 하는 Overlord, Coordinator node는 이중화가 가능하여 장애 허용 시스템이기도 하다. 게다가 클라우드 환경을 적극 고려한 시스템 설계로 데이터를 S3와 같은 클라우드 스토리지나 Auto scaling을 이용한 확장이 가능하게 해두었다.

필자는 아는 분이 추천해주셔서 Druid를 알게 됐는데,매우 만족하며 쓰고 있다. 한국에서도 SKT의 Metatron 팀이 주도하여 Druid Meet-up이 열리고 있다. 필자도 6회, 7회 meet-up에 참석했었는데, 훌륭한 솔루션인만큼 많은 분들이 Druid에 관심을 갖길 바래본다. 



데이터 흐름(Data Flow)을 다루는 NiFi

위에서 예시를 든 솔루션들은 국내에서도 많은 곳에서 다루기 때문에 익숙하겠지만, NiFi는 아마 처음 들어보는 사람들도 많을 것이다. 먼저, 잘 정리된 글이 있으므로 소개하고 싶다. NiFi에 대한 자세한 설명은 링크된 글을 읽는 것을 추천하며, 이 글에서는 간략하게 소개하고자 한다.

출처: https://nifi.apache.org/

점점 더 데이터를 처리하는 과정이 복잡해지고, 실시간으로 처리하고자 하는 요구 사항이 많아지고 있다. 그렇다고 매번 소소한 처리를 위한 코딩을 하는 것도 상당히 시간을 많이 잡아먹는 일이다. 예를 들면, Kafka에 들어온 메세지에 특정 필드를 추가해주는 작업이 필요하다고 했을 때, 실제로 하는 일은 매우 간단하지만 작업에는 많은 시간이 요구된다. 애플리케이션을 개발하기 위해 코딩하는데 드는 시간과, 그렇게 만들어진 애플리케이션을 모니터링까지 해야하기 때문에 관리 차원에서의 고민까지 필요하기 때문이다. 

NiFi에서는 여러가지 작업에 대한 프로세서(Processor)가 준비되어 있어 그러한 작업을 쉽고 빠르게 끝낼 수 있다. 또한, 프로세서와 프로세서 간의 데이터 흐름을 쉽게 모니터링할 수 있다. 심지어 수평적 확장까지 가능하다. NiFi가 하는 일이 많아져서 서버가 부족해지면 node를 하나 추가해주기만 하면 된다. 개인적으로는 Spark를 접한 때와 비슷한 수준으로 필자충격을 준 솔루션이다. 아직 해외에서도 Hadoop이나 Spark와 같이 널리 알려진 솔루션은 아니지만 굉장히 유용한 솔루션이기 때문에 곧 널리 퍼질 것이라 생각한다.



클러스터 관리를 위한 Ambari

지금까지 다룬 솔루션들을 제외하고도 수 많은 솔루션들이 존재한다. 그런 솔루션들을 여러 머신에 설치해서 관리해야만 하는데, 직접 ssh로 접속해서 이런 저런 설정을 하며 관리하는 것은 쉬운 일이 아니다. 클러스터가 매우 커지면 어떤 클러스터에 어떤 솔루션을 실행하고 있는지 기억하는 것 조차 쉽지 않을 것이다. Ambari는 클러스터상에 설치된 여러가지 솔루션들의 설정값을 관리하고, 각 요소들을 중지, 시작하는 것을 웹 인터페이스를 통해 쉽게 할 수 있도록 도와준다.

출처: https://hortonworks.com/blog/apache-ambari-1-6-1-released/

예를 들어 Hadoop HDFS 설정을 일부 수정했다고 생각해보자. 바뀐 설정 값이 반영되도록 하기 위해서는 Namenode와 Datanode들이 restart 되어야 한다. Namenode는 몇 대 안 되니 제외하더라도 Datanode가 100대 가량 된다고 생각해보자. parallel-ssh와 같은 툴을 이용해서 한 번에 restart 할 수도 있겠지만, 고가용성을 위해서는 일명 rolling restart라 불리는, 몇 node만을 restart 시켜나가는 방식을 이용한다. 이걸 직접 하려면 상상만 해도 피곤하다. Ambari를 이용하면 이러한 rolling restart를 웹에서 시작시킬 수 있다.

필자의 경우 Ambari 상의 인터페이스를 생각 없이 따라가다가 Hadoop HDFS나 Kafka 클러스터를 의도치 않게 통째로 stop 시키는 바람에 좋지 않은 기억을 갖고 있긴 하다. 가끔은 여러모로 아쉬운 점이 많이 느껴지는 도구지만, 적은 인원이 방대한 클러스터를 관리하기 위해서는 매우 유용한 도구임에 틀림없다. 



작업 흐름 관리를 위한 Airflow

데이터 파이프라인이 복잡해지면 각 데이터 처리 프로세스 또한 잘 구조화하여 관리할 필요성이 생긴다. 대충 1시간 내에는 끝나는 batch job이 있고, 그 다음에 실행되야 하는 job이 있다면 그냥 1시간 뒤에 실행 시킬 수도 있겠지만, 이런 방식은 딱 봐도 결함이 생기기 쉽다. 가끔 예상치 못한 장애로 인해 job은 얼마든지 지연될 수 있기 때문이다. 그렇기 때문에 job 간의 의존성에 따라 잘 실행시켜주는 것은 꽤 중요한 일이다.

출처: https://airflow.apache.org/ui.html

Airflow는 최근 떠오르는 workflow 도구이다. 몇 시간에 걸쳐 실행되는 것이 요구되는 workflow는 사람이 직접 관리하기에 상당히 피곤한 일이기 때문에 workflow 도구를 통해 자동화하는 것이 일반적이다. Oozie와 같은 workflow 도구가 있었지만 사용하기 쉽지 않았고, 그 불편함을 해소하고자 Luigi와 같은 도구가 떠올랐지만 이제는 Airflow로 대세가 기울고 있다. Luigi, Airflow, Pinball의 기능적 차이는 다음 링크에 잘 정리되어 있다. Airflow를 이용하면 workflow를 쉽게 스케쥴링할 수 있고, 각 Task의 의존성에 따라, 말하자면 DAG로 선언된 task들을 잘 실행해준다. DAG와 task 실행 로그를 보기 쉬운 Web dashboard가 제공되고, celery를 이용하여 task가 실행되기 때문에 확장성 있다. 아직 Apache Incubate 단계의 프로젝트임에도 불구하고 많은 곳에서 이용되는 이유이다.



쉽게 대시보드를 만들어 주는 Zeppelin

갖가지 데이터 처리와 정제를 거쳐도 사용자에게 그 데이터를 제공하지 않으면 무용지물이다. 복잡한 데이터일수록 쉽게 볼 수 있게 하기 위한 고민이 필요하다. 데이터 시각화라는 분야가 따로 존재할 정도이다. 여러 가지 데이터를 정리하여 보고서나 대시보드 같은 것을 제공할 필요성이 있는데, Zeppelin을 쓰면 그 작업을 쉽게 할 수 있다.

출처: https://zeppelin.apache.org/

쉽게 생각하면 Zeppelin은 Jupyter와 비슷하다. 다만, 코드 실행 결과보다 여러 가지 시스템에 대한 질의 결과를 보여주는데 좀 더 초점이 맞춰져 있다. 엄밀히 말하면 Zeppelin에서는 여러가지 시스템에 대한 실행 결과를 얻기 위핸 중간 객체로 Interpreter라는 것이 존재하는데, JDBC interpreter를 통한 JDBC 질의 결과, Spark interpreter를 통한 Spark 코드 실행 및 질의 결과를 볼 수 있다. 또한, 질의 결과를 그래프 같은 것으로 시각화하여 보여주기 용이하다. 매일매일 대시보드가 갱신되도록 cron 설정을 해둘 수도 있다.

개인적으로는 cron 기능을 이용하여 스케쥴링을 하다가, 또 이런 저런 작업을 하다가 쓴 경험을 많이 해서 아픈 기억이 많은 패키지이지만 쉽고 빠르게 대시보드를 만들 수 있다는 것은 분명 장점이라고 볼 수 있다.



마치며

지금까지 데이터 엔지니어링을 시작하며 학습한 것에 대한 정리를 해보았다. 글에서 언급하지 않았지만 Hive와 비슷하면서도 다른 Impala, Presto 같은 솔루션도 있고, 갖가지 Hadoop ecosystem을 통합하여 보여주는 Hue와 같은 솔루션도 있다. 너무나도 많은 솔루션이 있기 때문에 오히려 뭘 선택해야할 지 판단하기 어려울 정도이다. 각 요소는 대응되기도 하는 반면, Spark에서의 계산 결과를 Elasticsearch에 저장하는 등 함께 이용할 수도 있다. 결국, 그때 그때 필요한 작업에 어떤 프레임워크, 도구, 솔루션이 적합한지 판단하는 능력을 기르는 것이 중요하다.

필자 또한 이제 막 데이터를 다뤄보기 시작한 초심자에 불과하지만, 과거 처음 학습을 시작할 때 갖가지 솔루션을 왜 쓰고, 어떤 때 써야 하는지에 대한 잘 정리된 자료가 없어 고통받았던 기억이 있다. 이 글이 조금이나마 나와 같은 초심자들에게 도움이 되기를 바래본다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari