TL;DR

  • ์„ธ ํฌ๋งท ๋ชจ๋‘ ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์˜ Parquet ํŒŒ์ผ ๋ฌถ์Œ์— ACIDยทtime travelยท์Šคํ‚ค๋งˆ ์ง„ํ™”๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ ˆ์ด์–ด
  • ๊ฐˆ๋ฆฌ๋Š” ์ง€์ ์€ ์ปค๋ฐ‹ ์›์ž์„ฑ์˜ ์œ„์น˜(Iceberg๋Š” ์นดํƒˆ๋กœ๊ทธ, Delta๋Š” ๋กœ๊ทธ ํŒŒ์ผ, Hudi๋Š” ํƒ€์ž„๋ผ์ธ+๋ฝ)์™€ ์—…๋ฐ์ดํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹
  • ์„ ํƒ ๊ธฐ์ค€์€ ๋ฒค์น˜๋งˆํฌ๊ฐ€ ์•„๋‹ˆ๋ผ ์—”์ง„ ๊ตฌ์„ฑ๊ณผ ์›Œํฌ๋กœ๋“œ ์„ฑ๊ฒฉ, ์นดํƒˆ๋กœ๊ทธ ์ „๋žต

AI-assisted


1. ์™œ ํ…Œ์ด๋ธ” ํฌ๋งท์ด ํ•„์š”ํ–ˆ๋‚˜

๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์— Parquet ํŒŒ์ผ์„ ์Œ“์•„๋‘๋ฉด ์ €์žฅ์€ ์‹ธ์ง€๋งŒ ํŒŒ์ผ ๋ฌถ์Œ๋งŒ์œผ๋กœ๋Š” ํ˜„์žฌ ํ…Œ์ด๋ธ” ์ƒํƒœ๋ฅผ ๊ธฐ๋กํ•˜์ง€ ๋ชปํ•œ๋‹ค. Hive ์‹œ์ ˆ์˜ ํ…Œ์ด๋ธ” ์ •์˜๊ฐ€ โ€œ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ ์•„๋ž˜ ์žˆ๋Š” ํŒŒ์ผ ์ „๋ถ€โ€์˜€๋˜ ํƒ“์— ์—ฌ๋Ÿฌ ๋ฌธ์ œ๊ฐ€ ๋”ฐ๋ผ์™”๋‹ค.

  • ์›์ž์„ฑ ์—†์Œ: ์“ฐ๊ธฐ ๋„์ค‘์— ์ฝ์œผ๋ฉด ์ ˆ๋ฐ˜๋งŒ ๋ฐ˜์˜๋œ ์ƒํƒœ๊ฐ€ ๋ณด์ธ๋‹ค
  • ํŒŒ์ผ ๋ชฉ๋ก ์Šค์บ” ๋น„์šฉ: ํŒŒํ‹ฐ์…˜์ด ์ˆ˜๋งŒ ๊ฐœ๋ฉด LIST ํ˜ธ์ถœ๋งŒ์œผ๋กœ query planning์ด ์ˆ˜ ๋ถ„ ๊ฑธ๋ฆฐ๋‹ค
  • ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€: ์ปฌ๋Ÿผ ์ด๋ฆ„์„ ๋ฐ”๊พธ๋ ค๋ฉด ์ „์ฒด๋ฅผ ๋‹ค์‹œ ์“ด๋‹ค
  • ํŒŒํ‹ฐ์…˜ ๊ฒฐํ•ฉ๋„: ํŒŒํ‹ฐ์…˜ ์ปฌ๋Ÿผ์„ ์ฟผ๋ฆฌ์— ๋ช…์‹œํ•˜์ง€ ์•Š์œผ๋ฉด ์ „์ฒด ์Šค์บ”์ด ๋œ๋‹ค
  • ๋กค๋ฐฑ ๋ถˆ๊ฐ€: ์ž˜๋ชป ์“ด ๋ฐฐ์น˜๋ฅผ ๋˜๋Œ๋ฆด ๋ฐฉ๋ฒ•์ด ์—†๋‹ค

LIST ํ˜ธ์ถœ: ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์˜ ๋ชฉ๋ก ์กฐํšŒ API

  • S3์˜ ListObjectsV2, GCS์˜ objects.list์ฒ˜๋Ÿผ ์ ‘๋‘์‚ฌ์— ํ•ด๋‹นํ•˜๋Š” ํ‚ค๋ฅผ ๋‚˜์—ดํ•˜๋Š” ์š”์ฒญ
  • ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์—๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๊ฐ€ ์‹ค์žฌํ•˜์ง€ ์•Š๊ณ  dt=2024-01-01/part-0.parquet ๊ฐ™์€ ํ‚ค๊ฐ€ ํ‰๋ฉด์œผ๋กœ ๋Š˜์–ด์„œ ์žˆ์„ ๋ฟ์ด๋ผ ํŒŒ์ผ ๋ชฉ๋ก์„ ์•Œ๋ ค๋ฉด ๋งค๋ฒˆ ์š”์ฒญ์ด ํ•„์š”
  • ํ•œ ๋ฒˆ์— 1,000๊ฐœ๊นŒ์ง€๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ ํŒŒ์ผ 10๋งŒ ๊ฐœ๋ฉด ์™•๋ณต 100ํšŒ. ํ˜ธ์ถœ๋‹น ์ˆ˜์‹ญ~์ˆ˜๋ฐฑ ms๊ฐ€ ๋ถ™๊ณ  ๋‹จ๊ฐ€๋„ GET๋ณด๋‹ค ๋†’๋‹ค
  • Hive๋Š” ์ฟผ๋ฆฌ๋ฅผ ๊ณ„ํšํ•  ๋•Œ๋งˆ๋‹ค ๋Œ€์ƒ ํŒŒํ‹ฐ์…˜ ๊ฒฝ๋กœ๋ฅผ ์ „๋ถ€ LISTํ–ˆ๋‹ค. ํŒŒํ‹ฐ์…˜์ด ๋Š˜๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ์‹œ์ž‘๋˜๊ธฐ๋„ ์ „์— ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๊ฐ™์ด ๋Š˜์–ด๋‚œ๋‹ค

์„ธ ํฌ๋งท ๋ชจ๋‘ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ์–ด๋А ์‹œ์ ์— ์–ด๋–ค ํŒŒ์ผ์ด ํ…Œ์ด๋ธ”์— ์†ํ•˜๋Š”์ง€๋ฅผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋กœ ๋”ฐ๋กœ ๊ธฐ๋กํ•œ๋‹ค.

์ฟผ๋ฆฌ ์—”์ง„ (Spark / Flink / Trino / Snowflake)
        โ†“
ํ…Œ์ด๋ธ” ํฌ๋งท ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ  โ† Iceberg / Delta Lake / Hudi
        โ†“
ํŒŒ์ผ ํฌ๋งท (Parquet / ORC / Avro)
        โ†“
์Šคํ† ๋ฆฌ์ง€ (S3 / GCS / ADLS / HDFS)

ํ…Œ์ด๋ธ” ํฌ๋งท: ํŒŒ์ผ ํฌ๋งท๊ณผ ๋‹ค๋ฅธ ๊ณ„์ธต

  • ํŒŒ์ผ ํฌ๋งท: ๋ฐ”์ดํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐฐ์น˜ํ• ์ง€. Parquet, ORC, Avro
  • ํ…Œ์ด๋ธ” ํฌ๋งท: ๊ทธ ํŒŒ์ผ์„ ๋ฌถ์–ด ํ…Œ์ด๋ธ”๋กœ ๋งŒ๋“œ๋Š” ๊ทœ์•ฝ. Iceberg, Delta, Hudi
    • ํ…Œ์ด๋ธ” ํฌ๋งท์€ ์ƒˆ ํŒŒ์ผ ํ˜•์‹์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. ๋Œ€๋ถ€๋ถ„ Parquet์„ ๊ทธ๋Œ€๋กœ ์“ด๋‹ค

2. ์„ธ ํฌ๋งท์˜ ์ถœ์‹ ๊ณผ ์„ค๊ณ„ ๋™๊ธฐ

๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ’€์—ˆ์ง€๋งŒ ์ถœ๋ฐœ์ ์ด ๋‹ฌ๋ž๊ณ  ๊ทธ ์ฐจ์ด๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ์„ค๊ณ„์— ๋‚จ์•„ ์žˆ๋‹ค.

๊ตฌ๋ถ„Apache IcebergDelta LakeApache Hudi
์ถœ์‹ Netflix, 2017Databricks, 2019Uber, 2016
์žฌ๋‹จApacheLinux FoundationApache
์ตœ์ดˆ ๋™๊ธฐํŽ˜ํƒ€๋ฐ”์ดํŠธ ํ…Œ์ด๋ธ”์˜ query planning ์ง€์—ฐSpark ํŒŒ์ดํ”„๋ผ์ธ์˜ ์‹ ๋ขฐ์„ฑCDC ๋ฐ์ดํ„ฐ์˜ ๋ ˆ์ฝ”๋“œ ๋‹จ์œ„ ๊ฐฑ์‹ 
์„ค๊ณ„ ์ค‘์‹ฌ์Šค์บ” ํšจ์œจ๊ณผ ์—”์ง„ ์ค‘๋ฆฝ์„ฑ๋‹จ์ˆœํ•จ๊ณผ Spark ํ†ตํ•ฉingestion ์ง€์—ฐ๊ณผ upsert ์ฒ˜๋ฆฌ๋Ÿ‰
  • Iceberg: Hive ํ…Œ์ด๋ธ”์ด ์ˆ˜์‹ญ๋งŒ ํŒŒํ‹ฐ์…˜์— ๋„๋‹ฌํ•˜๋ฉด์„œ ๋ฉ”ํƒ€์Šคํ† ์–ด๊ฐ€ ๋ณ‘๋ชฉ์ด ๋˜์ž ํŒŒ์ผ ๋ชฉ๋ก๊ณผ ํ†ต๊ณ„๋ฅผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์ผ์— ๋ฏธ๋ฆฌ ์ €์žฅํ•ด LIST ํ˜ธ์ถœ ์ž์ฒด๋ฅผ ์—†์•ด๋‹ค
  • Delta: Spark job์ด ์ค‘๊ฐ„์— ์‹คํŒจํ•˜๋ฉด ๋ถ€๋ถ„ ์ถœ๋ ฅ์ด ๋‚จ๋Š” ๋ฌธ์ œ์—์„œ ์ถœ๋ฐœํ–ˆ๋‹ค. ๋กœ๊ทธ๋Š” ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ณ  Spark์™€์˜ ๊ฒฐํ•ฉ์„ ์šฐ์„ ํ–ˆ๋‹ค
  • Hudi: Uber์˜ ํŠธ๋ฆฝ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ณ„์† ๊ฐฑ์‹ ๋˜๋Š” ์ƒํ™ฉ์ด ๋ฐฐ๊ฒฝ์ด๋ผ ๋ ˆ์ฝ”๋“œ ํ‚ค๋กœ ํŒŒ์ผ์„ ์ฐพ๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋„ฃ์—ˆ๋‹ค

๋น„์œ : ์„ธ ํฌ๋งท์€ ์„œ๋กœ ๋‹ค๋ฅธ ๋„์„œ๊ด€ ๊ด€๋ฆฌ๋ฒ•์ด๋‹ค

  • Iceberg: ์‚ฌ์„œ๊ฐ€ ๋ชฉ๋ก ์นด๋“œ๋ฅผ ๊ณ„์ธต์œผ๋กœ ๊ด€๋ฆฌํ•œ๋‹ค. ์–ด๋А ์ฑ…์ด ์–ด๋А ์„œ๊ฐ€์— ์žˆ๊ณ  ํŽ˜์ด์ง€ ๋ฒ”์œ„๊ฐ€ ์–ผ๋งˆ์ธ์ง€๊นŒ์ง€ ์นด๋“œ์— ์ ํ˜€ ์žˆ์–ด ์„œ๊ฐ€๋ฅผ ๋Œ ํ•„์š”๊ฐ€ ์—†๋‹ค
  • Delta: ์ž…์ถœ๊ณ  ์žฅ๋ถ€๋ฅผ ์‹œ๊ฐ„์ˆœ์œผ๋กœ ์ ๋Š”๋‹ค. ํ˜„์žฌ ์žฌ๊ณ ๋ฅผ ์•Œ๋ ค๋ฉด ์žฅ๋ถ€๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ฝ์–ด ๋‚ด๋ ค๊ฐ„๋‹ค. ๋Œ€์‹  ์ฃผ๊ธฐ์ ์œผ๋กœ ์žฌ๊ณ  ์Šค๋ƒ…์ƒท์„ ๋‚จ๊ธด๋‹ค
  • Hudi: ์ฑ…๋งˆ๋‹ค ๊ณ ์œ  ๋ฒˆํ˜ธ๋ฅผ ๋ถ™์ด๊ณ  ์ƒ‰์ธ์„ ์œ ์ง€ํ•œ๋‹ค. ๊ฐ™์€ ๋ฒˆํ˜ธ์˜ ๊ฐœ์ •ํŒ์ด ๋“ค์–ด์˜ค๋ฉด ์ƒ‰์ธ์œผ๋กœ ์›๋ณธ์„ ์ฐพ์•„ ๋ฐ”๋กœ ๊ต์ฒดํ•œ๋‹ค

3. ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ตฌ์กฐ

์„ธ ํฌ๋งท์€ ํ…Œ์ด๋ธ”์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ๊ธฐ๋กํ•œ๋‹ค.

  • Iceberg: manifest ํŠธ๋ฆฌ
  • Delta Lake: ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ
  • Hudi: ํƒ€์ž„๋ผ์ธ๊ณผ ํŒŒ์ผ ๊ทธ๋ฃน

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์Šคํ† ๋ฆฌ์ง€์— ํŒŒ์ผ๋กœ ์Œ“๋Š”๋‹ค๋Š” ์ ์€ ์…‹์ด ๊ฐ™๋‹ค. ์ตœ์‹  ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋Š” ์œ„์น˜๋Š” ํฌ๋งท๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค.

3.1 Iceberg: manifest ํŠธ๋ฆฌ

์นดํƒˆ๋กœ๊ทธ (Hive Metastore / Glue / REST ...)
โ””โ”€ analytics.orders โ”€โ†’ s3://lake/db/orders/metadata/00002-def.metadata.json
                       ํ˜„์žฌ ์Šค๋ƒ…์ƒท ํฌ์ธํ„ฐ. ์ปค๋ฐ‹๋งˆ๋‹ค ์ด ๊ฐ’์ด ๋ฐ”๋€๋‹ค
 
s3://lake/db/orders/
โ”œโ”€ metadata/
โ”‚  โ”œโ”€ 00001-abc.metadata.json      ์ด์ „ ๋ฒ„์ „
โ”‚  โ”œโ”€ 00002-def.metadata.json      โ† ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ˜„์žฌ ๋ฒ„์ „
โ”‚  โ”‚                               ์Šคํ‚ค๋งˆ, ํŒŒํ‹ฐ์…˜ ์ŠคํŽ™, ์ •๋ ฌ ์ˆœ์„œ, ์Šค๋ƒ…์ƒท ๋ชฉ๋ก
โ”‚  โ”œโ”€ snap-8901-1-xyz.avro         manifest list: manifest file ๋ชฉ๋ก + ํŒŒํ‹ฐ์…˜ ๋ฒ”์œ„
โ”‚  โ””โ”€ xyz-m0.avro                  manifest file: ๋ฐ์ดํ„ฐ ํŒŒ์ผ ๋ชฉ๋ก + ์ปฌ๋Ÿผ ํ†ต๊ณ„
โ””โ”€ data/
   โ””โ”€ dt=2026-08-05/
      โ””โ”€ 00000-0-abc.parquet
  • 3๋‹จ ํŠธ๋ฆฌ: metadata.json โ†’ manifest list โ†’ manifest file ์ˆœ์œผ๋กœ ๋‚ด๋ ค๊ฐ„๋‹ค. ์ƒ์œ„ ๋…ธ๋“œ์— ํ•˜์œ„ ๋ฒ”์œ„ ์š”์•ฝ์ด ๋“ค์–ด ์žˆ์–ด ์œ„์—์„œ๋ถ€ํ„ฐ ๊ฐ€์ง€์น˜๊ธฐ๊ฐ€ ๋œ๋‹ค
  • ํŒŒ์ผ๋ณ„ ํ†ต๊ณ„: ์ปฌ๋Ÿผ๋งˆ๋‹ค min/max, null ๊ฐœ์ˆ˜, ๊ฐ’ ๊ฐœ์ˆ˜๋ฅผ manifest์— ์ €์žฅํ•œ๋‹ค. WHERE amount > 1000์—์„œ ํŒŒ์ผ์˜ max๊ฐ€ 1000 ์ดํ•˜์ด๋ฉด ํ†ต๊ณ„๋งŒ ๋ณด๊ณ  ๊ทธ ํŒŒ์ผ์„ ๊ฑด๋„ˆ๋›ด๋‹ค
  • ๋ถˆ๋ณ€: ์ปค๋ฐ‹ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ metadata.json์„ ์“ด๋‹ค. ๊ธฐ์กด ํŒŒ์ผ์€ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค
  • ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ํ•„์ˆ˜: metadata/์— ์—ฌ๋Ÿฌ ๋ฒ„์ „์ด ์Œ“์—ฌ ์žˆ์–ด๋„ ํŒŒ์ผ ๋ชฉ๋ก๋งŒ์œผ๋กœ๋Š” ์–ด๋А ๊ฒƒ์ด ํ˜„์žฌ์ธ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค. ์ปค๋ฐ‹์— ์‹คํŒจํ•ด ๋ฒ„๋ ค์ง„ ํŒŒ์ผ๋„ ์„ž์—ฌ ์žˆ๋‹ค

3.2 Delta Lake: ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ

s3://lake/orders/
โ”œโ”€ _delta_log/
โ”‚  โ”œโ”€ 00000000000000000000.json                 Action ๋ชฉ๋ก
โ”‚  โ”œโ”€ 00000000000000000001.json
โ”‚  โ”œโ”€ ...
โ”‚  โ”œโ”€ 00000000000000000010.checkpoint.parquet   10์ปค๋ฐ‹๋งˆ๋‹ค ์ „์ฒด ์ƒํƒœ
โ”‚  โ””โ”€ _last_checkpoint                          ์ตœ์‹  ์ฒดํฌํฌ์ธํŠธ ์œ„์น˜
โ””โ”€ part-00000-....snappy.parquet

๊ฐ JSON์€ ์ƒํƒœ ์ „์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ณ€๊ฒฝ๋ถ„์„ ๋‹ด๋Š”๋‹ค.

{"add":{"path":"part-00003-....parquet","partitionValues":{},"size":1048576,"modificationTime":1754000000000,"dataChange":true,"stats":"{\"numRecords\":5000,\"minValues\":{\"id\":1}}"}}
{"remove":{"path":"part-00001-....parquet","deletionTimestamp":1754000000000,"dataChange":true}}
  • ํ˜„์žฌ ์ƒํƒœ = ์ฒดํฌํฌ์ธํŠธ + ์ดํ›„ JSON ์žฌ์ƒ: ๋กœ๊ทธ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ์ ์šฉํ•ด ํŒŒ์ผ ๋ชฉ๋ก์„ ๋งŒ๋“ ๋‹ค
  • ๊ฒฝ๋กœ๋กœ ์ตœ์‹  ์ƒํƒœ ํ™•์ธ: _delta_log/๋ฅผ ๋‚˜์—ดํ•ด ๋ฒˆํ˜ธ๊ฐ€ ๊ฐ€์žฅ ํฐ JSON์„ ์ฐพ์œผ๋ฉด ์ตœ์‹  ์ปค๋ฐ‹์ด๋‹ค. ์นดํƒˆ๋กœ๊ทธ ์—†์ด ๊ฒฝ๋กœ๋งŒ์œผ๋กœ ์ฝํžŒ๋‹ค
  • ๊ตฌ์กฐ๊ฐ€ ์–•๋‹ค: ํŠธ๋ฆฌ๋ฅผ ํƒ€์ง€ ์•Š๋Š”๋‹ค. ์ปค๋ฐ‹์ด ๋งŽ์ด ์Œ“์ด๋ฉด ๋กœ๊ทธ ์žฌ์ƒ ๋น„์šฉ์ด ์ƒ๊ธด๋‹ค

3.3 Hudi: ํƒ€์ž„๋ผ์ธ๊ณผ ํŒŒ์ผ ๊ทธ๋ฃน

s3://lake/orders/
โ”œโ”€ .hoodie/
โ”‚  โ”œโ”€ hoodie.properties
โ”‚  โ”œโ”€ 20260805120000.commit                ํƒ€์ž„๋ผ์ธ instant
โ”‚  โ”œโ”€ 20260805121500.deltacommit
โ”‚  โ”œโ”€ 20260805130000.compaction.requested
โ”‚  โ””โ”€ metadata/                            ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” (๊ทธ ์ž์ฒด๊ฐ€ Hudi ํ…Œ์ด๋ธ”)
โ””โ”€ 2026/08/05/
   โ”œโ”€ fileId-1_20260805120000.parquet      base file
   โ””โ”€ .fileId-1_20260805121500.log.1       log file (MOR)
  • ํƒ€์ž„๋ผ์ธ: ๋ชจ๋“  ๋™์ž‘์ด instant๋กœ ๊ธฐ๋ก๋œ๋‹ค. ์ƒํƒœ๋Š” requested โ†’ inflight โ†’ completed๋กœ ์ง„ํ–‰ํ•œ๋‹ค. ํƒ€์ž„์Šคํƒฌํ”„๊ฐ€ ๊ฐ€์žฅ ํฐ ์™„๋ฃŒ instant๊ฐ€ ํ˜„์žฌ ์ƒํƒœ๋ผ ์นดํƒˆ๋กœ๊ทธ ์—†์ด ์ฝํžŒ๋‹ค
  • ํŒŒ์ผ ๊ทธ๋ฃน: ๋ ˆ์ฝ”๋“œ ํ‚ค๊ฐ€ ํŠน์ • ํŒŒ์ผ ๊ทธ๋ฃน์— ๊ณ ์ • ๋งคํ•‘๋œ๋‹ค. ๊ฐ™์€ ํ‚ค์˜ ๊ฐฑ์‹ ์€ ํ•ญ์ƒ ๊ฐ™์€ ๊ทธ๋ฃน์œผ๋กœ ๊ฐ„๋‹ค
  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”: ํŒŒ์ผ ๋ชฉ๋ก, ์ปฌ๋Ÿผ ํ†ต๊ณ„, ๋ ˆ์ฝ”๋“œ ์ธ๋ฑ์Šค๋ฅผ ๋ณ„๋„ ๋‚ด๋ถ€ ํ…Œ์ด๋ธ”๋กœ ๊ด€๋ฆฌํ•œ๋‹ค

File Group๊ณผ File Slice: Hudi ๊ณ ์œ  ๊ฐœ๋…

  • File Group: ๊ฐ™์€ fileId๋ฅผ ๊ณต์œ ํ•˜๋Š” ํŒŒ์ผ ๋ฌถ์Œ. ๋ ˆ์ฝ”๋“œ ํ‚ค์˜ ์†Œ์† ๋‹จ์œ„
  • File Slice: ํ•˜๋‚˜์˜ base file + ๊ทธ์— ๋”ธ๋ฆฐ log file. ์ปค๋ฐ‹ ์‹œ์ ๋งˆ๋‹ค ์ƒˆ file slice๊ฐ€ ์ƒ๊ธด๋‹ค
  • ์ด ๊ตฌ์กฐ์—์„œ โ€œ์ด ํ‚ค๋ฅผ ๊ฐฑ์‹ ํ•˜๋ ค๋ฉด ์–ด๋А ํŒŒ์ผ์„ ๊ฑด๋“œ๋ ค์•ผ ํ•˜๋Š”์ง€โ€๊ฐ€ ์ •ํ•ด์ง„๋‹ค

์นดํƒˆ๋กœ๊ทธ: ํฌ๋งท๋ณ„ ์—ญํ• 

  • Iceberg: ํ˜„์žฌ ์Šค๋ƒ…์ƒท ํฌ์ธํ„ฐ๋ฅผ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ๋“ค๊ณ  ์žˆ๋‹ค. ์นดํƒˆ๋กœ๊ทธ ์ ‘์† ์ •๋ณด ์—†์ด๋Š” ํ…Œ์ด๋ธ”์„ ์—ด ์ˆ˜ ์—†๋‹ค
  • DeltaยทHudi: ํ˜„์žฌ ์ƒํƒœ ์ •๋ณด๊ฐ€ ์Šคํ† ๋ฆฌ์ง€์— ์žˆ๋‹ค. ์นดํƒˆ๋กœ๊ทธ๋Š” ์ด๋ฆ„๊ณผ ๊ถŒํ•œ์„ ๋ถ™์ด๋Š” ์šฉ๋„๋ผ ์ง€์›Œ๋„ ๊ฒฝ๋กœ๋กœ ๋‹ค์‹œ ์ฝํžŒ๋‹ค
  • DeltaยทHudi๋„ ์ด๋ฆ„์œผ๋กœ ์ฐธ์กฐํ•˜๊ณ  ํ…Œ์ด๋ธ” ๋‹จ์œ„๋กœ ๊ถŒํ•œ์„ ๊ฑธ๊ณ  AthenaยทTrino๊ฐ€ ํ…Œ์ด๋ธ”์„ ์ฐพ๊ฒŒ ํ•˜๋ ค๋ฉด ์นดํƒˆ๋กœ๊ทธ์— ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค

4. ์ปค๋ฐ‹๊ณผ ๋™์‹œ์„ฑ (์›์ž์„ฑ์„ ๋ˆ„๊ฐ€ ๋ณด์žฅํ•˜๋Š”๊ฐ€)

4.1 ๊ฐ™์€ ์ƒํ™ฉ์„ ์…‹์— ๋†“๊ณ  ๋ณธ๋‹ค

๋ฐฐ์น˜ ๋‘ ๊ฐœ๊ฐ€ ๊ฐ™์€ ํ…Œ์ด๋ธ”์— ๋™์‹œ์— ์“ฐ๋Š” ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•œ๋‹ค.

  • 09:00 ๋ฐฐ์น˜ A: ์–ด์ œ ์ฃผ๋ฌธ 1๋งŒ ๊ฑด์„ orders ํ…Œ์ด๋ธ”์— ์ถ”๊ฐ€
  • 09:00 ๋ฐฐ์น˜ B: ๋ˆ„๋ฝ๋ถ„ ์žฌ์ฒ˜๋ฆฌ. ๊ฐ™์€ ํ…Œ์ด๋ธ”์— 5์ฒœ ๊ฑด ์ถ”๊ฐ€
  • ๊ณตํ†ต ์‹œ์ž‘์ : ๋‘˜ ๋‹ค 09:00 ์‹œ์ ์˜ ํ…Œ์ด๋ธ” ์ƒํƒœ๋ฅผ ์ฝ๊ณ  ๊ฐ์ž ์ผ์„ ์‹œ์ž‘ํ–ˆ๋‹ค

์„ธ ํฌ๋งท์€ ๋‹ค์Œ ์ ˆ์ฐจ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

  1. ํ˜„์žฌ ํ…Œ์ด๋ธ” ์ƒํƒœ๋ฅผ ์ฝ๋Š”๋‹ค
  2. ๊ฐ์ž Parquet ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์Šคํ† ๋ฆฌ์ง€์— ์“ด๋‹ค. ์ด ๋‹จ๊ณ„๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค
  3. ๋งˆ์ง€๋ง‰์— ์ƒˆ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ํ…Œ์ด๋ธ” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ๊ธฐ๋กํ•œ๋‹ค

์ฐจ์ด๋Š” 3๋ฒˆ์—์„œ ์ƒ๊ธด๋‹ค. ์„ธ ํฌ๋งท์€ ์ปค๋ฐ‹์„ ์„œ๋กœ ๋‹ค๋ฅธ ์œ„์น˜์™€ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.

multi-writer: ํ•œ ํ…Œ์ด๋ธ”์— ๋‘˜ ์ด์ƒ์ด ๋™์‹œ์— ์“ฐ๋Š” ์ƒํ™ฉ

  • ์ŠคํŠธ๋ฆฌ๋ฐ ingestion์ด ๊ณ„์† ์“ฐ๋Š” ์ค‘์— ๋ฐฐ์น˜ backfill์ด ๊ฐ™์€ ํ…Œ์ด๋ธ”์— ๋“ค์–ด์˜ฌ ๋•Œ
  • compaction์ด๋‚˜ cleanup job์ด ingestion๊ณผ ์‹œ๊ฐ„๋Œ€๊ฐ€ ๊ฒน์น  ๋•Œ
  • ํŒ€์ด ์—ฌ๋Ÿฟ์ด๋ผ ์„œ๋กœ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๊ฐ™์€ ํ…Œ์ด๋ธ”์„ ๊ฐฑ์‹ ํ•  ๋•Œ
  • writer๊ฐ€ ํ•˜๋‚˜๋ฟ์ด๋ฉด ์•„๋ž˜์˜ ์ปค๋ฐ‹ ๊ฒฝ์Ÿ์€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š”๋‹ค. ๋‹ค๋งŒ compaction ๊ฐ™์€ table service๋Š” ๋ณ„๋„ ํ–‰์œ„์ž๋ผ ๊ทธ์ชฝ ์ถฉ๋Œ์€ ๋‚จ๋Š”๋‹ค

์…‹ ๋‹ค ๋‚™๊ด€์  ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์“ด๋‹ค

  • ๊ฐ writer๊ฐ€ ์ž‘์—…ํ•œ ๋’ค ์ปค๋ฐ‹ ์ง์ „์— ๋‹ค๋ฅธ ์ปค๋ฐ‹๊ณผ ์ถฉ๋Œํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค
  • ๋ฐฐ์น˜ job ์‚ฌ์ด์˜ ์ถฉ๋Œ์ด ๋“œ๋ฌผ๋ฉด ์ถฉ๋Œ๋กœ ๋‹ค์‹œ ์ฒ˜๋ฆฌํ•  ์ž‘์—…๋„ ์ ๋‹ค
  • Iceberg๋Š” ์นดํƒˆ๋กœ๊ทธ์˜ ํฌ์ธํ„ฐ ๊ต์ฒด, Delta๋Š” ๋กœ๊ทธ ํŒŒ์ผ์˜ ์กฐ๊ฑด๋ถ€ ์ƒ์„ฑ, Hudi์˜ OCC ๋ชจ๋“œ๋Š” ์ปค๋ฐ‹ ๋ฝ์œผ๋กœ ๋งˆ์ง€๋ง‰ ๊ธฐ๋ก์„ ์กฐ์ •ํ•œ๋‹ค

์ฝ๊ธฐ ์ถฉ๋Œ์€ ์ด๋ฏธ ํ’€๋ ค ์žˆ๋‹ค

  • ์„ธ ํฌ๋งท ๋ชจ๋‘ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ๋ฎ์–ด์“ฐ์ง€ ์•Š๊ณ  ์ƒˆ๋กœ ์Œ“๋Š”๋‹ค. ์ฝ๋Š” ์ชฝ์€ ์ž๊ธฐ๊ฐ€ ์žก์€ ์Šค๋ƒ…์ƒท์„ ๊ณ„์† ๋ณธ๋‹ค
  • reader๋Š” ํŠน์ • ๋ฒ„์ „์„ ๊ณ„์† ์ฝ๋Š”๋‹ค. ์ดํ›„ ์„ค๋ช…์€ writer โ†” writer์— ์ง‘์ค‘ํ•œ๋‹ค
ํฌ๋งทreader โ†” writerwriter โ†” writer
Iceberg์Šค๋ƒ…์ƒท์นดํƒˆ๋กœ๊ทธ CAS
Delta๋ฒ„์ „๋ณ„ ๋กœ๊ทธ๋กœ๊ทธ ํŒŒ์ผ ์ด๋ฆ„ ์„ ์ 
Hudiํƒ€์ž„๋ผ์ธ instantOCC + ์™ธ๋ถ€ lock provider

4.2 Iceberg: ์นดํƒˆ๋กœ๊ทธ์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ”๊พผ๋‹ค

์นดํƒˆ๋กœ๊ทธ๋Š” ํ˜„์žฌ metadata.json์˜ ์œ„์น˜๋ฅผ ํฌ์ธํ„ฐ๋กœ ์ €์žฅํ•œ๋‹ค. ์ปค๋ฐ‹์€ ๊ทธ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ”๊พธ๋Š” ์ผ์ด๋‹ค.

sequenceDiagram
    participant A as ๋ฐฐ์น˜ A
    participant C as ์นดํƒˆ๋กœ๊ทธ
    participant B as ๋ฐฐ์น˜ B
    A->>C: ํ˜„์žฌ ํฌ์ธํ„ฐ ์กฐํšŒ
    C-->>A: v3
    B->>C: ํ˜„์žฌ ํฌ์ธํ„ฐ ์กฐํšŒ
    C-->>B: v3
    Note over A,B: ๊ฐ์ž parquet๊ณผ manifest, v4.json ์ž‘์„ฑ
    A->>C: ์•„์ง v3๋ฉด v4๋กœ ๋ฐ”๊ฟ”๋ผ
    C-->>A: ์„ฑ๊ณต. ํฌ์ธํ„ฐ๋Š” v4
    B->>C: ์•„์ง v3๋ฉด v4๋กœ ๋ฐ”๊ฟ”๋ผ
    C-->>B: ์‹คํŒจ. ํ˜„์žฌ๊ฐ’์€ v4
    Note over B: ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ <br/>v4 ๊ธฐ์ค€์œผ๋กœ manifest๋งŒ ๋‹ค์‹œ ์ž‘์„ฑ
    B->>C: ์•„์ง v4๋ฉด v5๋กœ ๋ฐ”๊ฟ”๋ผ
    C-->>B: ์„ฑ๊ณต. ํฌ์ธํ„ฐ๋Š” v5
  • B์˜ Parquet ํŒŒ์ผ์€ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค: ์ด๋ฏธ ์Šคํ† ๋ฆฌ์ง€์— ์“ด ๋ฐ์ดํ„ฐ๋Š” ๊ทธ๋Œ€๋กœ ๋‘๊ณ  manifest๋งŒ ์ƒˆ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์‹œ ๋งŒ๋“ ๋‹ค. ๊ทธ๋ž˜์„œ ์žฌ์‹œ๋„ ๋น„์šฉ์ด ๋‚ฎ๋‹ค
  • ์ปค๋ฐ‹ ์›์ž์„ฑ์€ ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ์กฐ์ •ํ•œ๋‹ค: ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ํ˜„์žฌ metadata.json ํฌ์ธํ„ฐ์˜ ๊ต์ฒด๋ฅผ ์กฐ์ •ํ•œ๋‹ค
  • ๋Œ€์‹  ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ์—†์œผ๋ฉด ํ…Œ์ด๋ธ”์ด ์„ฑ๋ฆฝํ•˜์ง€ ์•Š๋Š”๋‹ค

์ปค๋ฐ‹ ๊ฒ€์ฆ: ํฌ์ธํ„ฐ ๋น„๊ต์™€ ์ถฉ๋Œ ํŒ์ •

  • CAS๋Š” ํฌ์ธํ„ฐ ๊ฐ’๋งŒ ๋น„๊ตํ•œ๋‹ค. ํฌ์ธํ„ฐ๋Š” ํ…Œ์ด๋ธ”์— ํ•˜๋‚˜๋ฟ์ด๋ผ ๋‹ค๋ฅธ ํŒŒํ‹ฐ์…˜์— appendํ•œ ์ปค๋ฐ‹์—๋„ ์‹คํŒจํ•œ๋‹ค
  • ๊ทธ๋ž˜์„œ ์žฌ์‹œ๋„ํ•  ๋•Œ ์ƒˆ base๋ฅผ ์ฝ๊ณ  ๊ทธ ์ปค๋ฐ‹์ด ์ž๊ธฐ์™€ ์‹ค์ œ๋กœ ์ถฉ๋Œํ•˜๋Š”์ง€ ํ•œ ๋ฒˆ ๋” ํŒ์ •ํ•œ๋‹ค. ๋‘˜ ๋‹ค append๋ฉด ์ถฉ๋Œ์ด ์•„๋‹ˆ๋ผ manifest๋งŒ ๋‹ค์‹œ ๋งŒ๋“ค๊ณ  ๋„˜์–ด๊ฐ„๋‹ค
  • ์ด ํŒ์ • ๊ธฐ์ค€์€ ์„ค์ •์œผ๋กœ ์ •ํ•œ๋‹ค
์†์„ฑ๊ธฐ๋ณธ๊ฐ’ํ—ˆ์šฉ ๊ฐ’/์˜๋ฏธ
write.delete.isolation-levelserializableserializable ๋˜๋Š” snapshot
write.update.isolation-levelserializableใ€ƒ
write.merge.isolation-levelserializableใ€ƒ
commit.retry.num-retries4์žฌ์‹œ๋„ ํšŸ์ˆ˜
  • serializable์€ ๋‚ด ํ•„ํ„ฐ์— ๋งž๋Š” ํŒŒ์ผ์ด ๊ทธ์‚ฌ์ด ์ถ”๊ฐ€๋์œผ๋ฉด ์‹คํŒจ์‹œํ‚ค๊ณ  snapshot์€ ๊ฐ™์€ ํŒŒ์ผ์ด ์ง€์›Œ์กŒ์„ ๋•Œ๋งŒ ์‹คํŒจ์‹œํ‚จ๋‹ค

์นดํƒˆ๋กœ๊ทธ CAS: metadata ํฌ์ธํ„ฐ์˜ ์กฐ๊ฑด๋ถ€ ๊ต์ฒด

  • Iceberg๋Š” CAS๋กœ ํ˜„์žฌ metadata ํฌ์ธํ„ฐ๊ฐ€ writer๊ฐ€ ์ฝ์—ˆ๋˜ ๊ฐ’๊ณผ ๊ฐ™์„ ๋•Œ๋งŒ ์ƒˆ metadata ํŒŒ์ผ์„ ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๊ต์ฒดํ•œ๋‹ค

4.3 Delta: ๋กœ๊ทธ ํŒŒ์ผ ์ด๋ฆ„์„ ์„ ์ ํ•œ๋‹ค

_delta_log/ ์•„๋ž˜ ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ง„ JSON์„ ์Œ“๋Š” ๊ตฌ์กฐ๋ผ ์ปค๋ฐ‹์€ ๋‹ค์Œ ๋ฒˆํ˜ธ์˜ ๋กœ๊ทธ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ์ผ์ด๋‹ค.

sequenceDiagram
    participant A as ๋ฐฐ์น˜ A
    participant L as _delta_log/
    participant B as ๋ฐฐ์น˜ B
    A->>L: ์ตœ์‹  ๋กœ๊ทธ ๋ฒˆํ˜ธ ์กฐํšŒ
    L-->>A: 002
    B->>L: ์ตœ์‹  ๋กœ๊ทธ ๋ฒˆํ˜ธ ์กฐํšŒ
    L-->>B: 002
    Note over A,B: ๊ฐ์ž parquet ์ž‘์„ฑ
    A->>L: 003.json ์—†์œผ๋ฉด ์“ฐ๊ธฐ
    L-->>A: ์„ฑ๊ณต
    B->>L: 003.json ์—†์œผ๋ฉด ์“ฐ๊ธฐ
    L-->>B: ์‹คํŒจ. ์ด๋ฏธ ์žˆ์Œ
    B->>L: 003.json ์ฝ๊ธฐ
    L-->>B: A์˜ ๋ณ€๊ฒฝ๋ถ„
    Note over B: ๋‘˜ ๋‹ค ์ถ”๊ฐ€๋ผ ์ถฉ๋Œ ์•„๋‹˜<br/>๋ฒˆํ˜ธ๋งŒ ๋ฐ€์–ด ์žฌ์‹œ๋„
    B->>L: 004.json ์—†์œผ๋ฉด ์“ฐ๊ธฐ
    L-->>B: ์„ฑ๊ณต
  • ์ถฉ๋Œ ๊ฒ€์‚ฌ๊ฐ€ ํ•œ ๋‹จ๊ณ„ ๋” ์žˆ๋‹ค: B๋Š” ์ž๊ธฐ๊ฐ€ ์ฝ์€ ๋’ค ๋“ค์–ด์˜จ 003.json์„ ์—ด์–ด๋ณธ๋‹ค. ๋‘˜ ๋‹ค append๋ฉด ๋ฒˆํ˜ธ๋งŒ ๋ฐ€์–ด ์žฌ์‹œ๋„ํ•œ๋‹ค. A๊ฐ€ ์ง€์šด ํŒŒ์ผ์„ B๋„ ์ง€์šฐ๋ ค ํ–ˆ๋‹ค๋ฉด ์‹ค์ œ ์ถฉ๋Œ์ด๋ผ ์‹คํŒจํ•œ๋‹ค
  • ์นดํƒˆ๋กœ๊ทธ๊ฐ€ ํ•„์š” ์—†๋‹ค: ์ตœ์‹  ์ปค๋ฐ‹์„ ์•Œ๋ ค๋ฉด _delta_log/๋ฅผ ๋‚˜์—ดํ•ด ๊ฐ€์žฅ ํฐ ๋ฒˆํ˜ธ๋ฅผ ์ฐพ์œผ๋ฉด ๋œ๋‹ค

PUT-if-absent: ์—†์„ ๋•Œ๋งŒ ์จ๋ผ

  • โ€œ์ด ์ด๋ฆ„์˜ ํŒŒ์ผ์ด ์•„์ง ์—†์œผ๋ฉด ๋งŒ๋“ ๋‹ค. ์ด๋ฏธ ์žˆ์œผ๋ฉด ์‹คํŒจํ•œ๋‹คโ€๋ฅผ ์ชผ๊ฐค ์ˆ˜ ์—†๋Š” ํ•œ ๋™์ž‘์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค
  • Unix์˜ open(O_CREAT|O_EXCL)๊ณผ HTTP์˜ If-None-Match: *๋Š” ๋Œ€์ƒ์ด ์—†์„ ๋•Œ๋งŒ ์ƒ์„ฑํ•˜๋Š” ์กฐ๊ฑด์„ ์ง€์ •ํ•˜๋Š” ์˜ˆ๋‹ค
  • CAS์™€ ๋ฐœ์ƒ์€ ๊ฐ™๊ณ  ๋น„๊ต ๋Œ€์ƒ๋งŒ ๋‹ค๋ฅด๋‹ค. CAS๋Š” ๊ฐ’์„ ๋ณด๊ณ  ์ด์ชฝ์€ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๋ณธ๋‹ค

์ฃผ์˜: S3 multi-writer Delta ํ…Œ์ด๋ธ”

  • ์ด ๋ฐฉ์‹์€ ์Šคํ† ๋ฆฌ์ง€๊ฐ€ โ€œ์—†์„ ๋•Œ๋งŒ ์“ฐ๊ธฐโ€๋ฅผ ์›์ž์ ์œผ๋กœ ๋ณด์žฅํ•ด์•ผ ์„ฑ๋ฆฝํ•œ๋‹ค
  • HDFS์™€ ADLS๋Š” ํŒŒ์ผ ์‹œ์Šคํ…œ ์ˆ˜์ค€์˜ ์›์ž์  ๋™์ž‘์„ ์ œ๊ณตํ•ด ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค. S3์—๋Š” ์˜ค๋ž˜๋„๋ก ์ด ๊ธฐ๋Šฅ์ด ์—†์–ด์„œ ๋‘ ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ๊ฐ™์€ 003.json์„ ์“ฐ๋ฉด ์ด์ „ ์ปค๋ฐ‹ ๋กœ๊ทธ๊ฐ€ ๋ฎ์–ด์จ์งˆ ์ˆ˜ ์žˆ์—ˆ๋‹ค
  • ๊ทธ๋ž˜์„œ S3DynamoDBLogStore๋กœ DynamoDB์— ๋ฝ ํ…Œ์ด๋ธ”์„ ๋‘๋Š” ๊ตฌ์„ฑ์ด ํ•„์š”ํ–ˆ๋‹ค
  • S3๊ฐ€ If-None-Match ์กฐ๊ฑด๋ถ€ ์“ฐ๊ธฐ๋ฅผ ์ง€์›ํ•˜๋ฉด์„œ ์ œ์•ฝ์ด ํ’€๋ ธ์ง€๋งŒ ์šด์˜ ์ค‘์ธ Delta ๋ฒ„์ „์ด ์ด๋ฅผ ์“ฐ๋Š”์ง€ ํ™•์ธ์ด ํ•„์š”ํ•˜๋‹ค
  • ๋‹จ์ผ Spark ํด๋Ÿฌ์Šคํ„ฐ๋งŒ ์“ฐ๋Š” ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค

ADLS: Azure Data Lake Storage

  • Azure์˜ ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ์œ„์— ๊ณ„์ธต์  ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์–น์€ ๊ฒƒ์ด๋ผ ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ rename์ด ์‹ค์žฌํ•œ๋‹ค
  • ADLS์˜ ์›์ž์  rename: ๊ณ„์ธต์  ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ADLS์—์„œ๋Š” ๊ฐ™์€ ํŒŒ์ผ ์‹œ์Šคํ…œ ์•ˆ์˜ rename์„ ์›์ž์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ž„์‹œ ๊ฒฝ๋กœ์— ํŒŒ์ผ์„ ๋‹ค ์“ด ๋’ค ์ตœ์ข… ๊ฒฝ๋กœ๋กœ renameํ•ด ๊ณต๊ฐœํ•œ๋‹ค
  • S3์—๋Š” rename์ด ์—†๋‹ค. ๋ณต์‚ฌ ํ›„ ์‚ญ์ œ๋ผ ํŒŒ์ผ ์ˆ˜๋งŒํผ ๋น„์šฉ์ด ๋ถ™๊ณ  ์ค‘๊ฐ„์— ์‹คํŒจํ•˜๋ฉด ๋ถ€๋ถ„ ์™„๋ฃŒ ์ƒํƒœ๊ฐ€ ๋‚จ๋Š”๋‹ค
  • HDFS๋„ ์›์ž์  rename์„ ์ œ๊ณตํ•œ๋‹ค

4.4 Hudi: ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ๋ฝ ๋ฐ–์—์„œ ์“ฐ๊ณ  ์ปค๋ฐ‹๋งŒ ๋ฝ ์•ˆ์—์„œ ์ฒ˜๋ฆฌํ•œ๋‹ค

๊ธฐ๋ณธ ๊ฐ€์ •์ด ๋‹จ์ผ writer๋‹ค. ๋‹ค๋งŒ ๋‹จ์ผ writer ๋ชจ๋“œ์—์„œ๋„ ๋™์‹œ์„ฑ ์ œ์–ด๋Š” ์ด๋ฏธ ๋Œ๊ณ  ์žˆ๋‹ค. ingestion writer์™€ ๋ณ„๋„๋กœ compactionยทclusteringยทcleaning ๊ฐ™์€ table service๊ฐ€ ๊ฐ™์€ ํ…Œ์ด๋ธ”์„ ๊ฑด๋“œ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

reader๋Š” ์ฝ๊ธฐ ์‹œ์ž‘ ์‹œ์ ์˜ ํŒŒ์ผ ๋ฒ„์ „์„ ์ฐธ์กฐํ•˜๊ณ  writer๋Š” ์ƒˆ ๋ฒ„์ „์„ ์“ด๋‹ค. ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค์˜ writer์™€ async table service๋ฅผ ๋ฝ์œผ๋กœ ์กฐ์ •ํ•  ๋•Œ๋Š” InProcessLockProvider๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ถ€๋”ชํžˆ๋Š” ์กฐํ•ฉํ•ด๊ฒฐ ์ˆ˜๋‹จ๋ฝ
writer โ†” reader๋ฒ„์ „๋ถˆํ•„์š”
writer โ†” ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค์˜ async table service๋ฒ„์ „ + ํ”„๋กœ์„ธ์Šค ๋‚ด๋ถ€ ์กฐ์ •ํ•„์š” ์‹œ InProcessLockProvider
writer โ†” writer (OCC ๋ชจ๋“œ)OCC๊ณต์œ  ๋ฝ ํ•„์š”

์—ฌ๋Ÿฌ writer๋ฅผ OCC ๋ชจ๋“œ๋กœ ์‹คํ–‰ํ•  ๋•Œ๋Š” writer ์‚ฌ์ด์—์„œ ๊ณต์œ ํ•  ๋ฝ์„ ์ง€์ •ํ•œ๋‹ค.

sequenceDiagram
    participant A as ๋ฐฐ์น˜ A
    participant K as ๋ฝ ์„œ๋น„์Šค
    participant B as ๋ฐฐ์น˜ B
    Note over A,B: ๊ฐ์ž parquet ์ž‘์„ฑ. ์—ฌ๊ธฐ๊นŒ์ง€๋Š” ๋ฝ ๋ฐ–์ด๋‹ค
    A->>K: ๋ฝ ์š”์ฒญ
    K-->>A: ํš๋“
    B->>K: ๋ฝ ์š”์ฒญ
    Note over B: ๋Œ€๊ธฐ
    Note over A: ์ถฉ๋Œ ๊ฒ€์‚ฌ ํ›„ commit ๊ธฐ๋ก
    A->>K: ๋ฝ ๋ฐ˜๋‚ฉ
    K-->>B: ํš๋“
    Note over B: ์ถฉ๋Œ ๊ฒ€์‚ฌ<br/>A์™€ ๊ฒน์น˜๋ฉด job ์‹คํŒจ
# ๊ธฐ๋ณธ๊ฐ’. writer๊ฐ€ ํ•˜๋‚˜๋ฉด ์ด๋Œ€๋กœ ๋‘”๋‹ค
hoodie.write.concurrency.mode=SINGLE_WRITER
 
# writer๊ฐ€ ๋‘˜ ์ด์ƒ์ด๋ฉด OCC๋กœ ๋ฐ”๊พธ๊ณ  ๋ฝ์„ ์ง€์ •ํ•œ๋‹ค
hoodie.write.concurrency.mode=optimistic_concurrency_control
hoodie.write.lock.provider=org.apache.hudi.aws.transaction.lock.DynamoDBBasedLockProvider
hoodie.cleaner.policy.failed.writes=LAZY

๋งˆ์ง€๋ง‰ ์ค„์ด ํ•จ๊ป˜ ํ•„์š”ํ•˜๋‹ค. ๊ธฐ๋ณธ๊ฐ’ EAGER๋Š” ๋‹ค๋ฅธ writer๊ฐ€ ์•„์ง ์“ฐ๋Š” ์ค‘์ธ ํŒŒ์ผ์„ ์‹คํŒจํ•œ ๊ฒƒ์œผ๋กœ ๋ณด๊ณ  ์ง€์šด๋‹ค.

  • ๋ฝ ๊ตฌ๊ฐ„์ด ์งง๋‹ค: ๋ฐ์ดํ„ฐ ํŒŒ์ผ ์“ฐ๊ธฐ๋Š” ๋ฝ ๋ฐ–์—์„œ ํ•œ๋‹ค. ์ปค๋ฐ‹ ์ง์ „ ์ถฉ๋Œ ๊ฒ€์‚ฌ์™€ ๊ธฐ๋ก๋งŒ ๋ฝ ์•ˆ์ด๋‹ค
  • ์ž๋™ ์žฌ์‹œ๋„๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค: Iceberg์™€ Delta๋Š” ์‹คํŒจํ•œ ์ปค๋ฐ‹์„ ์ƒˆ ๊ธฐ์ค€์œผ๋กœ ๋‹ค์‹œ ์‹œ๋„ํ•˜์ง€๋งŒ Hudi๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ job์„ ์‹คํŒจ์‹œํ‚จ๋‹ค. ์žฌ์‹คํ–‰์€ ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค
  • ๋น„์ฐจ๋‹จ ๋™์‹œ์„ฑ ์ œ์–ด: Hudi 1.x๋Š” ๋กœ๊ทธ ํŒŒ์ผ ๊ธฐ๋ฐ˜์˜ ๋น„์ฐจ๋‹จ ๋™์‹œ์„ฑ ์ œ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด ์ŠคํŠธ๋ฆฌ๋ฐ ingestion๊ณผ compaction์ด ์„œ๋กœ๋ฅผ ๋ง‰์ง€ ์•Š๊ฒŒ ํ–ˆ๋‹ค

lock provider: ๋ฝ ๊ตฌํ˜„ ์ง€์ •

  • ์ปค๋ฐ‹ ๋ฝ์— ์‚ฌ์šฉํ•  ๊ตฌํ˜„์„ ์ง€์ •ํ•˜๋Š” ์„ค์ •์ด๋‹ค. ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ์•ˆ์˜ ๋ฝ์€ InProcessLockProvider๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ๊ณ  ์—ฌ๋Ÿฌ writer ์‚ฌ์ด์—์„œ๋Š” DynamoDB๋‚˜ ZooKeeper ๊ฐ™์€ ๊ณต์œ  ๋ฝ ๊ตฌํ˜„์„ ์“ด๋‹ค
  • DynamoDB, ZooKeeper, Hive Metastore, ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ธฐ๋ฐ˜ ์ค‘์— ๊ณ ๋ฅธ๋‹ค
  • ๋ฝ ์„œ๋น„์Šค๊ฐ€ ์ค‘๋‹จ๋˜๋ฉด ์ปค๋ฐ‹์ด ๋ง‰ํžˆ๊ณ  ๋ฝ์„ ํ•ด์ œํ•˜์ง€ ๋ชปํ•œ ์ฑ„ job์ด ๋น„์ •์ƒ ์ข…๋ฃŒํ•˜๋ฉด ๋งŒ๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค

๋‹จ์ผ writer์—๋„ lock provider๊ฐ€ ๋‚˜์˜ค๋Š” ๊ฒฝ์šฐ

  • ํ•œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์“ฐ๋ฉด์„œ async table service๋ฅผ ํ•จ๊ป˜ ์‹คํ–‰ํ•˜๋Š” ๊ตฌ์„ฑ์—์„œ๋Š” InProcessLockProvider๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๊ฐ™์€ JVM ์•ˆ์—์„œ๋งŒ ๋„๋Š” ๋ฝ์ด๋ผ DynamoDB๋‚˜ ZooKeeper๊ฐ€ ํ•„์š” ์—†๋‹ค

4.5 ์ •๋ฆฌ

ํฌ๋งท์›์ž์„ฑ์˜ ๊ทผ๊ฑฐ์‹คํŒจํ•œ ์ชฝ์˜ ์ฒ˜๋ฆฌํ•„์ˆ˜ ์™ธ๋ถ€ ๊ตฌ์„ฑ ์š”์†Œ
Iceberg์นดํƒˆ๋กœ๊ทธ์˜ CASmanifest๋งŒ ๋‹ค์‹œ ๋งŒ๋“ค์–ด ์žฌ์‹œ๋„์นดํƒˆ๋กœ๊ทธ (ํ•„์ˆ˜)
Delta๋กœ๊ทธ ํŒŒ์ผ PUT-if-absent๋กœ๊ทธ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ€์–ด ์žฌ์‹œ๋„์—†์Œ. S3 multi-writer๋Š” ์กฐ๊ฑด๋ถ€ ์“ฐ๊ธฐ ๋˜๋Š” ๋ฝ
Hudiํƒ€์ž„๋ผ์ธ + ์™ธ๋ถ€ ๋ฝ๊ธฐ๋ณธ์€ job ์‹คํŒจmulti-writer์ผ ๋•Œ lock provider

์•ž์˜ append ์˜ˆ์‹œ์—์„œ Iceberg์™€ Delta๋Š” ์ถฉ๋Œ ๊ฒ€์ฆ์„ ํ†ต๊ณผํ•˜๋ฉด ์ด๋ฏธ ์“ด ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์žฌ์‚ฌ์šฉํ•ด ์ปค๋ฐ‹์„ ๋‹ค์‹œ ์‹œ๋„ํ•œ๋‹ค. ์ด ์žฌ์‹œ๋„๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ฐฑ์‹ ์ด ์ค‘์‹ฌ์ด๋‹ค. Hudi์˜ job ์‹คํŒจ ํ›„ ์žฌ์‹คํ–‰ ๋น„์šฉ์€ ํŒŒ์ดํ”„๋ผ์ธ์˜ ์žฌ์ฒ˜๋ฆฌ ๋ฒ”์œ„์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค.


5. ์นดํƒˆ๋กœ๊ทธ ์ „๋žต

Iceberg๋Š” ์นดํƒˆ๋กœ๊ทธ๋กœ ํ…Œ์ด๋ธ”์„ ์กฐํšŒํ•˜๊ณ  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์„ ์ปค๋ฐ‹ํ•œ๋‹ค. ์นดํƒˆ๋กœ๊ทธ ๊ตฌ์„ฑ์— ์“ฐ์ด๋Š” API ๊ทœ๊ฒฉ, ๊ตฌํ˜„์ฒด, ์ €์žฅ ์„œ๋น„์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ๋ถ„ํ•œ๋‹ค.

ํ•ญ๋ชฉ์ข…๋ฅ˜์„ค๋ช…
Hive Metastore๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์„œ๋น„์Šคํ…Œ์ด๋ธ”๊ณผ ์Šคํ‚ค๋งˆ ๋“ฑ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ
AWS Glue Data Catalog๊ด€๋ฆฌํ˜• ์นดํƒˆ๋กœ๊ทธ ์„œ๋น„์ŠคAWS์—์„œ ์ œ๊ณตํ•˜๋Š” ์ค‘์•™ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ
Iceberg REST Catalog API์ธํ„ฐํŽ˜์ด์Šค ๊ทœ๊ฒฉ์—”์ง„๊ณผ ์นดํƒˆ๋กœ๊ทธ ์‚ฌ์ด์˜ ๊ณตํ†ต HTTP API
Nessie์นดํƒˆ๋กœ๊ทธ ๊ตฌํ˜„ํ…Œ์ด๋ธ” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ ๋ธŒ๋žœ์น˜์™€ ์ปค๋ฐ‹ ๊ด€๋ฆฌ
Polaris์นดํƒˆ๋กœ๊ทธ ๊ตฌํ˜„Iceberg REST Catalog API ๊ตฌํ˜„
S3 Tables๊ด€๋ฆฌํ˜• ํ…Œ์ด๋ธ” ์Šคํ† ๋ฆฌ์ง€Iceberg ํ…Œ์ด๋ธ” ์ €์žฅ๊ณผ ์œ ์ง€๋ณด์ˆ˜ ์ œ๊ณต
HadoopCatalogํŒŒ์ผ ์‹œ์Šคํ…œ ๊ธฐ๋ฐ˜ ์นดํƒˆ๋กœ๊ทธ ๊ตฌํ˜„๋””๋ ‰ํ„ฐ๋ฆฌ์™€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํŒŒ์ผ๋กœ ๊ด€๋ฆฌ. ์›์ž์  rename ํ•„์š”

์•„๋ž˜๋Š” Spark๋ฅผ REST Catalog API๋กœ Polaris์— ์—ฐ๊ฒฐํ•˜๋Š” ์„ค์ •์ด๋‹ค.

spark.conf.set("spark.sql.catalog.prod", "org.apache.iceberg.spark.SparkCatalog")
spark.conf.set("spark.sql.catalog.prod.type", "rest")
spark.conf.set("spark.sql.catalog.prod.uri", "https://polaris.example.com/api/catalog")

Delta์™€ Hudi๋Š” ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. ์นดํƒˆ๋กœ๊ทธ ๋“ฑ๋ก์€ ์ด๋ฆ„ ๋ถ™์ด๊ธฐ์™€ ๊ถŒํ•œ ๊ด€๋ฆฌ ์šฉ๋„์ด๊ณ  ์ปค๋ฐ‹ ์›์ž์„ฑ๊ณผ๋Š” ๋ฌด๊ด€ํ•˜๋‹ค.

# ์นดํƒˆ๋กœ๊ทธ ๋“ฑ๋ก ์—†์ด ์ฝํžŒ๋‹ค
spark.read.format("delta").load("s3://lake/orders")
spark.read.format("hudi").load("s3://lake/orders")
  • ํ…Œ์ด๋ธ” ์ด๋ฆ„๊ณผ ๊ฒฝ๋กœ ๋ณ€๊ฒฝ: Iceberg์˜ ํ…Œ์ด๋ธ” ์ด๋ฆ„์€ ์นดํƒˆ๋กœ๊ทธ์—์„œ ๋ฐ”๊พธ๋ฉฐ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ์ด๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฝ๋Š” ํ…Œ์ด๋ธ”์˜ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์˜ฎ๊ธธ ๋•Œ๋Š” ์ฝ๊ธฐ ๊ฒฝ๋กœ์™€ ์นดํƒˆ๋กœ๊ทธ ๋“ฑ๋ก ์ •๋ณด๋„ ํ•จ๊ป˜ ํ™•์ธํ•œ๋‹ค
  • ํŒŒ์ผ ์œ„์น˜์˜ ์ž์œ ๋„: Iceberg manifest๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๊ธฐ๋กํ•ด ํ•œ ํ…Œ์ด๋ธ”์˜ ํŒŒ์ผ์ด ์—ฌ๋Ÿฌ ๋ฒ„ํ‚ท์— ํฉ์–ด์ ธ๋„ ๋œ๋‹ค. Delta์™€ Hudi๋ฅผ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ์ฝ์„ ๋•Œ๋Š” ํ…Œ์ด๋ธ”์˜ ๋ฃจํŠธ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•œ๋‹ค
  • ์ดˆ๊ธฐ ์ง„์ž… ๋น„์šฉ: Delta์™€ Hudi๋Š” ์นดํƒˆ๋กœ๊ทธ๋ฅผ ๋ณ„๋„๋กœ ๊ตฌ์ถ•ยท์šด์˜ํ•˜์ง€ ์•Š๊ณ  ์‹œ์ž‘ํ•œ๋‹ค

์ฃผ์˜: ์นดํƒˆ๋กœ๊ทธ ๊ต์ฒด ์‹œ ๊ถŒํ•œ๊ณผ job ์„ค์ • ๋ณ€๊ฒฝ

  • ์นดํƒˆ๋กœ๊ทธ๋ฅผ ๋ฐ”๊พธ๋ฉด ํ…Œ์ด๋ธ” ์žฌ๋“ฑ๋ก, ๊ถŒํ•œ ์žฌ์„ค๊ณ„, ๋ชจ๋“  job์˜ ์ปค๋„ฅํ„ฐ ์„ค์ • ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜๋‹ค
  • ์ดˆ๊ธฐ ์„ค๊ณ„ ๋‹จ๊ณ„์—์„œ ์นดํƒˆ๋กœ๊ทธ์™€ ๊ถŒํ•œยท์ปค๋„ฅํ„ฐ ๊ตฌ์„ฑ์„ ํ•จ๊ป˜ ๊ฒ€ํ† ํ•œ๋‹ค

6. ํŒŒํ‹ฐ์…˜, ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜์™€ Data Skipping

์ฝ์„ ๋ฐ์ดํ„ฐ๋ฅผ ์ค„์ด๋Š” ๊ธฐ๋ฒ•์€ ์—ญํ• ์— ๋”ฐ๋ผ ๊ตฌ๋ถ„ํ•œ๋‹ค.

์—ญํ• ๋™์ž‘
ํŒŒํ‹ฐ์…”๋‹๋ฐ์ดํ„ฐ๋ฅผ ํŒŒํ‹ฐ์…˜์œผ๋กœ ๋‚˜๋ˆ„๊ณ  ์กฐํšŒ ์กฐ๊ฑด์— ๋งž๋Š” ํŒŒํ‹ฐ์…˜๋งŒ ์„ ํƒ
๋ฐ์ดํ„ฐ ๋ฐฐ์น˜์ •๋ ฌยทZ-Orderingยทclustering์œผ๋กœ ๊ด€๋ จ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ™์€ ํŒŒ์ผ์— ๋ชจ์Œ
ํ†ต๊ณ„ ๊ธฐ๋ฐ˜ Data Skipping์กฐํšŒ ์กฐ๊ฑด๊ณผ ํŒŒ์ผ๋ณ„ min/max ๋“ฑ์„ ๋น„๊ตํ•ด ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ ์ œ์™ธ

์ •๋ ฌ ๋“ฑ์œผ๋กœ ํŒŒ์ผ๋ณ„ ๊ฐ’ ๋ฒ”์œ„๋ฅผ ์ขํžˆ๋ฉด ์กฐํšŒ ์กฐ๊ฑด๊ณผ ๊ฒน์น˜์ง€ ์•Š๋Š” ํŒŒ์ผ์„ ์ œ์™ธํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.

์„ธ ํฌ๋งท ๋ชจ๋‘ ํŒŒ์ผ๋ณ„ ์ปฌ๋Ÿผ ํ†ต๊ณ„๋ฅผ ํ™œ์šฉํ•œ data skipping์„ ์ง€์›ํ•˜๋ฉฐ ํ†ต๊ณ„๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค.

ํฌ๋งทํŒŒ์ผ๋ณ„ ์ปฌ๋Ÿผ ํ†ต๊ณ„์˜ ๊ด€๋ฆฌ ์œ„์น˜
Icebergmanifest์˜ ๋ฐ์ดํ„ฐ ํŒŒ์ผ ํ•ญ๋ชฉ
DeltaํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ์˜ ํŒŒ์ผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ (add.stats)
Hudi๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”์˜ column_stats

๊ตฌํ˜„ ์˜ˆ: Hidden Partitioning๊ณผ ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜

  • Hidden Partitioning(Iceberg): ์›๋ณธ ์ปฌ๋Ÿผ์˜ ์กฐํšŒ ์กฐ๊ฑด์„ ํŒŒํ‹ฐ์…˜ ์กฐ๊ฑด์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ts ์กฐ๊ฑด์œผ๋กœ days(ts) ํŒŒํ‹ฐ์…˜์„ ๊ณ ๋ฅธ๋‹ค
  • Z-Ordering: ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ์˜ ๊ฐ€๊นŒ์šด ๊ฐ’์„ ๊ฐ™์€ ํŒŒ์ผ์— ๋ชจ์œผ๋Š” ๋ฐฐ์น˜ ๊ธฐ๋ฒ•์ด๋‹ค. Delta์™€ Iceberg, Hudi์˜ ์ง€์› ์—”์ง„์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • Liquid Clustering(Delta): ์ง€์ •ํ•œ ํ‚ค๋กœ OPTIMIZE๊ฐ€ ํ•„์š”ํ•œ ํŒŒ์ผ์„ ์ ์ง„์ ์œผ๋กœ ์žฌ๋ฐฐ์น˜ํ•œ๋‹ค. ํ‚ค ๋ณ€๊ฒฝ๊ณผ ๊ธฐ์กด ํŒŒ์ผ ์žฌ๋ฐฐ์น˜๋Š” ๋ณ„๋„ ์ž‘์—…์ด๋ฉฐ ํŒŒํ‹ฐ์…”๋‹ยทZ-Ordering๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค
-- Iceberg: Hidden Partitioning (Spark SQL)
CREATE TABLE orders_iceberg (order_id BIGINT, ts TIMESTAMP)
USING iceberg
PARTITIONED BY (days(ts));
 
-- ์›๋ณธ ์ปฌ๋Ÿผ์˜ ์กฐ๊ฑด์œผ๋กœ ํŒŒํ‹ฐ์…˜์„ ์„ ํƒํ•œ๋‹ค
SELECT * FROM orders_iceberg
WHERE ts >= TIMESTAMP '2026-08-01 00:00:00';
-- Delta: ๊ธฐ์กด ํ…Œ์ด๋ธ”์— Z-Ordering ์ ์šฉ
OPTIMIZE orders ZORDER BY (customer_id, ts);
-- Delta: Liquid Clustering ํ…Œ์ด๋ธ” ์ƒ์„ฑ
CREATE TABLE orders_clustered (customer_id BIGINT, ts TIMESTAMP)
USING DELTA
CLUSTER BY (customer_id, ts);

7. ์—…๋ฐ์ดํŠธ์™€ ์‚ญ์ œ ์ฒ˜๋ฆฌ

์—…๋ฐ์ดํŠธ์™€ ์‚ญ์ œ๋Š” ๋ ˆ์ดํฌํ•˜์šฐ์Šค์—์„œ ๋น„์šฉ์ด ํฐ ์—ฐ์‚ฐ์ด๋ผ ์„ธ ํฌ๋งท์˜ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ๊ฐˆ๋ฆฐ๋‹ค.

7.1 ๊ธฐ๋ณธ ์ „๋žต

  1. Copy-on-Write (COW)
    • ๊ทธ ํ–‰์ด ๋“  ํŒŒ์ผ์„ ํ†ต์งธ๋กœ ๋‹ค์‹œ ์”€
    • ์“ฐ๊ธฐ ๋น„์Œˆ / ์ฝ๊ธฐ ๋น ๋ฆ„
  2. Merge-on-Read (MOR)
    • ๋ณ€๊ฒฝ๋ถ„๋งŒ ๋”ฐ๋กœ ๊ธฐ๋ก, ์ฝ์„ ๋•Œ ๋ณ‘ํ–ก
    • ์“ฐ๊ธฐ ๋น ๋ฆ„ / ์ฝ๊ธฐ ๋น„์Œˆ

7.2 ํฌ๋งท๋ณ„ ๊ตฌํ˜„

COWMOR ๋ฐฉ์‹
Iceberg๊ธฐ๋ณธposition delete / equality delete ํŒŒ์ผ. v3 ์ŠคํŽ™์—์„œ deletion vector ๋„์ž…
Delta๊ธฐ๋ณธDeletion Vector. ์‚ญ์ œ๋œ ํ–‰ ์œ„์น˜๋ฅผ ๋น„ํŠธ๋งต์œผ๋กœ ํ‘œ์‹œ
Hudiํ…Œ์ด๋ธ” ํƒ€์ž…์œผ๋กœ ์„ ํƒํ…Œ์ด๋ธ” ํƒ€์ž…์œผ๋กœ ์„ ํƒ. base file + Avro log file
  • Iceberg: ์‚ญ์ œ๋ฅผ ๋ณ„๋„ ํŒŒ์ผ๋กœ ๊ธฐ๋กํ•œ๋‹ค. ์œ„์น˜ ๊ธฐ๋ฐ˜๊ณผ ๊ฐ’ ๊ธฐ๋ฐ˜ ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๊ณ  ๊ฐ’ ๊ธฐ๋ฐ˜์€ ์œ ์—ฐํ•˜์ง€๋งŒ ์ฝ๊ธฐ ๋น„์šฉ์ด ํฌ๋‹ค
  • Delta: Deletion Vector๋กœ ํŒŒ์ผ ์žฌ์ž‘์„ฑ์„ ํ”ผํ•œ๋‹ค. ํ•œ ํ–‰์„ ์ง€์šฐ๋ ค๊ณ  1GB ํŒŒ์ผ์„ ๋‹ค์‹œ ์“ฐ๋Š” ์ƒํ™ฉ์„ ๋ง‰๋Š”๋‹ค
  • Hudi: ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค ๋•Œ COW/MOR์„ ์ •ํ•œ๋‹ค. MOR ํ…Œ์ด๋ธ”์€ ์ฟผ๋ฆฌ ํƒ€์ž…๋„ ๋‚˜๋‰œ๋‹ค

Hudi MOR์˜ ์„ธ ๊ฐ€์ง€ ์ฟผ๋ฆฌ ํƒ€์ž…

  • Snapshot: base + log๋ฅผ ๋ณ‘ํ•ฉํ•ด ์ตœ์‹  ์ƒํƒœ๋ฅผ ๋ณธ๋‹ค. log ๋ณ‘ํ•ฉ ๋น„์šฉ์ด ๋ถ™๋Š”๋‹ค
  • Read Optimized: base file๋งŒ ์ฝ์–ด log ๋ณ‘ํ•ฉ ๋น„์šฉ์€ ์ค„์ง€๋งŒ ๋งˆ์ง€๋ง‰ compaction ์‹œ์ ๊นŒ์ง€์˜ ๋ฐ์ดํ„ฐ๋งŒ ๋ณธ๋‹ค
  • Incremental: ํŠน์ • ์ปค๋ฐ‹ ์ดํ›„ ๋ณ€๊ฒฝ๋œ ๋ ˆ์ฝ”๋“œ๋งŒ ์ฝ๋Š”๋‹ค

7.3 upsert ์„ฑ๋Šฅ ์ฐจ์ด

upsert์—์„œ๋Š” ๋Œ€์ƒ ํŒŒ์ผ์„ ์ฐพ๋Š” ๋ฐฉ์‹์ด ์„ฑ๋Šฅ ์ฐจ์ด๋ฅผ ๋งŒ๋“ ๋‹ค.

Iceberg / Delta์˜ MERGE
  โ†’ ๋Œ€์ƒ ํŒŒ์ผ์„ ์ฐพ๊ธฐ ์œ„ํ•ด ์†Œ์Šค์™€ ํƒ€๊นƒ์„ ์กฐ์ธ
  โ†’ ํ†ต๊ณ„๋กœ ์ขํžˆ์ง€๋งŒ ํ‚ค๊ฐ€ ๋„“๊ฒŒ ํผ์ ธ ์žˆ์œผ๋ฉด ๋งŽ์€ ํŒŒ์ผ์„ ๊ฑด๋“œ๋ฆผ
 
Hudi์˜ upsert
  โ†’ ์ธ๋ฑ์Šค๋กœ ์ž…๋ ฅ ๋ ˆ์ฝ”๋“œ ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ์ผ ๊ทธ๋ฃน ํƒ์ƒ‰
  โ†’ ๊ทธ ํŒŒ์ผ ๊ทธ๋ฃน์—๋งŒ ์“ฐ๊ธฐ

Hudi์˜ ์ธ๋ฑ์Šค๋Š” upsertํ•  ๋ ˆ์ฝ”๋“œ์˜ ํ‚ค๋กœ ๋Œ€์ƒ ํŒŒ์ผ ๊ทธ๋ฃน์„ ์ฐพ๋Š”๋‹ค.

์ธ๋ฑ์ŠคํŒŒ์ผ ๊ทธ๋ฃน์„ ์ฐพ๋Š” ๋ฐฉ์‹
Bloom๋ ˆ์ฝ”๋“œ ํ‚ค์˜ Bloom filter๋กœ ํ›„๋ณด ํŒŒ์ผ์„ ์ขํž˜
Simple์ž…๋ ฅ ๋ ˆ์ฝ”๋“œ ํ‚ค์™€ ๊ธฐ์กด ๋ฐ์ดํ„ฐ์˜ ํ‚ค๋ฅผ ์กฐ์ธํ•ด ์œ„์น˜๋ฅผ ์ฐพ์Œ
Bucket๋ ˆ์ฝ”๋“œ ํ‚ค์˜ ํ•ด์‹œ๋กœ ํŒŒ์ผ ๊ทธ๋ฃน์„ ๊ฒฐ์ •
Record Level Index๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ ํ‚คโ†’ํŒŒ์ผ ๊ทธ๋ฃน ๋งคํ•‘ ์ €์žฅ

8. ์Šคํ‚ค๋งˆ ์ง„ํ™”

์„ธ ํฌ๋งท ๋ชจ๋‘ ์Šคํ‚ค๋งˆ ์ง„ํ™”๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ ์„ค์ • ์—†์ด ๋˜๋Š” ๋ฒ”์œ„๊ฐ€ ๋‹ค๋ฅด๋‹ค.

  • Iceberg: ์ปฌ๋Ÿผ๋งˆ๋‹ค ๊ณ ์œ  ID๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค. ์ด๋ฆ„์ด ์•„๋‹ˆ๋ผ ID๋กœ ๋งคํ•‘ํ•˜๋ฏ€๋กœ ์ด๋ฆ„์„ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ์ˆœ์„œ๋ฅผ ์˜ฎ๊ฒจ๋„ ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ทธ๋Œ€๋กœ ์ฝํžŒ๋‹ค. ์ถ”๊ฐ€ยท์‚ญ์ œยทrenameยท์ˆœ์„œ ๋ณ€๊ฒฝยทํƒ€์ž… ์Šน๊ฒฉ์ด ์„ค์ • ์—†์ด ๋œ๋‹ค
  • Delta: Column Mapping์„ ์ผœ๋ฉด Iceberg์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค. ๋„๊ณ  ์“ฐ๋ฉด ์‚ญ์ œ์™€ rename์ด ๋ง‰ํžŒ๋‹ค
  • Hudi: schema.on.read๋ฅผ ์ผœ์•ผ ์‚ญ์ œ์™€ rename์ด ๋œ๋‹ค

9. Time Travel๊ณผ ์ฆ๋ถ„ ์ฝ๊ธฐ

Time travel์€ ์…‹ ๋‹ค ์ง€์›ํ•œ๋‹ค. ํฌ๋งท๋ณ„ ์กฐํšŒ ๋ฌธ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

-- Iceberg
SELECT * FROM orders FOR SYSTEM_TIME AS OF '2026-08-01 00:00:00';
SELECT * FROM orders FOR SYSTEM_VERSION AS OF 3821550127947089987;
 
-- Delta
SELECT * FROM orders TIMESTAMP AS OF '2026-08-01';
SELECT * FROM orders VERSION AS OF 12;
 
-- Hudi
SELECT * FROM orders TIMESTAMP AS OF '20260801000000';

Hudi์˜ ์ฆ๋ถ„ ์ฝ๊ธฐ๋Š” ์ง€์ •ํ•œ ์ปค๋ฐ‹ ์ดํ›„ ๋ณ€๊ฒฝ๋œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์กฐํšŒํ•œ๋‹ค.

# Hudi: ํŠน์ • instant ์ดํ›„ ๋ณ€๊ฒฝ๋œ ๋ ˆ์ฝ”๋“œ๋งŒ
spark.read.format("hudi") \
    .option("hoodie.datasource.query.type", "incremental") \
    .option("hoodie.datasource.read.begin.instanttime", "20260801120000") \
    .load("s3://lake/orders")
# Delta: Change Data Feed (ํ…Œ์ด๋ธ” ์†์„ฑ์œผ๋กœ ์ผœ์•ผ ํ•จ)
spark.read.format("delta") \
    .option("readChangeFeed", "true") \
    .option("startingVersion", 12) \
    .table("orders")
-- Iceberg: incremental scan / changelog view
SELECT * FROM analytics.orders.changes
WHERE _change_ordinal >= 3;
  • Hudi: ingestion ํŒŒ์ดํ”„๋ผ์ธ ์„ค๊ณ„ ์ž์ฒด๊ฐ€ ์ฆ๋ถ„ ์†Œ๋น„๋ฅผ ์ „์ œ๋กœ ํ•œ๋‹ค
  • Delta: CDF๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ผœ์•ผ ํ•˜๊ณ  ์ผ  ์‹œ์  ์ดํ›„๋ถ€ํ„ฐ ๊ธฐ๋ก๋œ๋‹ค
  • Iceberg: ์Šค๋ƒ…์ƒท ๊ฐ„ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ์‹์ด๋ผ ์‚ญ์ œ ์ฒ˜๋ฆฌ์— ์ œ์•ฝ์ด ์žˆ๋‹ค

10. ํ…Œ์ด๋ธ” ์œ ์ง€๋ณด์ˆ˜

์ž‘์€ ํŒŒ์ผ์„ ๋ณ‘ํ•ฉํ•˜๊ณ  ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

์ž‘์—… ๋ชฉ์ IcebergDeltaHudi
์ž‘์€ ํŒŒ์ผ ๋ณ‘ํ•ฉยท๋ฐ์ดํ„ฐ ์žฌ๋ฐฐ์น˜rewrite_data_filesOPTIMIZEclustering
MOR์˜ base file๊ณผ log file ๋ณ‘ํ•ฉํ•ด๋‹น ์—†์Œํ•ด๋‹น ์—†์Œcompaction
์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ ์ •๋ฆฌexpire_snapshots: ์Šค๋ƒ…์ƒท ๋งŒ๋ฃŒ์™€ ๋ถˆํ•„์š”ํ•ด์ง„ ํŒŒ์ผ ์‚ญ์ œVACUUM: ๋ณด๊ด€ ๊ธฐ๊ฐ„์ด ์ง€๋‚œ ๋ฏธ์‚ฌ์šฉ ๋ฐ์ดํ„ฐ ํŒŒ์ผ ์‚ญ์ œCleaner: ๋ณด๊ด€ ์ •์ฑ…์— ๋”ฐ๋ฅธ ๊ณผ๊ฑฐ ํŒŒ์ผ ๋ฒ„์ „ ์‚ญ์ œ

์‹คํ–‰ ์ฃผ๊ธฐ์™€ ์ž๋™ํ™” ์—ฌ๋ถ€๋Š” ์—”์ง„ยท๊ด€๋ฆฌํ˜• ์„œ๋น„์Šคยท์„ค์ •์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค.

-- Iceberg
CALL catalog.system.rewrite_data_files(table => 'analytics.orders');
CALL catalog.system.expire_snapshots(table => 'analytics.orders', older_than => TIMESTAMP '2026-07-01');
 
-- Delta
OPTIMIZE orders;
VACUUM orders RETAIN 168 HOURS;

์ฃผ์˜: ๋ฐ์ดํ„ฐ ๋ณด๊ด€ ๊ธฐ๊ฐ„

  • ์˜ค๋ž˜๋œ ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋ฉด ๊ทธ ํŒŒ์ผ์ด ํ•„์š”ํ•œ time travel์ด๋‚˜ ์žฅ๊ธฐ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํŒจํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋ณด๊ด€ ๊ธฐ๊ฐ„์€ ํ•„์š”ํ•œ ๋กค๋ฐฑ ๋ฒ”์œ„์™€ ์žฅ๊ธฐ ์ฟผ๋ฆฌ ์‹คํ–‰ ์‹œ๊ฐ„์„ ๊ณ ๋ คํ•ด ์ •ํ•œ๋‹ค

11. ์ƒํƒœ๊ณ„๊ฐ€ ์ˆ˜๋ ดํ•˜๋Š” ์ง€์ 

์„œ๋กœ ๋‹ค๋ฅธ ํฌ๋งท์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•ด ๊ฐ™์€ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์ฝ๋Š” ์ƒํ˜ธ์šด์šฉ ๊ธฐ๋Šฅ์ด ์ œ๊ณต๋œ๋‹ค.

  • Delta UniForm: ํ•˜๋‚˜์˜ Parquet ๋ฐ์ดํ„ฐ์— _delta_log์™€ Iceberg ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ์ƒ์„ฑํ•œ๋‹ค. ์—”์ง„๋ณ„๋กœ ๊ณจ๋ผ ์ฝ๋Š”๋‹ค
  • Apache XTable(๊ตฌ OneTable): ์„ธ ํฌ๋งท์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ƒํ˜ธ ๋ณ€ํ™˜ํ•œ๋‹ค. ๋ฐ์ดํ„ฐ ํŒŒ์ผ์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋งŒ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค
  • Unity Catalog์˜ Iceberg REST ์—”๋“œํฌ์ธํŠธ: Delta ํ…Œ์ด๋ธ”์„ ์™ธ๋ถ€ ์—”์ง„์ด Iceberg REST๋กœ ์ฝ๊ฒŒ ์—ด์—ˆ๋‹ค

๊ถŒํ•œ๊ณผ lineage, ๊ฑฐ๋ฒ„๋„Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•  ์นดํƒˆ๋กœ๊ทธ๋„ ํ•จ๊ป˜ ์„ ํƒํ•œ๋‹ค.


12. ์„ ํƒ ๊ธฐ์ค€

Iceberg๋ฅผ ๊ณ ๋ฅธ๋‹ค

  • ์—”์ง„ ํ˜ผ์šฉ: ์—ฌ๋Ÿฌ ์—”์ง„์„ ์„ž์–ด ์“ฐ๊ฑฐ๋‚˜ ์•ž์œผ๋กœ ๋ฐ”๊ฟ€ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค
  • ์›จ์–ดํ•˜์šฐ์Šค ์—ฐ๋™: Snowflake, BigQuery, Trino ๋“ฑ ์›จ์–ดํ•˜์šฐ์Šค์™€ ๋ ˆ์ดํฌ๋ฅผ ํ•จ๊ป˜ ์“ด๋‹ค
  • AWS ์Šคํƒ: AWS ๋„ค์ดํ‹ฐ๋ธŒ ์Šคํƒ์„ ์“ด๋‹ค. S3 Tables์™€ Glue๊ฐ€ Iceberg๋ฅผ ์šฐ์„ ํ•œ๋‹ค
  • ํŒŒํ‹ฐ์…˜ ๊ทœ๋ชจ: ํŒŒํ‹ฐ์…˜์ด ์ˆ˜๋งŒ ๊ฐœ ์ด์ƒ์ด๊ณ  query planning์ด ๋ณ‘๋ชฉ์ด๋‹ค
  • ๋ฒค๋” ์ข…์† ํšŒํ”ผ: ๋ฒค๋” ์ข…์†์„ ํ”ผํ•˜๋Š” ๊ฒƒ์ด ์กฐ์ง ๋ฐฉ์นจ์ด๋‹ค

Delta Lake๋ฅผ ๊ณ ๋ฅธ๋‹ค

  • Databricks ์‚ฌ์šฉ: Databricks๋ฅผ ์“ฐ๊ณ  ์žˆ๋‹ค
  • ๋‹จ์ผ ์—”์ง„: Spark ๋‹จ์ผ ์—”์ง„์ด๊ณ  ํŒ€ ๊ทœ๋ชจ๊ฐ€ ํฌ์ง€ ์•Š๋‹ค
  • ์ดˆ๊ธฐ ์ง„์ž… ๋น„์šฉ: ์นดํƒˆ๋กœ๊ทธ ์ธํ”„๋ผ ์—†์ด ๋ฐ”๋กœ ์‹œ์ž‘ํ•˜๊ณ  ์‹ถ๋‹ค
  • ๊ถŒํ•œ ๊ด€๋ฆฌ: Unity Catalog๋กœ ํ…Œ์ด๋ธ”ยท๋ชจ๋ธยท๋…ธํŠธ๋ถ ๊ถŒํ•œ์„ ํ•œ ๊ณณ์—์„œ ๋ณด๊ณ  ์‹ถ๋‹ค

Hudi๋ฅผ ๊ณ ๋ฅธ๋‹ค

  • ๊ณ ๋นˆ๋„ CDC: ์ดˆ ๋‹จ์œ„ ๋˜๋Š” ๋ถ„ ๋‹จ์œ„ CDC๋ฅผ ๋ ˆ์ดํฌ์— ๋ฐ˜์˜ํ•ด์•ผ ํ•œ๋‹ค
  • upsert ๋ณ‘๋ชฉ: ๋ ˆ์ฝ”๋“œ ๋‹จ์œ„ upsert ์ฒ˜๋ฆฌ๋Ÿ‰์ด ์ด๋ฏธ ๋ณ‘๋ชฉ์ด๋‹ค
  • Flink ์ค‘์‹ฌ ํŒŒ์ดํ”„๋ผ์ธ: Flink ์ŠคํŠธ๋ฆฌ๋ฐ ingestion์ด ํŒŒ์ดํ”„๋ผ์ธ์˜ ์ค‘์‹ฌ์ด๋‹ค
  • ํŠœ๋‹ ์—ฌ๋ ฅ: ํŠœ๋‹์— ์‹œ๊ฐ„์„ ์“ธ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๊ฐ€ ์žˆ๋‹ค