HDFS 는 대용량 파일을 순차로 쓰고 여러 번 읽는 용도로 설계됐다. 파일은 한 번 쓰고 닫으면 내용을 바꾸지 않는 것이 기본이며, 나중에 덧붙이기(append)와 truncate 가 제한적으로 추가됐을 뿐 임의 위치 수정은 지원하지 않는다. 반면 ACID 는 레코드 단위의 갱신과 격리를 전제한다. 이 간극이 근본 원인이다.
레코드 단위 갱신이 없다. 한 행을 고치려면 그 행이 든 파일을 통째로 다시 써야 한다. 파일 단위 잠금이나 다중 버전 관리 같은 장치도 없다.
동시 쓰기가 제한된다. 하나의 파일은 한 번에 한 writer 만 연다. 여러 프로세스가 같은 파일을 동시에 갱신하는 모델 자체가 없다.
원자성의 단위가 크다. 파일 생성과 rename 은 NameNode 메타데이터 연산이라 원자적이지만, "여러 파일을 한 묶음으로 커밋"하는 연산은 없다. 잡이 중간에 죽으면 부분적으로 쓰인 파일이 남는다. 이를 피하려고 임시 경로에 쓰고 마지막에 rename 하는 방식을 널리 쓴다.
격리 수준이 없다. 읽는 쪽은 쓰는 중인 파일의 상태를 그대로 본다. 읽기 일관성을 보장하려면 애플리케이션이 디렉터리 전환이나 _SUCCESS 마커 같은 규약을 직접 만들어야 한다.
파일시스템 대신 테이블 형식 계층이 트랜잭션을 담당한다.
| 방식 | 처리 방법 |
|---|---|
| Hive ACID 테이블 | 베이스와 델타 디렉터리를 나눠 쓰고 compaction 으로 병합. ORC 기반 |
| Apache Iceberg | 스냅샷과 매니페스트로 원자적 커밋. 포맷 v2 는 행 단위 삭제 지원 |
| Apache Kudu | HDFS 를 쓰지 않는 별도 저장 엔진. 기본키 기반 갱신과 삭제 지원 |
| HBase | LSM 구조로 행 단위 갱신. 행 내 원자성 보장 |
어느 쪽이든 "HDFS 가 트랜잭션을 지원하게 만든다"기보다, 불변 파일 위에 메타데이터로 버전을 관리해 원자적 전환을 흉내 내는 방식이다. 커밋은 대개 메타데이터 포인터를 바꾸는 한 번의 연산으로 끝난다.
갱신과 삭제가 잦은 데이터를 HDFS 텍스트·Parquet 테이블에 그대로 올리면 결국 전체 재작성 배치를 만들게 된다. 요구사항에 갱신이 있으면 처음부터 Iceberg 나 Kudu 를 검토한다. 반대로 적재 후 변하지 않는 로그성 데이터라면 단순 파티션 구조가 가장 빠르고 운영이 쉽다.
오브젝트 스토리지(S3 호환)를 쓰면 제약이 하나 더 는다. rename 이 원자적이지 않아 "임시 경로에 쓰고 rename" 패턴이 성립하지 않으므로, 커밋 프로토콜을 지원하는 테이블 형식이 사실상 필수다.