Skip to content
Published on

Cassandra 6.0-alpha1과 Accord 트랜잭션 — 5년 만의 "범용 트랜잭션"은 지금 어디까지 왔나

공유하기
Authors

들어가며 — 5년짜리 약속의 중간 점검

Cassandra에서 "트랜잭션"은 오랫동안 반쪽짜리 단어였습니다. LWT(경량 트랜잭션)는 Paxos 기반 CAS라서 단일 키 안에서만 동작합니다 — Cassandra 문서의 표현 그대로, "Paxos only supports a single key". 여러 파티션을 원자적으로 묶는 일은 애플리케이션이 사가나 배치로 흉내 내야 했습니다.

이걸 바꾸겠다는 제안이 CEP-15: General Purpose Transactions입니다. 추적용 JIRA인 CASSANDRA-17092는 2021년 10월 30일에 만들어졌고, 2025년 1월 21일에야 "Fixed"로 닫히며 trunk에 병합됐습니다. 그리고 2026년 3월 21일자 아티팩트로 6.0-alpha1이 아파치 공식 저장소에 올라왔고, 4월 3일 dev 리스트에 릴리스가 공지됐습니다. 제안에서 실행 가능한 릴리스까지 4년 반. 이 글을 쓰는 2026년 7월 중순 기준으로 6.0은 여전히 alpha1이 전부이고, 프로덕션 라인은 5.0.8(2026-04-16)입니다.

그래서 지금 시점에 정리할 가치가 있습니다. 무엇이 약속됐고, 무엇이 실제로 배포됐으며, 문서에 적힌 제약은 무엇이고, 당신은 언제부터 신경 쓰면 되는지.

Accord가 약속한 것 — CEP-15의 목표

CEP-15가 명시한 목표를 그대로 옮기면 이렇습니다.

  • 범용 트랜잭션 — 데이터베이스의 어떤 키들이든 한 번에 묶을 수 있다
  • strict-serializable 격리
  • 최적 지연 — 정상 조건에서 모든 트랜잭션이 WAN 왕복 1회
  • 최적 장애 허용 — 소수 복제본 장애에 지연·성능이 영향받지 않음
  • 확장성 — 병목을 새로 만들지 않음
  • Paxos로부터의 라이브 마이그레이션 지원

기존 시스템과의 차별점은 리더가 없다는 것입니다. CEP 문서 자체가 선행 사례를 이렇게 분류합니다 — FaunaDB·FoundationDB는 글로벌 리더(확장성 병목), DynamoDB·CockroachDB·YugabyteDB는 트랜잭션 로그와 키별 리더의 복잡한 조합, 그리고 학계의 리더리스 접근(EPaxos 계열)은 아직 실제 DB에 쓰인 적이 없다. Accord는 이 세 번째 길을 프로덕션 DB에 넣겠다는 시도입니다. 장기 계획도 문서에 명시돼 있습니다 — 이 작업은 프로젝트에서 Paxos를 대체할 것으로 기대되며, 과도기 동안 두 프로토콜이 공존한 뒤 Paxos는 폐기 예정입니다.

주의할 점 하나. "WAN 왕복 1회"는 프로토콜 수준의 주장이고, 밀리초 단위의 공식 벤치마크 수치는 이 글을 쓰는 시점에 공식 문서 어디에도 없습니다. 뒤에서 보겠지만 릴리스 노트조차 아직 자리 표시자 상태입니다.

무엇이 실제로 배포됐나 — "분기별 알파"의 실체

6.0-alpha1의 CHANGES.txt에는 실제로 이 줄이 들어 있습니다.

6.0-alpha1
 * General Purpose Transactions (Accord) [CEP-15] (CASSANDRA-17092)
 * Automated Repair Inside Cassandra [CEP-37] (CASSANDRA-19918)
 * ...(발췌 — 이 밖에 TCM, 제약 프레임워크, UCS 병렬 컴팩션 등 다수)

Accord만 온 게 아닙니다. NEWS.txt의 6.0 신기능 목록에는 CEP-21 트랜잭셔널 클러스터 메타데이터(TCM), CEP-37 자동 리페어 스케줄러, CEP-42 제약 프레임워크, JDK 21과 Generational ZGC 기본 GC 채택이 올라 있습니다. TCM은 업그레이드 절차 자체를 바꾸는 변경이라 NEWS.txt 최상단에 "이전 업그레이드들과 다른 운영 단계가 필요하다"는 경고가 붙어 있습니다.

다만 릴리스의 성격을 정확히 읽어야 합니다. 4월 3일 공지문은 이렇게 말합니다 — 이것은 6.0 시리즈의 분기별(quarterly) 알파 릴리스이며, cassandra-6.0 브랜치는 아직 만들어지지 않았고, 이 릴리스는 알파 품질 라이프사이클 가이드라인을 시작하지 않으며, 분기별 알파는 오직 개발·테스트 용도라고요. 2025년 11월의 릴리스 케이던스 제안 스레드를 보면 취지가 분명합니다 — 분기별 알파는 백포트도 지원도 없는, "빌드가 되는 걸 확인하고 투표한 특정 날짜의 태그"일 뿐입니다.

정식 사이클은 그 직후에 시작됐습니다. 2026년 4월 9일 스레드에서 cassandra-6.0 브랜치 분기와 6.0-alpha2가 논의됐고("이것이 알파 릴리스 라이프사이클을 개시한다"), 실제로 지금 저장소에는 cassandra-6.0 브랜치가 존재하며 trunk는 7.0 개발로 넘어갔습니다. 그러나 7월 중순 현재 공식 다운로드 페이지에 있는 6.0 계열 아티팩트는 alpha1 하나뿐입니다. 베타도, GA 날짜 약속도 없습니다.

버전 번호에 얽힌 뒷이야기도 있습니다. 원래 이 릴리스는 5.1이 될 예정이었는데, 2024년 12월 dev 리스트 논의 "5.1 should be 6.0"에서 TCM과 Accord가 운영 방식을 근본적으로 바꾸는 세대 교체라는 이유로 메이저 번호를 올리자는 쪽으로 정리됐습니다. 결과적으로 5.1은 나오지 않았고 다음 버전은 6.0이 됐습니다.

문서가 코드를 못 따라가고 있다는 신호도 그대로 보입니다. NEWS.txt의 6.0 신기능 섹션에는 "아래는 자리 표시자이며 곧 수정될 것"이라는 문구가 남아 있고, 정작 Accord는 신기능 목록에 항목조차 없습니다. CQL 트랜잭션 사용자 가이드(transactions.adoc)는 trunk에는 있지만 cassandra-6.0 브랜치에는 아직 없습니다. 알파를 직접 테스트할 게 아니라면, 지금 단계에서 블로그·발표 자료보다 저장소의 원문서를 읽는 편이 정확합니다.

문법 — BEGIN TRANSACTION의 생김새와 원샷 모델

trunk의 트랜잭션 가이드에 실린 구문은 이렇게 생겼습니다.

BEGIN TRANSACTION
  LET sender = (SELECT balance FROM accounts WHERE user_id = ?);

  SELECT sender.balance;              -- 결과 반환은 수정문보다 앞에서만

  IF sender.balance >= 100 THEN
    UPDATE accounts SET balance = balance - 100 WHERE user_id = ?;
    UPDATE accounts SET balance = balance + 100 WHERE user_id = ?;  -- 다른 파티션도 OK
  END IF
COMMIT TRANSACTION

서로 다른 파티션(그리고 서로 다른 테이블)에 걸친 읽기-조건-쓰기가 하나의 원자 단위가 됩니다. LWT로는 불가능했던 일입니다.

핵심은 이것이 대화형 트랜잭션이 아니라는 점입니다. RDBMS처럼 BEGIN을 열어 두고 애플리케이션 로직을 오가며 여러 문장을 실행하는 모델이 아니라, 전체 트랜잭션을 하나의 문장으로 한 번에 제출하는 원샷 모델입니다. 내부 문서(CQL on Accord)가 이유를 설명해 줍니다 — 트랜잭션이 건드릴 키 집합은 실행 전에 전부 선언돼야 하고 실행 중에 바꿀 수 없습니다. 이 선선언이 리더 없는 의존성 추적을 가능하게 하는 대가입니다.

문서에 명시된 제약을 추리면 이렇습니다.

  • LET의 SELECT는 정확히 한 행만 반환해야 하고, 파티션 키 전체를 등호로 지정해야 하며, 범위 조건·다중 파티션·집계는 불가
  • 트랜잭션 블록 안에서 카운터 테이블, 집계 함수, ORDER BY와 GROUP BY, 사용자 지정 TTL·타임스탬프, 범위 DELETE 사용 불가
  • IF 조건은 AND만 지원(OR 없음), null 비교는 전부 거짓
  • SET 절에서 행 참조 산술 불가 — SET balance = sender.balance - 100 같은 건 안 되고, 계산값을 파라미터로 넘겨야 함
  • 결과를 돌려주는 SELECT는 수정문보다 앞에 와야 하고, 수정 후의 값을 보려면 커밋 뒤 별도 조회

성능 가이드도 문서에 있는데, 그 각주가 이 기능의 성숙도를 정직하게 보여 줍니다 — LET은 5개, 파티션은 3개 미만으로 시작하라면서, 이는 "경험적으로 도출된 한계가 아니라 제안된 가이드라인"이라고 스스로 밝힙니다. 즉 프로젝트도 아직 실측 기반 튜닝 지침을 갖고 있지 않다는 뜻입니다.

모드와 비용 — full, mixed_reads, off

Accord는 켠다고 일괄 적용되는 게 아니라 테이블 단위로 선택합니다. cassandra.yaml에서 accord.enabled: true를 켠 뒤, 테이블마다 transactional_mode를 설정합니다. 운영 가이드 기준으로 세 모드입니다.

off(기본값) — 지금까지의 Cassandra 그대로. SERIAL은 Paxos로, 나머지는 최종 일관성 경로로 가고, 트랜잭션 문장은 거부됩니다.

full(권장) — 모든 읽기·쓰기가 Accord를 통과합니다. 비트랜잭션 독자가 없다는 걸 알기에 Accord가 단일 복제본 읽기와 비동기 커밋을 쓸 수 있고, 문서 표현으로는 WAN 왕복이 2회에서 1회로 줄어듭니다. 대신 일관성 수준 지정은 무시됩니다.

mixed_reads — 쓰기는 Accord로, 비SERIAL 읽기는 기존 경로로. 이 경우 Accord 쓰기를 기존 읽기가 볼 수 있어야 하므로 요청된 일관성 수준으로 동기 커밋을 해야 하고, WAN 왕복은 총 2회가 됩니다. 문서 스스로 "대부분의 사용자는 off에서 곧장 full로 가라"고 권합니다.

여기서 멀티 DC 운영자라면 반드시 알아야 할 제약이 나옵니다. Accord가 지원하는 일관성 수준은 읽기 ONE·QUORUM·SERIAL·ALL, 쓰기 ANY·ONE·QUORUM·SERIAL·ALL이 전부입니다. LOCAL 계열(LOCAL_QUORUM, LOCAL_ONE, LOCAL_SERIAL)과 TWO·THREE는 지원되지 않고, 지원 안 되는 수준의 요청은 거부됩니다. DC 로컬 지연에 기대어 멀티 리전을 굴려 온 워크로드라면, 지금의 Accord는 그 요구를 표현할 방법 자체가 없습니다. CEP-15도 LOCAL_SERIAL 대체(비글로벌 동작 모드)를 "향후 목표"로만 적어 뒀습니다. 덤으로, 커밋 일관성 수준을 ONE으로 줘도 조용히 QUORUM으로 수행된다는 것도 문서에 명시돼 있습니다.

성능 관련해서 문서가 정직하게 적어 둔 비용도 있습니다. LIMIT이 걸린 파티션 범위 읽기는 노드별 커맨드 스토어(기본값: 가용 프로세서 수) 개수만큼 분할 실행된 뒤 코디네이터에서 병합되므로 메모리와 CPU가 그에 비례해 증폭됩니다. 페이징은 페이지마다 별도 트랜잭션이라 전체 결과의 선형화를 보장하지 않고, 파티션 범위 읽기는 strict-serializable 결과를 내지 않습니다. 범위 트랜잭션은 키 트랜잭션보다 의존성 추적이 비싸고 충돌도 잦다고 내부 문서가 못 박아 둡니다.

기존 테이블을 옮기는 비용 — 마이그레이션은 공짜가 아니다

새 테이블이야 WITH transactional_mode = 'full'로 만들면 그만이지만, 기존 테이블은 라이브 마이그레이션을 거쳐야 합니다. 이유가 흥미로운데, Accord는 트랜잭션 복구 시 읽기를 재실행해야 해서 읽기가 결정적이어야 하고, 비SERIAL 쓰기는 그 결정성을 깨기 때문입니다. 그래서 마이그레이션은 2단계입니다.

  1. ALTER 후 1단계 — 비SERIAL 쓰기는 Accord로 가되(요청된 일관성 수준으로 동기 커밋), SERIAL은 Paxos에 남습니다. 데이터 리페어(풀 또는 증분)가 한 번 돌아야 Accord가 기존 데이터를 안전하게 읽을 수 있게 됩니다.
  2. 2단계 — 모든 연산이 Accord로 갑니다. 단, 키마다 Paxos 키 리페어가 선행돼 최소 WAN 왕복 1회가 추가되고, Paxos 쓰기가 QUORUM에서만 보이므로 Accord도 QUORUM으로 읽어야 합니다. 마이그레이션 완료에는 풀 리페어와 Paxos 리페어가 필요합니다 — 증분 리페어는 Paxos 리페어가 전파한 데이터를 포함하지 못해서 안 됩니다.

리페어 트리거에는 자동화가 없습니다. 문서 그대로, 호환되는 리페어를 정기적으로 돌리고 있다면 마이그레이션은 언젠가 끝나고, 아니면 nodetool consensus_admin finish-migration으로 직접 밀어야 합니다. 마이그레이션 중인 범위를 건드리는 요청은 두 시스템을 오가느라 최소 한 번의 WAN 왕복이 더 붙습니다. 되돌리는 길(full에서 off로)도 문서화돼 있다는 건 다행인 부분 — 단일 단계로, Accord 리페어 후 Paxos로 복귀합니다.

운영 관점 요약: 마이그레이션 기간 동안 지연은 늘고, 풀 리페어라는 무거운 작업이 필수이며, 그 오케스트레이션은 당신 몫입니다(6.0의 CEP-37 자동 리페어가 이 부담을 얼마나 덜어줄지는 아직 실측 사례가 없습니다).

그동안 5.x에서 쓸 수 있는 것 — SAI와 벡터 검색의 현실

Accord가 알파에 머무는 동안, 5.0(2024-09-05 GA)이 들여온 SAI와 벡터 검색은 이미 2년 가까이 GA로 굴러가고 있습니다. 이쪽은 기대치만 정확히 잡으면 됩니다.

SAI(Storage-Attached Indexing)에 대해 공식 FAQ가 스스로 선을 긋습니다 — SAI는 엔터프라이즈 검색 엔진이 아니라 본질적으로 필터링 엔진입니다. 문자열 연산자는 등호와 CONTAINS 계열뿐이고 LIKE는 지원되지 않습니다. 인덱스 디스크 오버헤드는 비인덱스 데이터 대비 20~35%로 문서화돼 있고, 한 쿼리에서 SAI 인덱스를 셋 이상 AND로 엮으면 두 개까지만 인덱스로 처리하고 나머지는 후필터링입니다. 파티션 키 없는 쿼리는 여전히 스캐터-개더라서, 고카디널리티 컬럼 최악의 경우 클러스터 전체 스캔이 될 수 있다고 문서가 직접 경고합니다. SAI가 데이터 모델링의 기본 원칙(파티션 키 중심 설계)을 대체하는 게 아니라 보완하는 이유입니다.

벡터 검색은 JVector(DiskANN 계열 ANN 라이브러리) 기반으로, VECTOR 타입은 최대 8K(2의 13승) 차원, ANN 쿼리의 LIMIT은 1,000 이하여야 합니다. 유사도 함수는 코사인(기본)·내적·유클리드 세 가지인데, 문서가 적어 둔 함정 하나는 기억할 만합니다 — 내적이 더 빠르다지만(문서 주장 기준 50%), 정규화되지 않은 임베딩에 내적을 쓰면 조용히 무의미한 결과가 나옵니다. 인덱스 옵션은 만든 뒤 바꿀 수 없어서 드롭 후 재생성해야 합니다. 전용 벡터 DB를 대체한다기보다, 이미 Cassandra에 있는 데이터 옆에 임베딩을 두고 싶을 때의 선택지로 보는 게 맞습니다. 엔진별 비교는 2026년 데이터베이스 엔진 딥다이브에서 다뤘습니다.

그래서 언제부터 신경 써야 하나

지금 프로덕션이라면. 5.0.x에 머뭅니다. 4.0은 6.0 릴리스와 함께, 4.1은 7.0과 함께 지원이 끝나는 구조라(공식 다운로드 페이지 기준) 5.0으로의 업그레이드 압력은 이미 실재합니다. 6.0 업그레이드 계획에는 TCM 전환이라는 별도 운영 절차가 들어간다는 점을 미리 적어 두세요.

Accord를 테스트해 볼 가치가 있는 경우. LWT를 여러 파티션에 걸쳐 흉내 내느라 사가·배치 코드가 쌓인 워크로드, 그리고 단일 리전 또는 글로벌 QUORUM이 허용되는 지연 프로파일. 이런 팀이라면 알파에서 자기 워크로드의 충돌 패턴을 미리 재 보는 게 의미 있습니다. 단, 분기별 알파에는 지원도 백포트도 없습니다.

아직 신경 쓸 필요가 없는 경우. LOCAL_QUORUM으로 멀티 DC를 굴리는 워크로드(표현할 방법이 없습니다), 카운터 테이블 의존 워크로드(트랜잭션 불가), RDBMS식 대화형 트랜잭션을 기대하는 마이그레이션(원샷 모델입니다), 그리고 벤치마크 수치를 보고 결정하고 싶은 모든 경우 — 공식 수치가 아직 없으니 볼 것도 없습니다.

마치며

정리하면 이렇습니다. Accord는 2021년의 제안이 2026년에야 실행 가능한 형태로 도착한, 리더 없는 멀티 파티션 strict-serializable 트랜잭션이라는 야심적인 설계입니다. 6.0-alpha1에 코드는 실렸지만, 그 알파는 "빌드되는 걸 확인한 날짜 태그"에 가깝고, 릴리스 노트는 자리 표시자이며, 성능은 프로토콜 왕복 횟수 이상으로 말해 주는 공식 자료가 없습니다. 문법의 원샷 모델, LOCAL 일관성 수준 부재, 풀 리페어가 필요한 마이그레이션 — 이 세 가지가 현재 시점의 실질적인 경계선입니다.

거꾸로 말하면, 판단에 필요한 원자료가 전부 공개돼 있는 드문 시기이기도 합니다. CHANGES.txt와 인트리 문서, dev 리스트만으로 이만큼 그림이 그려집니다. 베타가 나오고 벤치마크가 실리기 시작할 때 다시 점검하겠습니다 — 그때까지 이 기능에 대한 의사결정은 발표 슬라이드가 아니라 위 문서들을 직접 읽고 하시길 권합니다.

참고 자료