시스템에서 시스템으로 데이터를 옮기는 경로. 카프카가 여기서 맡는 역할은 하나로 요약된다. 매우 크고 안정적인 버퍼다.

버퍼가 만드는 분리

읽는 쪽과 쓰는 쪽을 버퍼로 갈라놓으면, 하나의 원본에서 온 같은 데이터를 서로 다른 적시성과 가용성 요구를 가진 여러 시스템으로 보낼 수 있다. 양쪽이 분리되면서 신뢰성과 보안성, 효율성이 함께 올라간다.

파이프라인을 세울 때 따지는 것

파이프라인을 설계할 때 볼 것이 여덟 가지다.

적시성은 어떤 자료가 의사결정에 영향을 줄 수 있도록 적절한 시기에 제공되는 성질이다. 좋은 통합 시스템은 파이프라인마다 다른 적시성 요구를 지원하면서, 요구가 바뀌었을 때 이전하기 쉬워야 한다. 카프카를 쓰는 쪽과 읽는 쪽 사이의 시간적 민감도를 분리시키는 거대한 버퍼로 보면 이해가 쉽다. 쓰는 쪽은 실시간으로, 읽는 쪽은 배치로 갈 수 있고 반대도 된다. 백프레셔도 여기서 단순해진다. 소비 속도가 온전히 읽는 쪽에 의해 결정되므로, 카프카가 필요하면 쓰는 쪽에 대한 응답을 늦춤으로써 압력을 전달한다. 백프레셔는 소비자의 처리 능력을 초과하는 생산 속도를 제어해 시스템 안정성을 유지하는 방법이다.

신뢰성은 SPOF를 피하고 모든 종류의 장애에서 신속하게 자동 복구하는 것이다. 여기에 전달 보장 수준을 정하는 일이 딸려 온다. 카프카 자체는 최소 한 번을 보장하고, 트랜잭션 모델이나 고유 키를 지원하는 외부 저장소와 결합되면 정확히 한 번까지 간다. 많은 엔드포인트가 그런 저장소이므로 실무의 카프카 파이프라인은 대체로 정확히 한 번을 달성하지만, 그것은 카프카 혼자 한 일이 아니다. 정확히 한 번을 보라.

처리율은 갑자기 늘어야 하는 상황에도 적응할 수 있어야 한다. 카프카가 버퍼이므로 프로듀서와 컨슈머의 처리율을 묶어서 생각하지 않아도 된다. 프로듀서가 빨라도 데이터는 카프카에 쌓이고 컨슈머가 따라잡으므로, 앞에서 말한 압력 전달 장치를 직접 만들 필요가 없다. 프로듀서와 컨슈머를 각각 독립적으로 더해서 파이프라인의 한쪽만 확장할 수도 있다.

데이터 형식은 저장 시스템마다 다르다. 엘라스틱서치는 JSON, HDFS는 Parquet, S3는 CSV다. 카프카와 커넥트 API는 데이터 형식에 완전히 독립적이고, 컨버터가 그것을 가능하게 한다. 많은 소스와 싱크가 스키마를 가지므로, 소스에서 데이터와 함께 스키마를 읽어 저장해두면 호환성 검증에 쓰거나 싱크 DB의 스키마를 갱신하는 데 쓸 수 있다.

변환은 파이프라인이 통과하는 데이터에 손을 얼마나 대는가의 문제이고, ETL과 ELT로 갈린다. ETL은 파이프라인이 변환까지 담당한다. 수정 후 다시 저장할 필요가 없어 시간과 공간을 아끼는 대신 연산과 저장의 부담을 파이프라인이 지고, 파이프라인에서 누가 데이터를 삭제하면 사용처에서 그것을 쓸 수가 없다. ELT는 자료형 변환 정도의 최소한만 하고 원본과 최대한 비슷하게 전달해서 대상 시스템에 최대의 유연성을 준다. 대신 변환 작업이 대상 시스템의 CPU와 자원을 잡아먹는다. 커넥트의 SMT가 단위 레코드 변환을 맡고, 조인이나 집계처럼 상태가 필요한 변환은 카프카 스트림즈의 몫이다.

보안은 누가 접근할 수 있는가, 전송 중 암호화되는가, 누가 파이프라인을 바꿀 수 있는가, 개인 식별 정보(PII)를 다룰 때 법과 규제를 지키는가를 묻는다. 카프카는 암호화, SASL을 이용한 인증과 인가, 감사 로그, 외부 비밀 설정(HashiCorp Vault 등)을 지원한다.

장애 처리는 모든 데이터가 항상 완벽할 것이라는 가정을 버리는 데서 시작한다. 카프카는 이벤트를 장기간 저장할 수 있으므로 이전 시점으로 돌아가 에러를 복구할 수 있다.

결합과 민첩성은 데이터 원본과 대상을 끝까지 분리해두는 문제다. 어디서 결합이 새어 들어오는지는 아래에서 따로 본다.

결합이 새어 들어오는 세 군데

원본과 대상을 분리하는 것이 목표인데, 세 군데에서 결합이 새어 들어온다.

임기응변 파이프라인이 첫째다. 연결할 때마다 커스텀 파이프라인을 만들면 특정 엔드포인트에 강하게 결합되어 설치, 유지 보수, 모니터링에 상당한 노력이 든다.

메타데이터 유실이 둘째다. 스키마 메타데이터를 보존하지 않고 스키마 진화도 지원하지 않으면 양쪽 소프트웨어가 모두 데이터 파싱 방법을 알아야 해서 강하게 결합된다.

과도한 처리가 셋째다. 파이프라인에서 처리를 너무 많이 하면 하단 시스템에 어떤 필드를 보존할지, 어떻게 집계할지 선택지가 남지 않는다. 하단의 요구는 자주 바뀌는데 그때마다 파이프라인을 고쳐야 한다. 가공되지 않은 raw 데이터를 최대한 건드리지 않은 채 내려보내고, 처리와 집계는 애플리케이션이 알아서 결정하게 하는 쪽이 유연하다.

관련

출처