TL;DR

  • Parquet๊ณผ ORC๋Š” ์—ด ๋‹จ์œ„๋กœ, Avro๋Š” ํ–‰ ๋‹จ์œ„๋กœ ๋ฐ”์ดํŠธ๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ์ €์žฅ ํฌ๋งท
  • ์—ด ์ €์žฅ์ด ๋ถ„์„์—์„œ ๋น ๋ฅธ ์ด์œ ๋Š” ์•ˆ ์ฝ๋Š” ์ปฌ๋Ÿผ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๊ฐ™์€ ํƒ€์ž…๋ผ๋ฆฌ ๋ชจ์—ฌ ์••์ถ•์ด ์ž˜ ๋˜๋ฉฐ ํ†ต๊ณ„๋กœ ๋ธ”๋ก์„ ๊ฑธ๋Ÿฌ๋‚ด๊ธฐ ๋•Œ๋ฌธ
  • ์Šค์บ”์€ Parquet, Hive ์Šคํƒ์€ ORC, ์ŠคํŠธ๋ฆฌ๋ฐ ์ˆ˜์ง‘๊ณผ ์Šคํ‚ค๋งˆ ์ง„ํ™”๋Š” Avro

AI-assisted


1. ํŒŒ์ผ ํฌ๋งท์ด ์ •ํ•˜๋Š” ๊ฒƒ

ํŒŒ์ผ ํฌ๋งท์€ ๊ฐ’์„ ๋””์Šคํฌ์— ์–ด๋–ค ์ˆœ์„œ๋กœ ๋Š˜์–ด๋†“์„์ง€, ์–ด๋””์— ํ†ต๊ณ„๋ฅผ ์ ์–ด๋‘˜์ง€, ์–ด๋–ป๊ฒŒ ์••์ถ•ํ• ์ง€๋ฅผ ์ •ํ•œ๋‹ค. (ํŒŒ์ผ ํฌ๋งท์€ ํ…Œ์ด๋ธ” ์ •์˜์— ๊ด€์—ฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ํ…Œ์ด๋ธ” ์ •์˜๋Š” ํ…Œ์ด๋ธ” ํฌ๋งท์ด ๋งก๋Š”๋‹ค)

ํ…Œ์ด๋ธ” ํฌ๋งท   ์–ด๋А ์‹œ์ ์— ์–ด๋–ค ํŒŒ์ผ์ด ํ…Œ์ด๋ธ”์— ์†ํ•˜๋Š”๊ฐ€   Iceberg / Delta / Hudi
      โ†“
ํŒŒ์ผ ํฌ๋งท     ํ•œ ํŒŒ์ผ ์•ˆ์—์„œ ๋ฐ”์ดํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฐฐ์น˜ํ•˜๋Š”๊ฐ€   Parquet / ORC / Avro
      โ†“
๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€  ๋ฐ”์ดํŠธ๋ฅผ ์–ด๋””์— ๋‘๋Š”๊ฐ€                    S3 / GCS / HDFS

์…‹ ๋‹ค ๊ทœ๊ฒฉ์ด ๊ณต๊ฐœ๋ผ ์žˆ์–ด ํŠน์ • ๋ฒค๋” ๋„๊ตฌ ์—†์ด ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ์ง€๋งŒ ์„ค๊ณ„ ๋ชฉํ‘œ๋Š” ๊ฐˆ๋ฆฐ๋‹ค.

  • Parquet: ๋ถ„์„ ์Šค์บ”. ์—ด ์ €์žฅ, ํ†ต๊ณ„ ๊ธฐ๋ฐ˜ ์Šคํ‚ต
  • ORC: ๋ถ„์„ ์Šค์บ” + Hive ๊ฒฐํ•ฉ. ์—ด ์ €์žฅ, ๋‚ด์žฅ ์ธ๋ฑ์Šค
  • Avro: ๋ ˆ์ฝ”๋“œ ์ „๋‹ฌ๊ณผ ์Šคํ‚ค๋งˆ ์ง„ํ™”. ํ–‰ ์ €์žฅ

Parquet๊ณผ ORC๋ฅผ ๋ฌถ์–ด ๋ถ€๋ฅผ ๋•Œ๋Š” columnar file format, ์…‹์„ ํ•จ๊ป˜ ๊ฐ€๋ฆฌํ‚ฌ ๋•Œ๋Š” storage format์ด๋ผ๊ณ  ์“ด๋‹ค.

์Šคํ‚ค๋งˆ๋ฅผ ํŒŒ์ผ ์•ˆ์— ๋„ฃ์–ด์„œ ์™ธ๋ถ€ ์นดํƒˆ๋กœ๊ทธ ์—†์ด ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ๊ฑด๋„ค๋„ ํ•ด์„๋œ๋‹ค. ์ด๋Ÿฐ ์„ฑ์งˆ์„ self-describing์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

๋Œ€์ƒ์Šคํ‚ค๋งˆ ์ ์šฉ ์‹œ์ ์Šคํ‚ค๋งˆ ์ €์žฅ ์œ„์น˜
RDBMSํ…Œ์ด๋ธ” ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์“ธ ๋•Œ ๊ฒ€์ฆDB ์นดํƒˆ๋กœ๊ทธ
Parquet, ORC, Avro ํŒŒ์ผ์Šคํ‚ค๋งˆ์— ๋งž์ถฐ ์“ฐ๊ณ  ์ฝ์„ ๋•Œ ํŒŒ์ผ์˜ ์Šคํ‚ค๋งˆ ์ฐธ์กฐํŒŒ์ผ ๋‚ด๋ถ€
CSV, JSON์ฝ๋Š” ์ชฝ์—์„œ ํ•„๋“œ ํƒ€์ž…์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ์ถ”๋ก ํŒŒ์ผ ์ž์ฒด์— ํ•„๋“œ ํƒ€์ž…์„ ์ •์˜ํ•œ ์Šคํ‚ค๋งˆ ์—†์Œ

CSV๋„ ์ฝ๋Š” ์‹œ์ ์— ์Šคํ‚ค๋งˆ๋ฅผ ์ž…ํžˆ์ง€๋งŒ self-describing์€ ์•„๋‹ˆ๋‹ค. ํ—ค๋” ์ค„์ด ์žˆ์–ด๋„ ํƒ€์ž… ์ •๋ณด๊ฐ€ ์—†์–ด ์ฝ๋Š” ์ชฝ์ด ์ถ”์ธกํ•œ๋‹ค. self-describing์€ ๋’ค์— ๋‚˜์˜ค๋Š” Parquet footer์™€ Avro ํ—ค๋”, ๊ทธ๋ฆฌ๊ณ  ์Šคํ‚ค๋งˆ ์ง„ํ™”์˜ ์ „์ œ๊ฐ€ ๋œ๋‹ค.

self-describing: ๊ณผํ•™ ๋ฐ์ดํ„ฐ์—์„œ ์˜จ ์„ค๊ณ„

  • 1988๋…„ HDF, 1989๋…„ netCDF๊ฐ€ ์ด ๋ฐฉ์‹์„ ํ‘œ๋ฐฉํ–ˆ๋‹ค. ์œ„์„ฑ ๊ด€์ธก์ฒ˜๋Ÿผ ์ˆ˜์‹ญ ๋…„ ๋ณด๊ด€ํ•˜๋Š” ๋ฐ์ดํ„ฐ์—์„œ ํŒŒ์ผ๊ณผ ์Šคํ‚ค๋งˆ ๋ฌธ์„œ๊ฐ€ ๋ถ„๋ฆฌ๋˜๋ฉด ๋‚˜์ค‘์— ํ•ด์„ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฌธ์ œ๋ฅผ ํ’€๋ ค๋˜ ์„ค๊ณ„๋‹ค
  • ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง์—๋Š” 2009๋…„ Avro๊ฐ€ ๋“ค์—ฌ์™”๊ณ  2013๋…„ Parquet๊ณผ ORC๊ฐ€ ์—ด ์ €์žฅ์— ๊ฒฐํ•ฉํ–ˆ๋‹ค
  • Hive๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ๋ฉ”ํƒ€์Šคํ† ์–ด์— ๋‘๊ณ  HDFS์—๋Š” ๊ตฌ๋ถ„์ž๋กœ ๋‚˜๋‰œ ํ…์ŠคํŠธ๋ฅผ ๋’€๋‹ค. ์—”์ง„์ด ๋Š˜๋ฉด์„œ ๊ฐ์ž ๋ฉ”ํƒ€์Šคํ† ์–ด ์—ฐ๋™์„ ๊ตฌํ˜„ํ•ด์•ผ ํ–ˆ๊ณ  ํŒŒ์ผ์„ ๋‹ค๋ฅธ ํด๋Ÿฌ์Šคํ„ฐ๋กœ ๋ณต์‚ฌํ•˜๋ฉด ์Šคํ‚ค๋งˆ๊ฐ€ ํ•จ๊ป˜ ์ด๋™ํ•˜์ง€ ์•Š์•˜๋‹ค

2. ํ–‰ ์ €์žฅ๊ณผ ์—ด ์ €์žฅ

์ฃผ๋ฌธ ํ…Œ์ด๋ธ”์— id, user, amount, ts ๋„ค ์ปฌ๋Ÿผ์ด ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ผ๋„ ๋””์Šคํฌ์— ๋†“๋Š” ์ˆœ์„œ๋Š” ๋‹ฌ๋ผ์ง„๋‹ค.

ํ–‰ ์ €์žฅ (CSV, JSON, Avro)
[1|kim|1200|10:00][2|lee|300|10:01][3|park|8900|10:02]
 โ† ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜๊ฐ€ ๋ถ™์–ด ์žˆ์Œ
 
์—ด ์ €์žฅ (Parquet, ORC)
[1|2|3][kim|lee|park][1200|300|8900][10:00|10:01|10:02]
 โ† ๊ฐ™์€ ์ปฌ๋Ÿผ ๊ฐ’์ด ๋ถ™์–ด ์žˆ์Œ

SELECT sum(amount) FROM orders๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฐจ์ด๊ฐ€ ๋“œ๋Ÿฌ๋‚œ๋‹ค.

  • ํ–‰ ์ €์žฅ: ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ฝ์œผ๋ฉด์„œ amount ์œ„์น˜์˜ ๊ฐ’๋งŒ ๊บผ๋‚ธ๋‹ค. ์•ˆ ์“ฐ๋Š” ์ปฌ๋Ÿผ๋„ ๋””์Šคํฌ์—์„œ ์˜ฌ๋ผ์˜จ๋‹ค
  • ์—ด ์ €์žฅ: amount ๋ธ”๋ก๋งŒ ์ฝ๋Š”๋‹ค. ์ปฌ๋Ÿผ์ด 100๊ฐœ๊ณ  ํ•˜๋‚˜๋งŒ ์“ฐ๋ฉด I/O๊ฐ€ 1/100๋กœ ์ค„์–ด๋“ ๋‹ค

์••์ถ•๋ฅ ๋„ ๋ฒŒ์–ด์ง„๋‹ค. ์—ด ์ €์žฅ์€ ๊ฐ™์€ ํƒ€์ž…, ๋น„์Šทํ•œ ๊ฐ’์ด ์ธ์ ‘ํ•ด ์žˆ์–ด์„œ ์‚ฌ์ „ ์ธ์ฝ”๋”ฉ์ด๋‚˜ ๋ฐ˜๋ณต ์ œ๊ฑฐ์˜ ํšจ๊ณผ๊ฐ€ ํฌ๋‹ค. ํ–‰ ์ €์žฅ์€ ์ •์ˆ˜ ์˜†์— ๋ฌธ์ž์—ด์ด ์˜ค๊ณ  ๊ทธ ์˜†์— ํƒ€์ž„์Šคํƒฌํ”„๊ฐ€ ์˜ค๋ฏ€๋กœ ํŒจํ„ด์„ ์ฐพ๊ธฐ ์–ด๋ ต๋‹ค.

๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜๋ฅผ ํ†ต์งธ๋กœ ๊บผ๋‚ด๊ฑฐ๋‚˜ ์ƒˆ ๋ ˆ์ฝ”๋“œ ํ•˜๋‚˜๋ฅผ ๋ง๋ถ™์ด๋Š” ์ž‘์—…์€ ํ–‰ ์ €์žฅ์ด ์œ ๋ฆฌํ•˜๋‹ค. ์—ด ์ €์žฅ์—์„œ ํ•œ ํ–‰์„ ์žฌ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ์ปฌ๋Ÿผ ์ˆ˜๋งŒํผ ์œ„์น˜๋ฅผ ์ฐพ์•„ ์กฐ๋ฆฝํ•ด์•ผ ํ•œ๋‹ค.


3. Parquet

์“ฐ์ž„์ด ๊ฐ€์žฅ ๋„“์€ ํฌ๋งท์ด๋ผ ๊ตฌ์กฐ๋ถ€ํ„ฐ ์ž์„ธํžˆ ๋ณธ๋‹ค.

3.1 ๋ฌผ๋ฆฌ ๊ตฌ์กฐ

Parquet ํŒŒ์ผ์€ ๋„ค ๊ฒน์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

PAR1                          โ† magic bytes
โ”œโ”€โ”€ Row Group 0 (๊ธฐ๋ณธ 128MB)
โ”‚   โ”œโ”€โ”€ Column Chunk: id
โ”‚   โ”‚   โ”œโ”€โ”€ Page 0 (๊ธฐ๋ณธ 1MB)
โ”‚   โ”‚   โ”œโ”€โ”€ Page 1
โ”‚   โ”‚   โ””โ”€โ”€ ...
โ”‚   โ”œโ”€โ”€ Column Chunk: user
โ”‚   โ””โ”€โ”€ Column Chunk: amount
โ”œโ”€โ”€ Row Group 1
โ”œโ”€โ”€ ...
โ”œโ”€โ”€ Footer (FileMetaData)
โ”‚   โ”œโ”€โ”€ ์Šคํ‚ค๋งˆ
โ”‚   โ””โ”€โ”€ Row Group๋ณ„ ยท Column Chunk๋ณ„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
โ”‚       โ””โ”€โ”€ min / max / null ๊ฐœ์ˆ˜ / ์˜คํ”„์…‹ / ์ธ์ฝ”๋”ฉ
โ”œโ”€โ”€ footer ๊ธธ์ด (4๋ฐ”์ดํŠธ)
โ””โ”€โ”€ PAR1
  • Row Group: ํ–‰์„ ์ผ์ • ํฌ๊ธฐ๋กœ ์ž๋ฅธ ๋‹จ์œ„. ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์™€ ์Šคํ‚ต์˜ ๊ธฐ๋ณธ ๋‹จ์œ„๋‹ค
  • Column Chunk: ํ•œ Row Group ์•ˆ์—์„œ ์ปฌ๋Ÿผ ํ•˜๋‚˜์— ํ•ด๋‹นํ•˜๋Š” ์—ฐ์† ๊ตฌ๊ฐ„
  • Page: ์‹ค์ œ ์••์ถ•ยท์ธ์ฝ”๋”ฉ์ด ์ ์šฉ๋˜๋Š” ์ตœ์†Œ ๋‹จ์œ„
  • Footer: ์Šคํ‚ค๋งˆ์™€ ๋ชจ๋“  ํ†ต๊ณ„๊ฐ€ ํŒŒ์ผ ๋์— ๋ชจ์—ฌ ์žˆ๋‹ค

์ค‘์ฒฉ ์ปฌ๋Ÿผ๋„ ํ‰๋ฉด Column Chunk๋กœ ํŽผ์ณ์ง„๋‹ค

  • ์œ„ ๋„์‹์—์„œ Column Chunk๋Š” ๊ฐ’์ด ์ผ๋ ฌ๋กœ ๋Š˜์–ด์„  ๋ชจ์–‘์ด๋‹ค. ์Šคํ‚ค๋งˆ์— ๊ตฌ์กฐ์ฒด๋‚˜ ๋ฐฐ์—ด์ด ์žˆ์œผ๋ฉด ์ด ๋ชจ์–‘์— ๊ทธ๋Œ€๋กœ ๋‹ด๊ธฐ์ง€ ์•Š๋Š”๋‹ค
  • ์ด๋ฒคํŠธ ๋กœ๊ทธ๋‚˜ API ์‘๋‹ต์„ ๊ทธ๋Œ€๋กœ ์ ์žฌํ•˜๋ฉด ์ด๋Ÿฐ ์ปฌ๋Ÿผ์ด ์ƒ๊ธด๋‹ค
{"id": 1, "user": {"name": "kim", "address": {"city": "Seoul"}}, "tags": ["sale", "mobile"]}
  • Parquet์€ ์ด ํŠธ๋ฆฌ๋ฅผ leaf node ๊ธฐ์ค€์œผ๋กœ ์ชผ๊ฐ ๋‹ค. id, user.name, user.address.city, tags ๋„ท์ด ๊ฐ๊ฐ Column Chunk๊ฐ€ ๋œ๋‹ค. user์™€ user.address๋Š” ์ค‘๊ฐ„ ๋…ธ๋“œ๋ผ ๋ณ„๋„ Column Chunk๊ฐ€ ์—†๋‹ค
  • ๊ทธ๋ž˜์„œ SELECT user.address.city๊ฐ€ ๊ทธ ์ปฌ๋Ÿผ๋งŒ ์ฝ๋Š”๋‹ค. user ์ „์ฒด๋ฅผ ์ฝ์–ด ํŒŒ์‹ฑํ•˜์ง€ ์•Š๋Š”๋‹ค
  • ๊ฐ’๋งŒ ๋Š˜์–ด๋†“์œผ๋ฉด ์›๋ž˜ ๋ชจ์–‘์„ ์žƒ์œผ๋ฏ€๋กœ ๊ฐ’๋งˆ๋‹ค definition level๊ณผ repetition level ๋‘ ์ˆซ์ž๋ฅผ ๋ถ™์—ฌ ์–ด๋А ๊นŠ์ด์—์„œ null์ด์—ˆ๋Š”์ง€, ์–ด๋””์„œ ์ƒˆ ๋ฐฐ์—ด์ด ์‹œ์ž‘๋˜๋Š”์ง€๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. Google Dremel ๋…ผ๋ฌธ์—์„œ ์˜จ ๋ฐฉ์‹์ด๋‹ค

์ฝ๋Š” ์ˆœ์„œ๋Š” ๋’ค์—์„œ ์•ž์ด๋‹ค. ๋งˆ์ง€๋ง‰ 4๋ฐ”์ดํŠธ๋กœ footer ๊ธธ์ด๋ฅผ ์•Œ์•„๋‚ด๊ณ  footer๋ฅผ ์ฝ์–ด ์Šคํ‚ค๋งˆ์™€ ํ†ต๊ณ„๋ฅผ ํŒŒ์•…ํ•œ ๋’ค ํ•„์š”ํ•œ Column Chunk์˜ ์˜คํ”„์…‹์œผ๋กœ ๊ฑด๋„ˆ๋›ด๋‹ค. ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€์—์„œ๋Š” Range GET ๋‘์„ธ ๋ฒˆ์ด๋ฉด ๋œ๋‹ค.

Row Group ํฌ๊ธฐ๋Š” ์™œ 128MB์ธ๊ฐ€

  • HDFS ๋ธ”๋ก ํ•˜๋‚˜์— Row Group ํ•˜๋‚˜๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉด ๋„คํŠธ์›Œํฌ๋ฅผ ํƒ€์ง€ ์•Š๊ณ  ๋กœ์ปฌ์—์„œ ์ฝํžŒ๋‹ค. ์—ฌ๊ธฐ์„œ ๊ตณ์–ด์ง„ ๊ธฐ๋ณธ๊ฐ’์ด๋‹ค
  • ํฌ๊ฒŒ ์žก์œผ๋ฉด ์••์ถ•๋ฅ ๊ณผ ์Šค์บ” ์ฒ˜๋ฆฌ๋Ÿ‰์ด ์˜ค๋ฅด์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋” ์“ฐ๊ณ  ์Šคํ‚ต ๋‹จ์œ„๊ฐ€ ๊ฑฐ์น ์–ด์ง„๋‹ค
  • ์ž‘๊ฒŒ ์žก์œผ๋ฉด ์„ธ๋ฐ€ํ•˜๊ฒŒ ๊ฑธ๋Ÿฌ๋‚ด์ง€๋งŒ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋น„์ค‘์ด ์ปค์ง„๋‹ค. ํŒŒ์ผ์ด ์ˆ˜๋งŒ ๊ฐœ๋ฉด footer ์ฝ๊ธฐ๋งŒ์œผ๋กœ ๋ถ€๋‹ด์ด ๋œ๋‹ค

์ž‘์€ ํŒŒ์ผ ๋ฌธ์ œ

  • Parquet์€ ํŒŒ์ผ๋‹น ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์žˆ๋‹ค. footer, ์‚ฌ์ „, ์••์ถ• ๋ธ”๋ก์ด ๋งค๋ฒˆ ๋ถ™๋Š”๋‹ค
  • ์ˆ˜ MB์งœ๋ฆฌ ํŒŒ์ผ์ด ์ˆ˜์‹ญ๋งŒ ๊ฐœ๋ฉด ์••์ถ•๋ฅ ๋„ ํ†ต๊ณ„ ํšจ๊ณผ๋„ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค
  • ์ŠคํŠธ๋ฆฌ๋ฐ์œผ๋กœ ์ ์žฌํ•  ๋•Œ ํŠนํžˆ ์ž˜ ์ƒ๊ธด๋‹ค. compaction์„ ์ฃผ๊ธฐ๋กœ ๋Œ๋ ค์•ผ ํ•œ๋‹ค

3.2 ์ฝ๊ธฐ ์ „์— ๊ฑธ๋Ÿฌ๋‚ด๊ธฐ

์—ด ์ €์žฅ์˜ ์ด๋“ ์ค‘ ํฐ ๋ชซ์€ โ€œ์ฝ์ง€ ์•Š๋Š” ๊ฒƒโ€์—์„œ ๋‚˜์˜ค๋Š”๋ฐ ์ค„์ด๋Š” ๋ฐฉํ–ฅ์€ ๋‘˜์ด๋‹ค. ์ฝ์„ ์ปฌ๋Ÿผ์„ ์ขํžˆ๋Š” ์ชฝ๊ณผ ์ฝ์„ ํ–‰์„ ์ขํžˆ๋Š” ์ชฝ์ด๋‹ค.

SELECT user FROM orders WHERE amount > 5000
  1. projection pushdown: ์ฟผ๋ฆฌ์— ์“ฐ์ธ user, amount Column Chunk๋งŒ ์ฝ๋Š”๋‹ค. SELECT *๋ฅผ ์“ฐ๋ฉด ๋ชจ๋“  ์ปฌ๋Ÿผ์ด ํ•„์š”ํ•˜๋‹ค
  2. predicate pushdown: ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋Š” ๊ตฌ๊ฐ„์„ ์ฝ๊ธฐ ์ „์— ์ œ์™ธํ•œ๋‹ค
    • Row Group์˜ min/max: amount์˜ max๊ฐ€ 3000์ด๋ฉด amount > 5000์„ ๋งŒ์กฑํ•˜๋Š” ํ–‰์ด ์—†์–ด ํ•ด๋‹น Row Group์„ ๊ฑด๋„ˆ๋›ด๋‹ค. footer์˜ ํ†ต๊ณ„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค
    • Bloom filter: WHERE user = 'kim' ๊ฐ™์€ ๋“ฑํ˜ธ ์กฐ๊ฑด์— ์‚ฌ์šฉํ•œ๋‹ค. Column Chunk๋งˆ๋‹ค ์ €์žฅ๋œ ํ•„ํ„ฐ๋กœ Row Group์— ์ฐพ๋Š” ๊ฐ’์ด ์—†๋Š”์ง€ ํŒ์ •ํ•œ๋‹ค
    • page index: Page ๋‹จ์œ„ min/max์™€ ์˜คํ”„์…‹์„ ์ฐธ์กฐํ•ด ๋‚จ์€ Row Group ์•ˆ์—์„œ ์ฝ์„ ๊ตฌ๊ฐ„์„ ๊ณ ๋ฅธ๋‹ค

์ด๋•Œ ์ •๋ ฌ์— ๋”ฐ๋ผ ์„ฑ๋Šฅ์ด ๋‹ฌ๋ผ์ง„๋‹ค.

  • ์ •๋ ฌ: amount๋กœ ์ •๋ ฌํ•ด์„œ ์“ฐ๋ฉด Row Group๋งˆ๋‹ค ๊ฐ’ ๋ฒ”์œ„๊ฐ€ ์ข์•„์ ธ min/max๋กœ ๋Œ€๋ถ€๋ถ„ ๊ฑธ๋Ÿฌ์ง„๋‹ค.
  • ๋ฌด์ž‘์œ„: ๊ฐ’์„ ๋ฌด์ž‘์œ„ ์ˆœ์„œ๋กœ ์“ฐ๋ฉด ๊ฐ Row Group์˜ min/max ๋ฒ”์œ„๊ฐ€ ๋„“์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ์กฐ๊ฑด ๊ฒน์นจ: ์กฐํšŒ ์กฐ๊ฑด์˜ ๊ฐ’ ๋ฒ”์œ„๊ฐ€ ๊ทธ min/max์™€ ์ž์ฃผ ๊ฒน์น˜๋ฉด ํ†ต๊ณ„๋งŒ์œผ๋กœ ์ œ์™ธํ•  ์ˆ˜ ์žˆ๋Š” Row Group์ด ์ค„์–ด๋“ ๋‹ค.

๊ฐ™์€ ๋ฐ์ดํ„ฐ, ๊ฐ™์€ ํฌ๋งท์ธ๋ฐ ์Šค์บ”๋Ÿ‰์ด ์ˆ˜์‹ญ ๋ฐฐ ๋ฒŒ์–ด์ง„๋‹ค.

Bloom filter: "์—†๋‹ค"๋งŒ ํ™•์‹คํ•˜๊ฒŒ ๋‹ตํ•˜๋Š” ๋น„ํŠธ ๋ฐฐ์—ด

  • ๊ฐ’์„ ํ•ด์‹œํ•ด ๋น„ํŠธ ๋ช‡ ๊ฐœ๋ฅผ ์ผœ๋‘”๋‹ค. ์ฐพ์„ ๋•Œ ๊ทธ ๋น„ํŠธ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ 0์ด๋ฉด ์ด Row Group์— ๊ฐ’์ด ์—†๋‹ค๊ณ  ํ™•์ •ํ•œ๋‹ค
  • ๋น„ํŠธ๊ฐ€ ์ „๋ถ€ 1์ด๋ฉด โ€œ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹คโ€์— ๊ทธ์นœ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์—†์„ ์ˆ˜ ์žˆ์–ด ์ฝ์–ด๋ด์•ผ ์•ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ์ฝ๊ธฐ ํ•œ ๋ฒˆ์œผ๋กœ ๋๋‚˜๊ณ  ๊ฒฐ๊ณผ๊ฐ€ ํ‹€๋ฆฌ์ง€๋Š” ์•Š๋Š”๋‹ค
  • ๊ฐ’๋„ ๊ฐœ์ˆ˜๋„ ์œ„์น˜๋„ ๋‹ด์ง€ ์•Š๋Š”๋‹ค. Parquet์€ 32๋ฐ”์ดํŠธ ๋ธ”๋ก ์•ˆ์—์„œ ๋น„ํŠธ๋ฅผ ๊ฑด๋“œ๋ฆฌ๋Š” Split Block Bloom Filter๋ฅผ ์จ์„œ ์กฐํšŒ ํ•œ ๋ฒˆ์ด CPU ์บ์‹œ ํ•œ ์ค„์— ๋“ค์–ด๊ฐ„๋‹ค
  • ํ•ด์‹œ๊ฐ’์ด๋ผ ์ˆœ์„œ ์ •๋ณด๊ฐ€ ์—†๋‹ค. amount > 5000 ๊ฐ™์€ ๋ฒ”์œ„ ์กฐ๊ฑด์—๋Š” ์“ธ ์ˆ˜ ์—†๋‹ค
  • ํฌ๊ธฐ๋Š” ์˜ˆ์ƒ ๊ณ ์œ ๊ฐ’ ๊ฐœ์ˆ˜์™€ ์˜คํƒ๋ฅ ๋กœ ์ •ํ•ด์ง„๋‹ค. ์ •๋ฐ€ํ•˜๊ฒŒ ์žก์„์ˆ˜๋ก ํ•„ํ„ฐ๊ฐ€ ์ปค์ง€๊ณ  ์ฝ์„ ๋ฐ”์ดํŠธ๋„ ๋Š˜์–ด ์ด๋“์ด ์ƒ์‡„๋œ๋‹ค
  • ๊ธฐ๋ณธ์€ ๊บผ์ ธ ์žˆ๋‹ค. ์ปฌ๋Ÿผ์„ ์ง€์ •ํ•ด ์ผ ๋‹ค
(df.write
   .option("parquet.bloom.filter.enabled#user_id", "true")
   .option("parquet.bloom.filter.expected.ndv#user_id", "1000000")
   .parquet("s3://bucket/orders/"))
  • ๋ชจ๋“  ์ปฌ๋Ÿผ์— ์ผœ๋ฉด ํŒŒ์ผ๋งŒ ์ปค์ง„๋‹ค. cardinality๊ฐ€ ๋†’๊ณ  ๋“ฑํ˜ธ๋กœ ์ž์ฃผ ์กฐํšŒํ•˜๋Š” ์ปฌ๋Ÿผ์—๋งŒ ์ ์šฉํ•œ๋‹ค. user_id, order_id, ์ด๋ฉ”์ผ ๊ฐ™์€ ์ปฌ๋Ÿผ์ด๋‹ค

pushdown: ์—ฐ์‚ฐ์„ ๋ฐ์ดํ„ฐ ์†Œ์Šค ์ชฝ์œผ๋กœ ๋„˜๊ธฐ๋Š” ๊ฒƒ

  • ๋ฐ์ดํ„ฐ๋Š” ์Šคํ† ๋ฆฌ์ง€ โ†’ reader โ†’ ์—”์ง„ ์ˆœ์œผ๋กœ ์˜ฌ๋ผ์˜จ๋‹ค. ์—”์ง„์ด ํ•  ์ผ์„ ์•„๋ž˜ ๊ณ„์ธต์œผ๋กœ ๋„˜๊ธฐ๋ฉด pushdown์ด๋ผ ๋ถ€๋ฅธ๋‹ค
    • reader๊ฐ€ ์ฒ˜๋ฆฌ: footer๋ฅผ ๋ณด๊ณ  ํ•„์š” ์—†๋Š” ์ปฌ๋Ÿผ๊ณผ ๊ตฌ๊ฐ„์„ ์ฝ์ง€ ์•Š๋Š”๋‹ค. ์Šคํ† ๋ฆฌ์ง€์—๋Š” ํ•„์š”ํ•œ ๋ฐ”์ดํŠธ ๋ฒ”์œ„๋งŒ ์š”์ฒญํ•˜๋ฏ€๋กœ ์ „์†ก๋Ÿ‰๋„ ํ•จ๊ป˜ ์ค€๋‹ค
    • ์—”์ง„์ด ์ฒ˜๋ฆฌ: reader๊ฐ€ ์ „๋ถ€ ๋””์ฝ”๋”ฉํ•ด ์˜ฌ๋ ค๋ณด๋‚ด๊ณ  ์—”์ง„์ด ํ•„์š” ์—†๋Š” ์ปฌ๋Ÿผ๊ณผ ํ–‰์„ ๋ฒ„๋ฆฐ๋‹ค. ํ†ต๊ณ„๊ฐ€ ์—†๋Š” CSVยทJSON์€ ์ด ๋ฐฉ์‹์— ํ•ด๋‹นํ•œ๋‹ค
  • ๋Œ€์ƒ์ด ์ปฌ๋Ÿผ์ด๋ฉด projection, ์กฐ๊ฑด์ด๋ฉด predicate๋‹ค. ์—”์ง„์— ๋”ฐ๋ผ ์ง‘๊ณ„๋‚˜ LIMIT์„ ๋„˜๊ธฐ๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค

3.3 ์ธ์ฝ”๋”ฉ๊ณผ ์••์ถ•

Parquet์€ ๋‘ ๋‹จ๊ณ„๋กœ ํฌ๊ธฐ๋ฅผ ์ค„์ธ๋‹ค. ๊ฐ’ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ํ‘œํ˜„ํ•˜๋Š” ์ธ์ฝ”๋”ฉ์ด ๋จผ์ €๊ณ  ๊ทธ ๊ฒฐ๊ณผ ๋ฐ”์ดํŠธ๋ฅผ ์••์ถ•ํ•˜๋Š” ๊ฒŒ ๋‹ค์Œ์ด๋‹ค.

์ธ์ฝ”๋”ฉ๋ฐฉ์‹์ž˜ ๋งž๋Š” ๋ฐ์ดํ„ฐ
PLAIN๊ฐ’์„ ๊ทธ๋Œ€๋กœ์••์ถ• ํšจ๊ณผ๊ฐ€ ๋‚ฎ์€ ๋ฌด์ž‘์œ„ ๊ฐ’
RLE_DICTIONARY (์‚ฌ์ „ ์ธ์ฝ”๋”ฉ)๊ฐ’์„ ์‚ฌ์ „์— ๋„ฃ๊ณ  ์ •์ˆ˜ ID๋กœ ์น˜ํ™˜. ID ๋ฐฐ์—ด์€ RLE๋กœ ์ €์žฅ๊ณ ์œ ๊ฐ’์ด ์ ์€ ์ปฌ๋Ÿผ. ๊ตญ๊ฐ€, ์ƒํƒœ ์ฝ”๋“œ
DELTA_BINARY_PACKED (๋ธํƒ€ ์ธ์ฝ”๋”ฉ)์ด์ „ ๊ฐ’๊ณผ์˜ ์ฐจ์ด๋งŒ ์ €์žฅ์ฆ๊ฐ€ํ•˜๋Š” ์ •์ˆ˜. ํƒ€์ž„์Šคํƒฌํ”„, ์‹œํ€€์Šค ID
DELTA_BYTE_ARRAY (์ ‘๋‘์‚ฌ ์ธ์ฝ”๋”ฉ)์•ž ๋ฌธ์ž์—ด๊ณผ ๊ณตํ†ต ์ ‘๋‘์‚ฌ ์ƒ๋žต์ •๋ ฌ๋œ URL, ๊ฒฝ๋กœ
BYTE_STREAM_SPLIT๋ถ€๋™์†Œ์ˆ˜์  ๋ฐ”์ดํŠธ๋ฅผ ์ž๋ฆฌ๋ณ„๋กœ ๋ถ„๋ฆฌ์„ผ์„œ ์ธก์ •๊ฐ’

์‚ฌ์ „ ์ธ์ฝ”๋”ฉ์ด ๊ธฐ๋ณธ์ด๊ณ  ๊ณ ์œ ๊ฐ’์ด ๋งŽ์•„ ์‚ฌ์ „์ด ์ปค์ง€๋ฉด ์ž๋™์œผ๋กœ PLAIN์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.

์‚ฌ์ „ ์ธ์ฝ”๋”ฉ๊ณผ RLE: ๊ฒน์ณ ์“ฐ๋Š” ๋‘ ๊ธฐ๋ฒ•

  • ์‚ฌ์ „ ์ธ์ฝ”๋”ฉ: ์ปฌ๋Ÿผ์˜ ๊ณ ์œ ๊ฐ’์„ ๋ชจ์•„ ๋ฒˆํ˜ธ๋ฅผ ๋งค๊ธฐ๊ณ  ๋ฐ์ดํ„ฐ ์ž๋ฆฌ์—๋Š” ๋ฒˆํ˜ธ๋งŒ ๋‚จ๊ธด๋‹ค.
    • ["KR","US","KR","KR","JP"] โ†’ ์‚ฌ์ „ 0=KR, 1=US, 2=JP + ๋ฐ์ดํ„ฐ [0,1,0,0,2]
    • ๋ฒˆํ˜ธ๋Š” ๊ณ ์œ ๊ฐ’ ๊ฐœ์ˆ˜์— ๋งž๋Š” ์ตœ์†Œ ๋น„ํŠธ ํญ์œผ๋กœ ์ฑ„์šด๋‹ค. ๊ณ ์œ ๊ฐ’ 300๊ฐœ๋ฉด 9๋น„ํŠธ
    • ์‚ฌ์ „์ด ์ž„๊ณ„๋ฅผ ๋„˜์œผ๋ฉด ๊ทธ Column Chunk๋Š” PLAIN์œผ๋กœ ์ „ํ™˜ํ•œ๋‹ค. UUID๋‚˜ ์ด๋ฉ”์ผ์ฒ˜๋Ÿผ ํ–‰๋งˆ๋‹ค ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด ์‚ฌ์ „์ด ์›๋ณธ๋งŒํผ ์ปค์ง„๋‹ค
    • ์ผ๋ถ€ ์—”์ง„์€ ๋””์ฝ”๋”ฉ ์—†์ด ์‚ฌ์ „ ์ƒํƒœ๋กœ ํ•„ํ„ฐ๋งํ•œ๋‹ค. WHERE country = 'KR'์„ ์ •์ˆ˜ ๋น„๊ต๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค
  • RLE(run-length encoding): ๊ฐ™์€ ๊ฐ’์˜ ๋ฐ˜๋ณต์„ 0์ด 500๋ฒˆ ํ˜•ํƒœ๋กœ ์ค„์ธ๋‹ค.
    • ์‚ฌ์ „ ์ธ์ฝ”๋”ฉ์€ ๊ณ ์œ ๊ฐ’์ด ์ ์„ ๋•Œ, RLE๋Š” ๊ฐ™์€ ๊ฐ’์ด ์—ฐ์†์œผ๋กœ ๋†“์ผ ๋•Œ ํšจ๊ณผ์ ์ด๋‹ค. ์ •๋ ฌํ•˜๋ฉด ๊ฐ™์€ ๊ฐ’์˜ ์—ฐ์† ๊ตฌ๊ฐ„์ด ๊ธธ์–ด์ ธ RLE ํšจ์œจ์ด ์˜ค๋ฅธ๋‹ค. ์‚ฌ์ „ ํฌ๊ธฐ๋Š” ๊ณ ์œ ๊ฐ’ ๊ฐœ์ˆ˜๋กœ ์ •ํ•ด์ ธ ์ •๋ ฌํ•ด๋„ ๊ทธ๋Œ€๋กœ๋‹ค
  • ์ด๋ฆ„์˜ ๋‘ ์กฐ๊ฐ์€ ์„œ๋กœ ๋‹ค๋ฅธ ์ธต์„ ๊ฐ€๋ฆฌํ‚จ๋‹ค. ์‚ฌ์ „์€ ๋ณ„๋„ Dictionary Page์— PLAIN์œผ๋กœ ์ €์žฅ๋˜๊ณ  RLE_DICTIONARY๋Š” ๋ฐ์ดํ„ฐ ํŽ˜์ด์ง€์— ๋ถ™๋Š” ์ด๋ฆ„์ด๋‹ค
    • DICTIONARY: ์ด ํŽ˜์ด์ง€์˜ ๊ฐ’์€ ์‹ค์ œ ๊ฐ’์ด ์•„๋‹ˆ๋ผ ์‚ฌ์ „ ์ธ๋ฑ์Šค๋‹ค
    • RLE: ๊ทธ ์ธ๋ฑ์Šค ๋ฐฐ์—ด์„ RLE๋กœ ๋‹ด์•˜๋‹ค. ๋ฐ˜๋ณต์ด ๊ธธ๋ฉด ํšŸ์ˆ˜๋กœ ์ ‘๊ณ  ์งง์œผ๋ฉด ๋น„ํŠธ ํŒจํ‚น์œผ๋กœ ๋‹ด๋Š” ํ•˜์ด๋ธŒ๋ฆฌ๋“œ๋‹ค

์••์ถ• ์ฝ”๋ฑ์€ ์••์ถ•๊ณผ ํ•ด์ œ๋ฅผ ๋งก๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•œ ์Œ์ด๋‹ค. ์••์ถ•๋ฅ ์„ ๋†’์ผ์ˆ˜๋ก CPU ๋น„์šฉ์ด ๋Š˜์–ด๋‚œ๋‹ค.

์ฝ”๋ฑ์••์ถ•๋ฅ CPU ์‚ฌ์šฉ์“ฐ์ž„
Snappy๋‚ฎ์Œ์ ์Œ์˜ค๋ž˜ ์“ฐ์ธ ๊ธฐ๋ณธ๊ฐ’
Zstd๋†’์Œ์ค‘๊ฐ„์ตœ๊ทผ ๊ธฐ๋ณธ ์„ ํƒ. ๋ ˆ๋ฒจ๋กœ ์กฐ์ ˆ
Gzip๋†’์Œ๋งŽ์Œ์ž์ฃผ ์ฝ์ง€ ์•Š๋Š” ๋ณด๊ด€ ๋ฐ์ดํ„ฐ
LZ4๋‚ฎ์Œ๊ฐ€์žฅ ์ ์Œ์••์ถ• ํ•ด์ œ๊ฐ€ ๋ถ€๋‹ด๋  ๋•Œ

์–ด๋А ์ชฝ์ด ๋ณ‘๋ชฉ์ธ์ง€๋กœ ์ •ํ•œ๋‹ค. ์Šค์บ” job์˜ CPU ์‚ฌ์šฉ๋ฅ ์€ ๋†’๊ณ  ๋””์Šคํฌ ์‚ฌ์šฉ๋ฅ ์€ ๋‚ฎ๋‹ค๋ฉด ์••์ถ•๋ฅ ๋ณด๋‹ค ์••์ถ• ํ•ด์ œ ๋น„์šฉ์ด ๋‚ฎ์€ ์ฝ”๋ฑ์„ ์„ ํƒํ•˜๋Š” ํŽธ์ด ์ฒ˜๋ฆฌ๋Ÿ‰์„ ๋†’์ด๊ธฐ ์ข‹๋‹ค. ๋ฐ˜๋Œ€๋กœ ๋„คํŠธ์›Œํฌ bandwidth๊ฐ€ ๋ณ‘๋ชฉ์ด๋ฉด CPU๋ฅผ ๋” ์จ์„œ๋ผ๋„ ๋ฐ”์ดํŠธ๋ฅผ ์ค„์ธ๋‹ค.

# ์ •๋ ฌ์€ ์“ฐ๊ธฐ ์‹œ์ ์— ์ •ํ•ด์ง„๋‹ค. ์ €์žฅํ•œ ๋’ค์—๋Š” ๋‹ค์‹œ ์“ฐ์ง€ ์•Š๋Š” ํ•œ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€Œ์ง€ ์•Š๋Š”๋‹ค
(df.sortWithinPartitions("country", "user_id")
   .write.parquet("s3://bucket/orders/", compression="zstd"))
-- Spark ์„ธ์…˜ ๊ธฐ๋ณธ๊ฐ’
SET spark.sql.parquet.compression.codec = zstd;

์ •๋ ฌ ํ‚ค๊ฐ€ ์ธ์ฝ”๋”ฉยท์••์ถ• ์„ ํƒ๋ณด๋‹ค ์˜ํ–ฅ์ด ํฌ๋‹ค

  • ํ•„ํ„ฐ์— ์ž์ฃผ ์“ฐ๋Š” ์ปฌ๋Ÿผ์œผ๋กœ ์ •๋ ฌํ•˜๋ฉด ํ†ต๊ณ„ ์Šคํ‚ต๊ณผ ์••์ถ•๋ฅ ์ด ํ•จ๊ป˜ ์ข‹์•„์ง„๋‹ค
  • ์ •๋ ฌ ํ‚ค๊ฐ€ ์—ฌ๋Ÿฟ์ด๋ฉด cardinality๊ฐ€ ๋‚ฎ์€ ์ปฌ๋Ÿผ์„ ์•ž์ž๋ฆฌ์— ๋‘”๋‹ค. ORDER BY country, user_id์ฒ˜๋Ÿผ ์“ฐ๋ฉด ๊ฐ™์€ ๋ฒˆํ˜ธ๊ฐ€ ์—ฐ์†์œผ๋กœ ๋ชฐ๋ ค RLE ๋ฐ˜๋ณต ๊ตฌ๊ฐ„์ด ๊ธธ์–ด์ง„๋‹ค
  • ์ •๋ ฌ ํšจ๊ณผ๋Š” ์•ž์ชฝ ํ‚ค์— ์ง‘์ค‘๋œ๋‹ค. user_id๋งŒ์œผ๋กœ ๊ฑฐ๋Š” ํ•„ํ„ฐ๋Š” ์ด๋“์ด ์ ๋‹ค. ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ์œผ๋กœ ํ•„ํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ํ…Œ์ด๋ธ” ํฌ๋งท ์ธต์˜ Z-Ordering์ด๋‚˜ Liquid Clustering์„ ์“ด๋‹ค
  • ์ „์—ญ ์ •๋ ฌ์€ shuffle ๋น„์šฉ์ด ํฌ๋‹ค. ๋‚ ์งœ๋กœ ํŒŒํ‹ฐ์…˜์„ ๋‚˜๋ˆ  ์“ฐ๋Š” ๋ฐฐ์น˜๋ผ๋ฉด sortWithinPartitions๋กœ ์ถฉ๋ถ„ํ•œ ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค
  • ์ฝ”๋ฑ์„ ๋ฐ”๊ฟ” ์–ป๋Š” ์ฐจ์ด๋Š” ์ด๋ณด๋‹ค ์ž‘๋‹ค

4. ORC (Optimized Row Columnar)

ORC๋Š” Hive์˜ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ํ’€๋ ค๊ณ  2013๋…„์— ๋‚˜์™”๋‹ค. ์ „์ฒด ๊ตฌ์กฐ๋Š” Parquet๊ณผ ๊ฐ™๊ณ  ๊ตฌ์„ฑ ์ด๋ฆ„๊ณผ ์„ธ๋ถ€ ๋ฐฐ์น˜๊ฐ€ ๋‹ค๋ฅด๋‹ค.

โ”œโ”€โ”€ Stripe 0 (๊ธฐ๋ณธ 64MB)          โ† Parquet์˜ Row Group์— ํ•ด๋‹น
โ”‚   โ”œโ”€โ”€ Index Data               โ† 1๋งŒ ํ–‰๋งˆ๋‹ค min/max, ์œ„์น˜, bloom filter
โ”‚   โ”œโ”€โ”€ Row Data                 โ† ์ปฌ๋Ÿผ๋ณ„ ์ŠคํŠธ๋ฆผ
โ”‚   โ””โ”€โ”€ Stripe Footer
โ”œโ”€โ”€ Stripe 1
โ”œโ”€โ”€ File Footer                   โ† ์Šคํ‚ค๋งˆ, Stripe ๋ชฉ๋ก, ์ปฌ๋Ÿผ ํ†ต๊ณ„
โ””โ”€โ”€ Postscript                    โ† ์••์ถ• ๋ฐฉ์‹, File Footer ๊ธธ์ด
  • ์ธ๋ฑ์Šค ์œ„์น˜: ORC๋Š” Stripe ์•ˆ์— ์ธ๋ฑ์Šค๋ฅผ ๋„ฃ๋Š”๋‹ค. Parquet์€ ํ†ต๊ณ„๋ฅผ ํŒŒ์ผ ๋ footer์— ๋ชจ์€๋‹ค
  • ์ธ๋ฑ์Šค ๊ฐ„๊ฒฉ: ๊ธฐ๋ณธ 1๋งŒ ํ–‰๋งˆ๋‹ค ํ†ต๊ณ„๋ฅผ ๋‚จ๊ธด๋‹ค. Parquet์˜ page index์™€ ๋น„์Šทํ•œ ์—ญํ• ์„ ๋” ์ผ์ฐ ๊ฐ–์ท„๋‹ค
  • ํƒ€์ž… ์‹œ์Šคํ…œ: Hive ํƒ€์ž…์— ๋งž์ถฐ ์„ค๊ณ„๋ผ DECIMAL, TIMESTAMP ์ฒ˜๋ฆฌ๊ฐ€ Hive์™€ ์–ด๊ธ‹๋‚˜์ง€ ์•Š๋Š”๋‹ค
  • ACID: Hive์˜ ํŠธ๋žœ์žญ์…˜ ํ…Œ์ด๋ธ”์€ ORC๋ฅผ ์ „์ œ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค. delta ํŒŒ์ผ๊ณผ base ํŒŒ์ผ์„ ๋ณ‘ํ•ฉํ•ด ์ฝ๋Š” ๊ตฌ์กฐ๊ฐ€ ํฌ๋งท ์•ˆ์— ๋“ค์–ด ์žˆ๋‹ค

์„ ํƒ ๊ธฐ์ค€์€ ์‹คํ–‰ ์Šคํƒ์ด๋‹ค.

  • HiveยทTez: ORC๊ฐ€ ๊ธฐ๋ณธ๊ฐ’์ด๊ณ  ํŠœ๋‹ ์ž๋ฃŒ๋„ ๊ทธ์ชฝ์— ๋งŽ๋‹ค
  • SparkยทTrinoยทSnowflake์™€ Polars: Parquet ์ชฝ ์ตœ์ ํ™”๊ฐ€ ์•ž์„œ ์žˆ๋‹ค
  • ํ…Œ์ด๋ธ” ํฌ๋งท: ์„ธ ์ข…๋ฅ˜(Iceberg, Delta Lake, Hudi)๊ฐ€ ๋ชจ๋‘ ๋ฐ์ดํ„ฐ ํŒŒ์ผ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ Parquet์„ ์“ด๋‹ค
  • ์‹ ๊ทœ ํ”„๋กœ์ ํŠธ: ๋Œ€๊ฐœ Parquet์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค

์ฃผ์˜: ์„ฑ๋Šฅ ๋น„๊ต๋Š” ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋’ค์ง‘ํžŒ๋‹ค

  • ์••์ถ•๋ฅ ์€ ๋ฐ์ดํ„ฐ ์„ฑ๊ฒฉ์ด ๊ฒฐ์ •ํ•œ๋‹ค. ๊ฐ™์€ ๋ฐ์ดํ„ฐ์— ๊ฐ™์€ ์ฝ”๋ฑ์„ ์“ฐ๋ฉด ๋‘ ํฌ๋งท ์ฐจ์ด๋Š” ํฌ์ง€ ์•Š๋‹ค
  • ๋ฒค์น˜๋งˆํฌ์—์„œ ๋ฒŒ์–ด์ง€๋Š” ์ฐจ์ด๋Š” ๋Œ€๊ฐœ ํฌ๋งท์ด ์•„๋‹ˆ๋ผ reader ๊ตฌํ˜„๊ณผ ํ†ต๊ณ„ ํ™œ์šฉ๋„์—์„œ ์˜จ๋‹ค
  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ํŒ๋‹จ์€ ๋ฒค์น˜๋งˆํฌ ์ˆ˜์น˜๋ณด๋‹ค ์—”์ง„ ์ง€์› ๋ฒ”์œ„๋กœ ํ•˜๋Š” ํŽธ์ด ์•ˆ์ „ํ•˜๋‹ค

5. Avro

Avro๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ํ–‰ ๋‹จ์œ„๋กœ ์Œ“์œผ๋ฉฐ ์•ž์˜ ๋‘˜๊ณผ ๋ชฉ์ ์ด ๋‹ฌ๋ผ ๊ฐ™์€ ์ถ•์— ๋†“๊ณ  ์šฐ์—ด์„ ๊ฐ€๋ฆฌ๊ธฐ ์–ด๋ ต๋‹ค.

โ”œโ”€โ”€ Header
โ”‚   โ”œโ”€โ”€ magic "Obj\x01"
โ”‚   โ”œโ”€โ”€ ์Šคํ‚ค๋งˆ (JSON)             โ† ํŒŒ์ผ ์•ˆ์— ๋“ค์–ด ์žˆ์Œ
โ”‚   โ””โ”€โ”€ sync marker (16๋ฐ”์ดํŠธ ๋‚œ์ˆ˜)
โ”œโ”€โ”€ Block 0: [ํ–‰ ๊ฐœ์ˆ˜][๋ฐ”์ดํŠธ ์ˆ˜][์ง๋ ฌํ™”๋œ ๋ ˆ์ฝ”๋“œ๋“ค][sync marker]
โ”œโ”€โ”€ Block 1: ...
โ””โ”€โ”€ ...
  • ์Šคํ‚ค๋งˆ ๋‚ด์žฅ: ํŒŒ์ผ ํ—ค๋”์— ์Šคํ‚ค๋งˆ๊ฐ€ JSON์œผ๋กœ ๋“ค์–ด ์žˆ๋‹ค. ๋ณ„๋„ ์ฝ”๋“œ ์ƒ์„ฑ์ด๋‚˜ ์Šคํ‚ค๋งˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์—†์ด ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค
  • ์Šคํ‚ค๋งˆ ์ง„ํ™”: ์“ธ ๋•Œ์˜ ์Šคํ‚ค๋งˆ์™€ ์ฝ์„ ๋•Œ์˜ ์Šคํ‚ค๋งˆ๊ฐ€ ๋‹ฌ๋ผ๋„ ๊ทœ์น™์— ๋”ฐ๋ผ ํ•ด์„ํ•œ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์ด ์žˆ๋Š” ํ•„๋“œ ์ถ”๊ฐ€, ํ•„๋“œ ์‚ญ์ œ, ์ด๋ฆ„ ๋ณ€๊ฒฝ(alias), ํƒ€์ž… ์Šน๊ฒฉ์ด ๊ทœ๊ฒฉ์— ์ •์˜๋ผ ์žˆ๋‹ค
  • ๋ถ„ํ•  ๊ฐ€๋Šฅ: ๋ธ”๋ก๋งˆ๋‹ค sync marker๊ฐ€ ์žˆ์–ด ํŒŒ์ผ ์ค‘๊ฐ„๋ถ€ํ„ฐ ์ฝ์–ด๋„ ๊ฒฝ๊ณ„๋ฅผ ์ฐพ๋Š”๋‹ค. ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ ํƒœ์Šคํฌ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค

์“ฐ์ด๋Š” ์ž๋ฆฌ๋„ ๋‹ค๋ฅด๋‹ค.

  • Kafka ๋ฉ”์‹œ์ง€: producer์™€ consumer๊ฐ€ Avro ์Šคํ‚ค๋งˆ๋ฅผ ์ฐธ์กฐํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ์ง๋ ฌํ™”ยท์—ญ์ง๋ ฌํ™”ํ•œ๋‹ค. Confluent Schema Registry๋Š” ์ƒˆ ์Šคํ‚ค๋งˆ ๋ฒ„์ „์„ ๋“ฑ๋กํ•  ๋•Œ ์„ค์ •๋œ ํ˜ธํ™˜์„ฑ ๊ทœ์น™์„ ์ ์šฉํ•œ๋‹ค
  • landing zone: ์›๋ณธ์„ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„๋‘๋Š” ๊ณ„์ธต. ์Šคํ‚ค๋งˆ๊ฐ€ ์ž์ฃผ ๋ฐ”๋€Œ๋Š” ์†Œ์Šค์— ๋งž๋‹ค
  • ํ…Œ์ด๋ธ” ํฌ๋งท ๋‚ด๋ถ€: Iceberg manifest๊ฐ€ Avro๋กœ ์ €์žฅ๋œ๋‹ค. ์Šคํ‚ค๋งˆ ์ง„ํ™”๊ฐ€ ํ•„์š”ํ•˜๊ณ  ์—ด ๋‹จ์œ„ ์Šค์บ”์€ ํ•„์š” ์—†๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์— ๋งž๋Š” ์„ ํƒ์ด๋‹ค

์ปฌ๋Ÿผ ํ•˜๋‚˜๋งŒ ํ•„์š”ํ•ด๋„ ๋ ˆ์ฝ”๋“œ ์ „์ฒด๋ฅผ ์ฝ๊ณ  ์—ญ์ง๋ ฌํ™”ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ถ„์„ ์Šค์บ”์—๋Š” ๋งž์ง€ ์•Š๋Š”๋‹ค.

์ง๋ ฌํ™” ํฌ๋งท ์ถ•์—์„œ ๋ณธ Avro

  • Avro๋Š” Protobuf, Thrift์™€ ๊ฐ™์€ ์ง๋ ฌํ™” ํฌ๋งท ๊ฐˆ๋ž˜๋‹ค. ์ฐจ์ด๋Š” ์Šคํ‚ค๋งˆ๋ฅผ ํŒŒ์ผ์— ๋„ฃ๋А๋ƒ ์ฝ”๋“œ๋กœ ์ƒ์„ฑํ•˜๋А๋ƒ๋‹ค
  • Protobuf๋Š” .proto์—์„œ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด ์“ฐ๊ณ  Avro๋Š” ๋Ÿฐํƒ€์ž„์— ์Šคํ‚ค๋งˆ๋ฅผ ์ฝ์–ด ์ฒ˜๋ฆฌํ•œ๋‹ค

6. ํ•œ๋ˆˆ์— ๋น„๊ต

ํ•ญ๋ชฉParquetORCAvro
์ €์žฅ ๋ฐฉํ–ฅ์—ด์—ดํ–‰
์ถœ์‹ Twitter + Cloudera, 2013Hortonworks, 2013Hadoop, 2009
๋ธ”๋ก ๋‹จ์œ„Row Group 128MBStripe 64MBBlock
ํ†ต๊ณ„ ์œ„์น˜ํŒŒ์ผ ๋ footerStripe ๋‚ด๋ถ€ + File Footer์—†์Œ
์„ธ๋ฐ€ํ•œ ์Šคํ‚ตpage index1๋งŒ ํ–‰ row index๋ถˆ๊ฐ€
Bloom filterColumn Chunk ๋‹จ์œ„1๋งŒ ํ–‰ ๋‹จ์œ„์—†์Œ
์ค‘์ฒฉ ๊ตฌ์กฐdefinition/repetition level์ค‘์ฒฉ ํƒ€์ž… ์ง€์›์Šคํ‚ค๋งˆ๋กœ ํ‘œํ˜„
์Šคํ‚ค๋งˆ ์ง„ํ™”์ปฌ๋Ÿผ ์ถ”๊ฐ€ยท์‚ญ์ œ. rename์€ ๋ถˆ๊ฐ€์ปฌ๋Ÿผ ์ถ”๊ฐ€ยท์‚ญ์ œ. rename์€ ๋ถˆ๊ฐ€์ถ”๊ฐ€ยท์‚ญ์ œยทrenameยทํƒ€์ž… ์Šน๊ฒฉ
ํ•œ ํ–‰ ์“ฐ๊ธฐ๋น„์Œˆ๋น„์Œˆ์Œˆ
์ฃผ ์‚ฌ์šฉ์ฒ˜๋ถ„์„ ์Šค์บ” ์ „๋ฐ˜Hive ์Šคํƒ๋ฉ”์‹œ์ง€, landing zone

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

์ƒํ™ฉ์„ ํƒ์ด์œ 
๋ ˆ์ดํฌํ•˜์šฐ์Šค ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐParquet์—”์ง„ ์ง€์›์ด ๊ฐ€์žฅ ๋„“๊ณ  ํ…Œ์ด๋ธ” ํฌ๋งท ๊ธฐ๋ณธ๊ฐ’
HiveยทTez ๊ธฐ์กด ์ž์‚ฐORCํƒ€์ž… ํ˜ธํ™˜๊ณผ ACID ํ…Œ์ด๋ธ” ์ „์ œ
Kafka ๋ฉ”์‹œ์ง€AvroSchema Registry ์—ฐ๋™, ์Šคํ‚ค๋งˆ ์ง„ํ™”
์›๋ณธ ๋ณด์กด์šฉ landing zoneAvro์Šคํ‚ค๋งˆ๊ฐ€ ๋ฐ”๋€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๋Š” ํ˜ธํ™˜์„ฑ ๊ทœ์น™ ์ œ๊ณต
์ปฌ๋Ÿผ ์ˆ˜๋ฐฑ ๊ฐœ, ์ผ๋ถ€๋งŒ ์กฐํšŒParquetprojection pushdown ํšจ๊ณผ๊ฐ€ ํผ

๋ ˆ์ฝ”๋“œ ์กฐํšŒ: ํŒŒ์ผ ํฌ๋งท๊ณผ ์ €์žฅ ์‹œ์Šคํ…œ์˜ ์„ ํƒ

  • ํŒŒ์ผ ํฌ๋งท: ํ•œ ํ–‰์„ ๋ณต์›ํ•  ๋•Œ ์ฝ์„ ๋ฐ์ดํ„ฐ ์–‘๊ณผ ์—ญ์ง๋ ฌํ™” ๋น„์šฉ์„ ๋น„๊ต
  • ์ €์žฅ ์‹œ์Šคํ…œ: ํŠน์ • ํ‚ค์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ž์ฃผ ์กฐํšŒํ•˜๋Š” ๊ฒฝ์šฐ ํ‚ค ๊ธฐ๋ฐ˜ ์กฐํšŒ๋ฅผ ์ง€์›ํ•˜๋Š” KV ์Šคํ† ์–ด ๋“ฑ์„ ๋ณ„๋„๋กœ ๊ฒ€ํ† 

์‹ค๋ฌด์—์„œ๋Š” ๊ณ„์ธต๋ณ„๋กœ ๋‚˜๋ˆ  ์“ฐ๋Š” ๊ตฌ์„ฑ์ด ํ”ํ•˜๋‹ค.

์†Œ์Šค โ†’ Kafka(Avro) โ†’ landing zone(Avro) โ†’ ๋ณ€ํ™˜ โ†’ ๋ถ„์„ ํ…Œ์ด๋ธ”(Parquet)

์ˆ˜์ง‘ ๋‹จ๊ณ„๋Š” ์Šคํ‚ค๋งˆ ๋ณ€ํ™”๋ฅผ ๊ฒฌ๋””๋Š” ์ชฝ์ด, ๋ถ„์„ ๋‹จ๊ณ„๋Š” ์Šค์บ”์ด ๋น ๋ฅธ ์ชฝ์ด ์œ ๋ฆฌํ•˜๋‹ค.


8. ํ…Œ์ด๋ธ” ํฌ๋งท๊ณผ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„

๋‘ ๊ณ„์ธต ๋ชจ๋‘ min/max ํ†ต๊ณ„๋ฅผ ์“ด๋‹ค.

  • Parquet footer์˜ ํ†ต๊ณ„: ํŒŒ์ผ ํ•˜๋‚˜๋ฅผ ์—ด์–ด์•ผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ํŒŒ์ผ์„ ์ฝ๊ธฐ ์‹œ์ž‘ํ•œ ๋‹ค์Œ์˜ ์Šคํ‚ต์ด๋‹ค
  • Iceberg manifest์˜ ํ†ต๊ณ„: ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์—ด๊ธฐ ์ „์— ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์–ด๋–ค ํŒŒ์ผ์„ ์—ด์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋‹จ๊ณ„์˜ ์Šคํ‚ต์ด๋‹ค

์„ธ ๋‹จ๊ณ„๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์ž‘๋™ํ•œ๋‹ค.

  1. manifest ํ†ต๊ณ„: ์ฝ์„ ํŒŒ์ผ ๋ชฉ๋ก ํ™•์ • (ํ…Œ์ด๋ธ” ํฌ๋งท)
  2. footer ํ†ต๊ณ„: ์ฝ์„ Row Group ํ™•์ • (ํŒŒ์ผ ํฌ๋งท)
  3. page index: ์ฝ์„ Page ํ™•์ • (ํŒŒ์ผ ํฌ๋งท)

ํŒŒ์ผ ๋‚ด๋ถ€ ๋ฐฐ์น˜๋Š” ํŒŒ์ผ ํฌ๋งท์ด ๋งก๊ณ  ํŒŒ์ผ ๋ชฉ๋ก ๊ด€๋ฆฌ๋Š” ํ…Œ์ด๋ธ” ํฌ๋งท์ด ๋งก๋Š”๋‹ค.