카프카를 사용하는 주요 목적 중 하나는 데이터 파이프라인을 구축하는 것이다.
데이터파이프라인의 예는 몽고의 데이터를 카프카로 전송하고, 카프카의 내용을 엘라스틱서치에 넣는 일련의 과정이라고 할 수 있다.
실질적으로는 데이터 파이프라인의 읽는 쪽과 쓰는 쪽을 분리함으로써 버퍼의 역할을 수행하는 것을 의미한다. (신뢰성, 보안성, 효율성을 카프카가 제공하기에)
다음은 데이터 파이프라인 구축시 고려해야하는 상황을 이야기한다. 이는 카프카의 특징을 의미하기도 한다.
데이터가 실시간으로 필요한 곳, 배치로 돌아가는 곳 등 다양한 형태의 데이터 파이프라인이 있을 수 있다.
카프카는 각기 다른 적시성 요구 조건을 지원한다.
이러한 맥락에서 카프카는 쓰는 쪽과 읽는 쪽 사이의 시간적 민감도에 대한 요구 조건을 분리시키는 거대한 버퍼라고 보아도 좋다. 백프레셔 적용 역시 단순하게 해준다.
카프카에서는 다양한 형태의 신뢰성을 제공한다. '무조건 한번'은 제공하거나, 데이터 유실이 허용할 수도 있는 다양한 형태의 데이터파이프라인을 구축할 수 있다.
이전 장에서 배웠듯 모든 이벤트가, 유실도, 중복도 없이 목적지에 도착하게 할 수도 있다. -> 트랜잭션 모델이나 고유 키를 지원하는 외부 데이터저장소와의 결합을 통해 '정확히 한 번'을 보장할 수 있다. 이러한 기능을 카프카 커넥터
에서 제공한다.
처리율이 갑자기 증가해야 하는 경우에도 적응할 수 있어야 한다.
카프카는 쓰는 쪽과 읽는 쪽 사이에서 버퍼역할을 수행한다. 따라서 카프카는 독립적으로 프로듀서나 컨슈머를 추가함으로써 독립적으로 확장이 가능한 형태이다.
특히 카프카 커넥트 API
는 작업을 병렬화하는데 초점을 맞추기 때문에 시스템 요구 조건에 따라 하나의 노드에서든 다양한 노드에서든 scale-out
될 수 있다.
이러한 데이터 파이프라인에서는 데이터 형식과 자료형을 고려해야한다. 에이브로타입, 제이슨타입, CSV타입 등 각각의 엔드포인트에서 요구하는 사항이 다르다.
카프카 자체와 카프카 커텍터 API는 데이터 형식에 완전히 독립적이다. 앞에서 이미 보았듯이, 프로듀서와 컨슈머는 필요한 데이터 형식을 지원할 수만 있다면 어떤 시리얼라이저를 사용할 수 있다.
즉 장착가능한 시리얼라이저를 활용한다고 보면 된다.
데이터 파이프라인은 다음과 두 가지 같은 방식이 있다.
두가지 상황 모두 서로 다른 엔드포인트를 연결하는 상황이기에 데이터 형식의 변환이 필요하다.
카프카 커넥터
는 원본 시스템의 데이터를 카프카로 옮길 때 혹은 카프카의 데이터를 대상 시스템으로 옮길 때 단위 레코드를 변환할 수 있게 해주는 단일 메시지 변환(Single Message Tranformation)기능을 탑재하고 있다.
하지만, 조인이나 집적과 같이 복잡한 연산은 카프카 스트림
을 활용해야 한다.
참고) 파이프라인을 구축할 때 성급하게 데이터를 정제하고 최적화 하지 마라. 덜 정제된 데이터가 필요한 경우가 많다.
등 다양한 보안 문제가 있을 수 있다. 카프카의 경우는 SASL
인증 등 다양한 인증을 제공하기도 하며 허가받지 않은 접근 내용을 추적할 수 있는 감사 로그도 지원한다.
카프카는 장애가 발생했을 때 이전 시점으로 돌아가서 에러를 복구할 수 있다. 또한 카프카에 저장된 이벤트가 유실되었을 경우 이벤트 재생도 가능하다.(장기간에 걸쳐 카프카 로그 설정이 가능하기에)
데이터 파이프라인의 중요점 중 하나는 데이터 원본과 대상을 분리할 수 있어야 한다는 것이다.
결합의 예제는 다음과 같다.
플룸을 활용해 로그를 HDFS에 밀어 넣거나, 인포매티카를 활용해 XML형태로 데이터를 오라클에 밀어 넣는 등 이런 형식은 엔드포인트에 데이터 파이프라인이 결합되어 잏기에 유지보수가 쉽지 않다.
데이터의 스키마 메타데이터를 보존하지 않고 스키마 진화 역시 지원하지 않는다면, 소스 쪽에서 형태와 싱크 쪽에서의 데이터를 모두 강하게 결합하게 된다.
따라서 스키마 레지스트리와 같이 두 데이터를 모두 해석하는 방식을 지정해야 한다. (스키마 진화를 지원해야 한다.)
파이프라인에서 너무 많은 처리를 하면 하단의 데이터 파이프라인의 필드가 필연적으로 적어지게 된다. 이 때 특정 소스가 필요하면 파이프라인을 또 수정해야하기에 과도한 데이터 처리는 지원하지 않는 것이 좋다. (어플리케이션이 알아서 처리하도록)
프로듀서/컨슈머는 카프카 클라이언트
를 활용해 컨슘하거나 프로듀스하는 것을 의미한다. 어플리케이션 코드를 직접 커스텀하여 사용할 수 있다는 장점이 있다.
카프카 커넥트는 카프카를 직접 코드나 API를 작성하지 않고, 변경할 수 없는 데이터 저장소에 연결시켜야할 때 쓴다. 카프카 커넥트
를 활용하여 외부 데이터 저장소의 데이터를 카프카로 가져올 수도, 저장된 데이터를 외부 저장소로 내보낼 수도 있다.
이러한 카프카 커넥터
를 활용하고자 한다면 각 저장소에 맞는 커넥터가 필요한데, 요즘은 많은 커넥터가 나와 있기에 실제로 해야할 일은 설정 파일을 작성하는 것 뿐이다.
커넥터가 없다면 커넥트 API
를 활용하여 어플리케이션을 직접 작성할 수 있지만, 해당 작업은 쉽지 않다. 따라서 외부 잘 만든 커넥터를 활용하자.
카프카 커넥트는 다른 데이터 저장소와 카프카간의 확장성과 신뢰성을 가지면서 데이터를 주고받을 수 있는 수단을 제공한다.
카프카 커넥터는 커넥터 플러그인을 개발하고 실행하기 위한 API
와 런타임을 제공한다. 커넥터 플러그인은 카프카 커넥트가 실행하는 라이브러리로, 데이터를 이동하는 것을 담당한다. 해당 내용은 복잡함으로써 그저 외부 저장소와 카프카를 다양한 형태로 컨버터하여 지원한다고만 알면 될 것 같다.
사용 예는 다음과 같다.
MySQL
에서 Elasticsearch
로 내보내기CDC
를 활용하여 카프카에 이벤트 적재하여 대응하기이러한 외부 엔드포인트의 연결사이에도 개별 메시지 변환을 제공한다. 이에 대해서는 내용이 방대함으로 이런게 있다 정도로만
카프카가 최고다라고 할수 있을지 몰라도, 하둡이나 엘라스틱서치와 같은 시스템을 중심으로 대부분의 데이터 아키텍처를 구축하는 경우, 자체적으로 로그 수집툴이 갖춰져 있다.(하둡의 경우 플룸, 엘라스틱서치의 경우 로그스태시, 플루언트디)
카프카가 아키텍처에서 이미 쓰이고 있으며, 많은 수의 소스와 싱크를 연결하는 것이 목표라면 카프카 커넥트 API를 추천한다. 하지만 실제로 사용하고 있지 않으면 로그스태시나 플룸을 활용하는 것을 권장한다.
데이터의 통합 관점에서 카프카를 활용하는 것은 분명 매력적이다. 하지만 카프카와 카프카 커넥트 API가 다양한 관점에서 적합한지 확인한 후 사용하는 것을 권장한다.