Skip to content
Published on

Kafka Diskless Topics(KIP-1150) — 크로스 AZ 비용과 맞바꾸는 지연 시간, 그리고 아직 배송되지 않은 기능

공유하기
Authors

들어가며 — Tiered Storage가 풀지 못한 비용

Kafka를 클라우드에서 굴려 본 사람은 청구서의 어느 줄이 아픈지 알고 있습니다. 디스크가 아닙니다. 네트워크입니다.

KIP-405 Tiered Storage는 이미 널리 쓰이고 있고, 비활성 세그먼트를 오브젝트 스토리지로 내려 보내 보관 비용을 크게 줄였습니다. 그런데 KIP-1150의 동기 섹션이 짚는 지점이 정확히 여기입니다 — Tiered Storage는 "액티브 세그먼트의 복제와 내구성 있는 저장에 대한 필요를 제거하지 않으며, 그것이 오늘날 하이퍼스케일러에서 Kafka 운영자에게 가장 큰 인프라 비용"이라는 것입니다.

왜냐하면 Kafka의 복제는 브로커 대 브로커 통신이고, 가용 영역(AZ)에 걸쳐 배치된 클러스터에서 그 트래픽은 전부 크로스 AZ이기 때문입니다. 데이터를 얼마나 오래 보관하느냐와 무관하게, 들어오는 모든 바이트가 복제 팬아웃만큼 AZ 경계를 넘습니다. Tiered Storage는 "오래된 데이터"를 싸게 만들었지, "지금 들어오는 데이터"를 싸게 만들지 못했습니다.

2026년 3월 2일, Apache Kafka 커뮤니티는 이 문제를 정면으로 겨냥한 제안을 승인했습니다. KIP-1150: Diskless Topics입니다.

승인된 것과 승인되지 않은 것

먼저 오해를 걷어내겠습니다. 승인은 배송이 아닙니다.

KIP-1150 본문의 Proposed Changes 섹션은 이렇게 시작합니다 — "This KIP will not require any changes to the codebase or documentation upon acceptance." 승인해도 코드 한 줄 바뀌지 않는다는 뜻입니다. 이어지는 문장이 더 명확합니다. 이 KIP를 승인함으로써 커뮤니티는 "이 기능의 필요성과 최종 사용자 요구사항에 대한 합의에 도달하는 것이지, 구체적인 구현 세부사항에 대한 합의가 아니다"라고요.

Kafka 커뮤니티는 이걸 메타 KIP 또는 동기 부여 KIP라고 부릅니다. 전례가 있습니다. ZooKeeper를 걷어내고 KRaft를 도입한 KIP-500이 같은 방식이었습니다 — 큰 방향을 먼저 합의하고, 실제 설계는 후속 KIP으로 쪼개는 것입니다.

그래서 지금 상태를 정확히 적으면 이렇습니다.

KIP-1150: Diskless Topics       Accepted (2026-03-02)   <- 방향만 승인
  ├─ KIP-1163: Diskless Core         Under Discussion    <- 실제 설계
  ├─ KIP-1164: Diskless Coordinator  Under Discussion    <- 실제 설계
  └─ KIP-1165: Object Compaction     Under Discussion (Re-Opened)

Apache Kafka 최신 릴리스: 4.3.1 (2026-06-25 released) -> Diskless 없음

즉 2026년 7월 현재, Diskless Topics는 어떤 Kafka 릴리스에도 들어 있지 않습니다. 목표 릴리스 버전도 공표되지 않았습니다. 방향에 합의했을 뿐입니다.

시간 감각을 위해 한 가지 참고점을 덧붙이면 — Aiven의 Josep Prat이 승인 후기 글에서 밝힌 바에 따르면, KIP-405 Tiered Storage는 첫 초안에서 승인까지 2년 3개월이 걸렸습니다(2018년 12월 14일 → 2021년 2월 18일). 그리고 그건 승인까지의 시간이었습니다. KIP-1150 자체는 2025년 4월 16일에 첫 버전이 공개돼 약 10개월 반 만에 승인됐지만, 쪼개기 전략 덕분에 빨랐던 것이지 구현이 빨라진 건 아닙니다. 같은 글의 표현을 빌리면, "KIP-1150을 승인받음으로써 우리는 경로를 그렸고 베이스캠프에 도달했다. 이제 등반이 시작된다"입니다.

비용 계산의 출발점 — 크로스 AZ 트래픽

KIP-1150의 동기 섹션은 숫자를 딱 세 줄 제시합니다. 그대로 옮깁니다.

마지막 줄이 중요합니다. 3대 클라우드 중 2곳만 크로스 AZ 트래픽에 과금합니다. Azure에서 돌리고 있다면 Diskless의 핵심 경제 논리는 성립하지 않습니다. KIP도 이 점을 인정하면서, 네트워크 비용을 빼고도 남는 이점을 따로 나열합니다 — 디스크에 저장하고 브로커 간 리밸런싱할 데이터가 줄어 클러스터 확장성이 좋아지고, 오브젝트 스토리지가 로컬 디스크보다 내구성이 낫다는 것입니다. 정직한 서술이지만, 비용 절감이 주된 동기였던 팀이라면 Azure에서는 계산기를 다시 두드려야 합니다.

Diskless가 없애겠다고 약속하는 항목은 두 가지입니다.

  • 복제로 인한 존 간 데이터 전송 비용 제거
  • 프로듀서로부터의 존 간 인그레스, 컨슈머로의 존 간 이그레스 비용 제거

두 번째가 눈에 띕니다. 복제 트래픽뿐 아니라 클라이언트 트래픽까지 겨냥합니다. 어떻게 가능한지는 아키텍처를 봐야 합니다.

아키텍처 — WAL Segment와 Diskless Coordinator

KIP-1163: Diskless Core가 실제 설계를 담고 있습니다. 핵심 전환은 하나입니다 — 데이터와 메타데이터를 분리한다.

클래식 토픽에서 Produce 요청을 받은 브로커는 여섯 가지 일을 합니다. 데이터 검증, 오프셋·타임스탬프 할당, 배치 데이터에 오프셋 주입, 내구성 있는 저장소에 쓰기, 복제 완료 대기, 응답 반환. Diskless에서는 이 중 오프셋·타임스탬프 할당이 Diskless Coordinator로 넘어가고, 오프셋 주입은 각 레플리카가 담당합니다.

Produce 경로는 이렇게 흐릅니다.

1. 프로듀서가 아무 브로커에나 Produce 요청을 보낸다 (리더가 아니어도 됨)
2. 브로커가 요청을 버퍼에 쌓는다 (크기 또는 시간 한도까지)
3. 한도에 도달하면 브로커가 WAL Segment 하나를 만든다
   -> 여러 토픽/파티션의 배치가 한 오브젝트 안에 섞여 들어감
4. WAL Segment를 오브젝트 스토리지에 업로드 (여기서 내구성 확보)
5. 브로커가 Diskless Coordinator에 batch coordinates를 커밋
6. Coordinator가 오프셋을 할당하고, 좌표를 영속화하고, 응답
7. 브로커가 해당 오브젝트에 묶인 모든 Produce 요청에 응답

여기서 설계 결정 하나가 비용을 직접 건드립니다. WAL Segment는 클래식 세그먼트와 달리 여러 파티션의 데이터를 한 오브젝트에 섞어 담습니다. KIP의 표현으로는 "오브젝트 스토리지 쓰기 연산 비용을 합리적인 수준으로 유지하기 위해 필요"합니다. 파티션마다 오브젝트를 따로 만들면 PUT 요청 수가 파티션 수에 비례해 폭발하니까요. 대신 대가가 따라옵니다 — 한 오브젝트 안에 여러 토픽의 데이터가 섞여 있으므로, 물리적 삭제가 까다로워집니다. KIP-1163은 이 문제를 논리적 삭제로 풀고, 컴플라이언스 목적의 물리적 삭제 시점을 "가장 긴 롤 타임보다 약간 더 긴" 시점으로 정직하게 규정합니다.

"디스크가 없다"는 말의 실제 의미도 KIP-1150이 직접 정리해 뒀습니다. Diskless는 브로커 디스크를 사용자 데이터의 주된 내구성 저장소로 쓰지 않는다는 뜻이지, 디스크가 사라진다는 뜻이 아닙니다. KRaft 메타데이터, 배치 메타데이터, 티어드 스토리지로 복사되는 중의 데이터, 컨슈머에게 서빙하기 위한 캐시는 여전히 디스크를 씁니다. KIP의 문장이 재치 있습니다 — "Diskless가 '디스크 없음'에 대해 갖는 관계는, Serverless가 '서버 없음'에 대해 갖는 관계와 같다."

메타데이터 쪽인 KIP-1164: Diskless Coordinator에는 흥미로운 구현 선택이 있습니다. Coordinator 상태를 __diskless_metadata라는 새 내부 토픽에 저장하고, 이 토픽을 여러 파티션으로 샤딩해 코디네이터를 여러 개 만듭니다. 그리고 로컬 상태 구체화에는 SQLite를 씁니다. 이유가 명시돼 있습니다 — 다른 코디네이터와 달리 DC의 상태 크기는 "수백 메가바이트 또는 심지어 기가바이트"에 이를 것으로 예상되어 메모리에 다 들고 있기가 비현실적이기 때문입니다. Kafka 브로커 안에 SQLite가 들어온다는 게 낯설게 느껴진다면, 그 감각이 바로 이 KIP들이 아직 Under Discussion인 이유의 일부입니다.

지연 시간 청구서 — KIP-1163이 직접 적어 둔 예산

이제 이 글에서 가장 중요한 부분입니다. Diskless의 대가는 지연 시간이고, KIP-1163은 그 예산을 숨기지 않고 적어 뒀습니다.

Append latency is broadly composed by:
- Buffering: up to 250ms or 4MiB (both configurable)
- Upload to Remote Storage: P99 ~200-400ms, P50 ~100ms
- Batch Coordinates Commit: P99 ~20-50ms, P50 ~10ms (배치 수에 따라)

We are aiming for a Produce request latency of P50 ~500ms P99 ~1-2 sec

읽는 법이 중요합니다. 이건 측정값이 아니라 목표치입니다. KIP의 원문은 "We are aiming for"이고, 저는 이걸 "이렇게 나온다"로 바꿔 읽지 않겠습니다. 아직 업스트림 구현이 없으니 측정값이 있을 수도 없습니다.

그래도 이 예산은 구조를 드러냅니다. 목표 P50이 약 500ms인데, 그중 최대 250ms가 버퍼링입니다. 지연의 절반가량이 스토리지가 느려서가 아니라 기다리기로 한 결정에서 나온다는 뜻입니다 — 오브젝트 스토리지의 쓰기 연산 비용을 감당하려면 배치를 모아야 하고, 배치를 모으려면 기다려야 하니까요. 물리 법칙이 아니라 경제 법칙에서 나온 지연입니다.

나머지 절반은 물리 쪽입니다. KIP-1163은 "원격 스토리지는 로컬 디스크보다 지연이 높을 수 있으며, 이는 Kafka 요청과 종단 간 데이터 지연을 증가시킨다"고 적고, WarpStream 문서도 "오브젝트 스토리지에 파일을 만드는 것은 로컬 디스크 쓰기에 비해 상대적으로 높은 지연의 연산"이라고 같은 이야기를 합니다.

그렇다면 이 500ms를 무엇과 비교해야 할까요. KIP도 벤더 문서도 클래식 Kafka의 Produce 지연 기준치를 제시하지 않고, 그러니 저도 여기서 대신 숫자를 지어내지 않겠습니다. 비교 대상은 당신의 현재 클러스터입니다 — 지금 당신의 프로듀서가 몇 밀리초에 응답을 받고 있는지는 당신의 대시보드에만 있고, 그 숫자와 500ms를 나란히 놓는 것이 유일하게 의미 있는 비교입니다.

KIP-1163은 이 트레이드오프를 감추지 않고 아예 설계 원칙으로 삼습니다. Diskless 토픽, 클래식 토픽, 티어드 토픽이 한 클러스터에 공존하고, 애플리케이션 개발자가 "토픽 단위로 지연 시간과 비용을 맞바꿀 수 있게" 합니다. KIP의 데이터 흐름 설명에서 저지연 데이터는 클래식 토픽이 계속 나르고, 고지연 데이터가 Diskless 인그레션 엔진으로 갑니다. 즉 이건 Kafka를 대체하는 기능이 아니라, Kafka에 다이얼을 하나 추가하는 기능입니다.

벤더의 숫자를 어떻게 읽을 것인가

Diskless와 같은 아이디어를 이미 프로덕션에서 굴리고 있는 상용 제품들이 있습니다. WarpStream, Buffstream, Confluent Freight Clusters, Redpanda Cloud Topics 등입니다. 이들의 공개 수치는 "S3 기반 로그 엔진이 실제로 어떤 지연을 내는가"에 대한 유일한 실측 참고점이지만, 전부 벤더 자체 측정이라는 점을 잊으면 안 됩니다.

WarpStream 공식 문서가 가장 솔직한 편입니다. 성능 튜닝 문서는 이렇게 적습니다 — "WarpStream Agent는 로컬 디스크가 없고 오브젝트 스토리지에 데이터를 직접 씁니다. 오브젝트 스토리지에 파일을 만드는 것은 로컬 디스크 쓰기에 비해 상대적으로 높은 지연의 연산입니다. 예를 들어 우리 경험상 S3에 4MiB 파일을 쓰는 P99 지연은 약 400ms입니다." (Tuning for Performance) "우리 경험상(in our experience)"이라는 한정어가 원문에 그대로 있습니다.

이 문서가 이어서 하는 이야기가 더 실무적입니다. 400ms 지연 위에서 처리량을 내려면 리틀의 법칙에 따라 동시성이 필요합니다. 문서의 예시 그대로 옮기면 — 1GiB/s 쓰기 처리량은 1MiB 배치 크기에서 동시에 400개의 Produce 요청이 떠 있어야 달성됩니다. 그리고 "충분한 미처리 요청이 없는 것이 WarpStream 사용 시 낮은 쓰기 처리량의 가장 큰 단일 원인"이라고 못 박습니다. S3 기반 엔진으로 옮기면 클라이언트 튜닝의 성격 자체가 바뀐다는 뜻입니다.

지연을 더 낮추는 길도 있지만 공짜가 아닙니다. WarpStream의 S3 Express 문서는 "배치 타임아웃을 줄인 것과 결합하면 S3 Express가 Produce 요청의 P99 지연을 150ms 미만으로 낮출 수 있다"고 합니다. 대신 같은 문서가 대가를 나열합니다 — S3 Express One Zone은 이름대로 단일 AZ에만 저장하므로 WarpStream은 여러 단일 존 버킷의 쿼럼에 걸쳐 복제해야 하고, S3 Express의 보관 비용은 "복제를 고려하기 전에 이미 일반 오브젝트 스토리지의 약 7배"입니다. 그래서 권장 구성은 인그레션만 S3 Express로 하고 컴팩션은 일반 버킷으로 내리는 것입니다. 지연을 사려면 돈을 내야 한다는 원래 이야기로 돌아옵니다.

반면 조심해서 읽어야 할 숫자도 있습니다. Aiven의 승인 후기 글에는 관련 자료 카드에 "TCO를 최대 80%까지 절감"이라는 문구가 붙어 있습니다. 이건 벤더 자체 주장이고, 해당 글에는 그 80%가 무엇을 포함하고 무엇을 제외한 계산인지 — 어떤 워크로드, 어떤 클라우드, 어떤 복제 팩터, 어떤 보관 기간, 컴퓨트를 포함했는지 — 아무 근거도 제시돼 있지 않습니다. 홍보 카피에 붙은 상한선("최대")일 뿐입니다. Aiven은 KIP-1150의 주 저자이자 관리형 Kafka로 수익을 내는 회사입니다(글 자체가 이 이해관계를 솔직하게 밝히고는 있습니다). 스트리밍 벤더의 TCO 계산은 특히 자기 편향적이므로, 이런 숫자는 당신의 워크로드로 직접 검증하기 전까지는 방향 지시등 정도로만 취급하는 게 맞습니다.

조용히 깨지는 것들

KIP-1150은 Diskless 토픽이 클래식 토픽과 "의미론적으로 교체 가능"하도록 의도한다고 밝히고, 순서 보장·멱등성·트랜잭션·컨슈머 그룹·큐/셰어 그룹·티어드 스토리지를 모두 지원한다고 나열합니다. 대부분 사실이겠지만, 설계 문서를 자세히 읽으면 매끄럽지 않은 모서리가 몇 개 보입니다.

큐(셰어 그룹)는 비용 이점을 온전히 받지 못합니다. KIP-1163이 직접 적습니다 — ShareFetch 요청은 셰어 파티션 리더만 처리할 수 있고, 그 리더는 파티션 리더와 같은 곳에 있습니다. 따라서 "큐 컨슈머는 ShareFetch 요청을 파티션 리더에게 보내야 하며, 컨슈머 존 간 트래픽 제거의 이점을 항상 누릴 수는 없습니다." 존 간 이그레스를 없애겠다는 약속에 예외가 하나 있는 셈이고, 큐 기능에 대한 랙 인지 최적화는 이 KIP의 범위 밖으로 밀려나 있습니다.

ISR의 의미가 바뀝니다. Diskless에서 "in-sync replica"는 리더와 동기화됐다는 뜻이 아니라 Diskless Coordinator와 동기화됐다는 뜻입니다. Coordinator가 진실의 원천이니까요. KIP-1163이 짚는 함의가 날카롭습니다 — 리더도 그저 하나의 레플리카일 뿐이므로 리더가 out-of-sync일 수 있습니다. 그러면 리더는 티어드 스토리지로 세그먼트를 오프로드하는 자기 임무를 효율적으로 수행하지 못하고, 다른 out-of-sync 레플리카와 마찬가지로 리더에서 읽는 것이 권장되지 않습니다. Kafka를 오래 운영한 사람의 직관이 여기서 한 번 접히는 지점입니다. 참고로 레플리카는 브로커 간 복제를 하지 않는데도 여전히 리더에게 FetchRequest를 보냅니다 — 리더는 레코드 없는 빈 응답을 돌려주고, 이 왕복이 ISR 추적 수단으로만 남습니다.

오래된 클라이언트는 우회로를 타야 합니다. 새 클라이언트는 MetadataRequest v14로 랙 정보를 보내고 어떤 토픽이 Diskless인지, 어느 브로커에 produce하는 게 좋은지 받아 옵니다. 하지만 구버전이나 서드파티 클라이언트를 위해 KIP-1163이 제안하는 것은 클라이언트 ID에 랙 식별자를 덧붙이는 방식입니다.

client.id = "my-app,diskless_rack_id=use1-az4"

브로커는 이 문자열을 보고 해당 랙의 레플리카를 리더인 것처럼 응답에 채워 넣습니다. 동작은 하지만, KIP 스스로 밝히듯 이렇게 하면 진짜 리더만 처리할 수 있는 ShareFetch가 막힙니다. 그래서 "프로듀서와 일반 컨슈머에는 diskless_rack_id를 지정하고 셰어 컨슈머에는 지정하지 말라, 후자는 코드상 별도 인스턴스여야 한다"는 운영 지침이 따라붙습니다. 우아하지 않고, 본인들도 그걸 압니다.

그래서, 당신은 기다려야 하나

판단 기준은 이렇게 정리됩니다.

값을 할 가능성이 높은 경우

  • AWS 또는 GCP에서 돌리고 있고, 처리량이 커서 크로스 AZ 복제 트래픽이 청구서의 실제 항목으로 보인다.
  • 워크로드가 지연에 관대하다 — 로그 수집, 메트릭, 분석 파이프라인, 배치성 인제스트처럼 수백 밀리초의 Produce 지연이 아무 의미 없는 곳.
  • 처리량이 높고 파티션당 데이터가 두꺼워서 배치가 자연스럽게 찬다.

과잉이거나 해로운 경우

  • Azure에서 돌린다. 크로스 AZ 과금이 없으므로 핵심 경제 논리가 사라집니다.
  • 지연이 제품 요구사항이다. 목표치가 P50 500ms인 경로에 주문 체결이나 사용자 요청 경로를 올릴 수는 없습니다.
  • 처리량이 낮다. 트래픽이 적으면 크로스 AZ 비용도 적고, 버퍼링 지연만 고스란히 물게 됩니다.
  • 큐/셰어 그룹이 주 사용 패턴이다. 위에서 본 예외가 정면으로 걸립니다.
  • 그리고 지금 당장 필요하다. 이게 가장 현실적인 배제 조건입니다.

마지막 항목을 다시 강조하겠습니다. 2026년 7월 기준 이 기능은 존재하지 않습니다. 방향만 승인됐고, 설계 KIP 두 개가 아직 논의 중이며, 목표 릴리스도 없습니다. 지금 크로스 AZ 청구서가 아프다면 선택지는 상용 제품(WarpStream 등)이거나, Aiven이 오픈소스로 공개한 실험 포크 Inkless이거나, 아니면 기존 기법(단일 랙 토픽 같은)으로 버티는 것입니다. KIP-1150은 단일 랙 토픽 같은 기존 우회책을 "내구성·가용성·의미론·사용성 측면에서 애플리케이션별 타협을 강요한다"며 거부 대안 섹션에서 명시적으로 기각했는데, 그 타협이 바로 지금 당신이 선택할 수 있는 것들이라는 게 아이러니입니다.

남은 길

KIP-1150이 흥미로운 이유는 기술보다 정치에 가깝습니다.

거부 대안 섹션의 마지막 항목이 "Do Nothing"인데, 그 논거가 이례적으로 솔직합니다 — 아무것도 하지 않으면 이것이 "업스트림 구현에서 가장 크게 빠진 단일 기능"이 될 것이고, 고스케일·클라우드 사용자들을 Kafka 대안으로 밀어낼 것이며, Kafka가 "Kafka 프로토콜에 대한 권한을 완전히 잃을" 수 있다는 것입니다. 실제로 지난 몇 년간 등장한 클라우드 네이티브 Kafka 호환 제품들은 전부 오픈소스가 아닙니다. KIP-1150은 그 흐름에 대한 업스트림의 응답입니다.

그 응답이 얼마나 진지했는지는 경쟁 제안이 동시에 세 개나 올라왔다는 사실에서 드러납니다 — KIP-1150 외에 KIP-1176(Tiered Storage for the Active Log Segment)과 KIP-1183(Unified Shared Storage)이 같은 공간에 제출됐고, 결국 KIP-1183의 저자들(Slack)이 자기 제안을 접고 KIP-1150을 공식 지지하는 것으로 정리됐습니다. 투표는 2026년 1월 9일 재시작돼 3월 2일에 통과했고, Aiven의 집계에 따르면 바인딩 9표와 논바인딩 5표를 받았습니다.

앞으로 남은 것은 KIP-1163과 KIP-1164를 실제로 통과시키는 일입니다. 그리고 그 너머에는 KIP-1150이 "Further Work"로 남겨 둔, 아직 KIP조차 없는 항목들이 있습니다 — 클래식 토픽과 Diskless 토픽 간 타입 변경, 브로커 역할 특화(produce/consume/coordination/compaction 전용 브로커), 고지연 환경에서 프로듀서당 처리량을 높이기 위한 병렬 Produce 처리, Iceberg 포맷, 메타데이터 복제를 통한 멀티 리전 액티브-액티브. 마지막 두 개는 실현되면 Kafka의 정체성 자체를 건드리는 이야기지만, 지금은 목록의 한 줄일 뿐입니다.

마치며

정리하면 이렇습니다. Tiered Storage는 오래된 데이터를 싸게 만들었지만 액티브 세그먼트의 복제 트래픽은 그대로 뒀고, 그게 하이퍼스케일러에서 Kafka의 가장 큰 인프라 비용입니다. KIP-1150은 오브젝트 스토리지를 원본 저장소로 삼아 그 비용을 없애자는 방향에 커뮤니티가 합의한 것입니다 — 방향만.

대가는 명확하고, 설계 문서가 그걸 숨기지 않습니다. 목표 Produce 지연 P50 약 500ms, P99 약 1~2초. 그 절반은 오브젝트 스토리지 PUT 비용을 감당하려고 배치를 모으는 시간입니다. 그래서 Diskless는 "더 좋은 Kafka"가 아니라 토픽 단위로 돌릴 수 있는 다이얼입니다 — 저지연이 필요한 토픽은 클래식으로 남고, 지연에 관대한 대용량 토픽만 Diskless로 보내는 것이 설계자들이 그린 그림입니다.

그리고 그 다이얼은 아직 당신 손에 없습니다. Kafka 4.3.1에는 없고, 언제 들어올지도 공표되지 않았습니다. 그러니 지금 할 일은 마이그레이션 계획이 아니라 측정입니다 — 당신의 크로스 AZ 트래픽이 실제로 청구서의 얼마인지, 당신의 프로듀서가 500ms를 견딜 수 있는지. 그 두 숫자를 모르면 이 기능이 도착해도 쓸지 말지 판단할 수 없습니다. 기능이 먼저가 아니라 청구서가 먼저입니다.

참고 자료