Bigdata, Lakehouse / JDK

Jeonghak Choยท2025๋…„ 5์›” 11์ผ

Bigdata

๋ชฉ๋ก ๋ณด๊ธฐ
23/30

๐Ÿณ๏ธโ€๐ŸŒˆ [๊ถ๊ธˆํ•œ์ ]

  • Kafka, Trino, Spark์—์„œ ์‚ฌ์šฉํ•˜๋Š” JDK๋ฅผ ํ†ต์ผํ•ด์•ผ ํ• ๊นŒ
  • JDK ์–ด๋А ๋ฒ„์ „์„ ์„ ํƒํ•ด์•ผ ํ• ๊นŒ

๐Ÿ”—[๋ชฉ์ฐจ]

JDK ์ฃผ์š” ๋ฒ„์ „ ๋น„๊ต

JDK ๋ฒ„์ „

๋ฒ„์ „์ถœ์‹œ์ผLTS ์—ฌ๋ถ€๊ณต์‹ ์ง€์› ์ข…๋ฃŒ์ฃผ์š” ํŠน์ง•๊ถŒ์žฅ ํ™˜๊ฒฝ
JDK 82014-03Y2030 (Oracle ์œ ๋ฃŒ)๋„๋ฆฌ ์‚ฌ์šฉ๋จ, ๋งŽ์€ ์‹œ์Šคํ…œ๊ณผ ํ˜ธํ™˜๋ ˆ๊ฑฐ์‹œ ์‹œ์Šคํ…œ, ๋ณด์ˆ˜์  ์šด์˜ ํ™˜๊ฒฝ
JDK 112018-09Y2026-09 (๋ฌด๋ฃŒ), 2032 (์œ ๋ฃŒ)๋ชจ๋“ˆ ์‹œ์Šคํ…œ(JPMS), ZGC, TLS 1.3์•ˆ์ •์  ์šด์˜ ์‹œ์Šคํ…œ, ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์™„๋ฃŒ ํ™˜๊ฒฝ
JDK 172021-09Y2029-09 (๋ฌด๋ฃŒ), 2031+ (์œ ๋ฃŒ)Sealed classes, pattern matching, ์„ฑ๋Šฅ ๊ฐœ์„ ์‹ ๊ทœ ์„œ๋น„์Šค, ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ฐ˜ ๋ฐฐํฌ
JDK 212023-09Y2031-09 (๋ฌด๋ฃŒ)Virtual threads, record patterns, ๊ฐ•ํ™”๋œ GC๊ณ ์„ฑ๋Šฅ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค, ์ตœ์‹  JVM ๊ธฐ๋Šฅ ํ™œ์šฉ
JDK 222024-03N (๋น„LTS)6๊ฐœ์›” ์ง€์›Preview ๊ธฐ๋Šฅ ์‹คํ—˜์šฉํ…Œ์ŠคํŠธ, ์—ฐ๊ตฌ์šฉ

Lakehouse์— ์ ํ•ฉํ•œ JDK ๋ฒ„์ „

์šฉ๋„์ถ”์ฒœ JDK ๋ฒ„์ „์ด์œ 
Spark (3.x ~ 4.x)JDK 8 ๋˜๋Š” 11์•ˆ์ •์„ฑ๊ณผ ํ˜ธํ™˜์„ฑ ๋ฉด์—์„œ ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋จ. ์ผ๋ถ€ ์ตœ์‹  ๋ฒ„์ „์€ JDK 17๋„ ์ง€์›ํ•˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„ 11์ด ๊ฐ€์žฅ ์•ˆ์ „ํ•จ.
Trino (>= 380)JDK 17Trino๋Š” JDK 17 ์ด์ƒ์„ ๊ณต์‹์ ์œผ๋กœ ๊ถŒ์žฅํ•จ. JDK 21์—์„œ๋„ ์ž˜ ์ž‘๋™ํ•จ.
IcebergJDK 11 ์ด์ƒIceberg๋Š” Spark ๋˜๋Š” Trino์— ๋”ฐ๋ผ ๋‹ค๋ฆ„. Spark์™€ ํ•จ๊ป˜ ์“ฐ๋ฉด Spark ๊ธฐ์ค€์„ ๋”ฐ๋ผ์•ผ ํ•จ.
FlinkJDK 8 ๋˜๋Š” 11JDK 17๋„ ์ผ๋ถ€ ์ง€์›๋˜์ง€๋งŒ ๋ณด์ˆ˜์ ์œผ๋กœ๋Š” 8 ๋˜๋Š” 11์ด ์ผ๋ฐ˜์ .
Hive MetastoreJDK 8 ๋˜๋Š” 11์˜ค๋ž˜๋œ ์ฝ”๋“œ๋ฒ ์ด์Šค์ด๋ฏ€๋กœ JDK 11๊นŒ์ง€๊ฐ€ ๊ฐ€์žฅ ์•ˆ์ „ํ•จ.
KafkaJDK 11 (์ตœ์‹  ๋ฒ„์ „์€ JDK 17๋„ ๊ฐ€๋Šฅ)Kafka๋„ 11์—์„œ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘. ์ผ๋ถ€ ์ตœ์‹  ๋ฆด๋ฆฌ์Šค๋Š” JDK 17๊นŒ์ง€๋„ ์ง€์›.

JDK ๋ฐฐํฌํŒ

๋ฐฐํฌํŒ์„ค๋ช…
Temurin (Adoptium)๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์•ˆ์ •์ ์ธ ์˜คํ”ˆ์†Œ์Šค JDK. ๊ธฐ์—… ๋ฐ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ์—์„œ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ๋จ.
OpenJDK (ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์„ค์น˜)๊ณต์‹ JDK. ๋‹ค๋งŒ ์ผ๋ถ€ ํŒจํ‚ค์ง€๋Š” ์—…๋ฐ์ดํŠธ๊ฐ€ ๋А๋ฆด ์ˆ˜ ์žˆ์Œ.
Amazon CorrettoAWS ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ ์‹œ ์ถ”์ฒœ๋จ. ์žฅ๊ธฐ ์ง€์›(LTS) ์ œ๊ณต.
Zulu OpenJDK (Azul)๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ์— ๋Œ€ํ•œ ํญ๋„“์€ ์ง€์›.

Lakehouse ๊ตฌ์„ฑ์š”์†Œ๋ณ„ JDK 21 ํ˜ธํ™˜์„ฑ

์ปดํฌ๋„ŒํŠธJDK 21 ์ง€์› ํ˜„ํ™ฉ (2025 ๊ธฐ์ค€)์ฃผ์˜์‚ฌํ•ญ
Trino (v466)๊ณต์‹์ ์œผ๋กœ JDK 21 ์ง€์›Trino๋Š” ๋น ๋ฅด๊ฒŒ ์ตœ์‹  JDK ์ง€์›ํ•จ.
Apache IcebergSpark ๊ธฐ๋ฐ˜์ด๋ผ๋ฉด Spark ๊ธฐ์ค€ ๋”ฐ๋ฆ„Spark 3.5+์—์„œ JDK 21 ์ผ๋ถ€ ์ง€์›. Spark < 3.5๋Š” ์ง€์› ๋ถˆํ™•์‹ค.
Apache SparkSpark 3.5 ์ด์ƒ ์ผ๋ถ€ ํ˜ธํ™˜, ์•ˆ์ •์„ฑ ์ด์Šˆ ์กด์žฌ์•„์ง ์‹ค๋ฌด์—์„œ Spark+JDK 21 ์กฐํ•ฉ์€ ๋“œ๋ฌพ.
Hive Metastore๊ณต์‹์ ์œผ๋กœ JDK 11 ์ดํ•˜ ๊ถŒ์žฅ์˜ค๋ž˜๋œ ์ฝ”๋“œ๋ฒ ์ด์Šค. JDK 21์—์„œ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์—๋Ÿฌ ๋ฐœ์ƒ ๊ฐ€๋Šฅ.
Apache FlinkJDK 21์€ ์‹คํ—˜์  ์ˆ˜์ค€๋Œ€๋ถ€๋ถ„ JDK 11๊นŒ์ง€ ์•ˆ์ •.
KafkaJDK 17๊นŒ์ง€ ๊ด‘๋ฒ”์œ„ ๊ฒ€์ฆ, 21์€ ์‹คํ—˜์ ์ผ๋ถ€ JDK 21 ๋ฌธ์ œ ๋ณด๊ณ ๋จ.

JDK 21์ด ๊ณ ์„ฑ๋Šฅ์ธ ์ด์œ 

JDK 21์ด ๊ณ ์„ฑ๋Šฅ์ธ ์ด์œ ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ JVM ์ˆ˜์ค€์˜ ํ˜์‹ ์  ๊ธฐ๋Šฅ๊ณผ ์–ธ์–ด ๊ฐœ์„ ์ด ํฌํ•จ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ํŠนํžˆ ๋Œ€๊ทœ๋ชจ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ํ˜„๋Œ€์  ์„œ๋น„์Šค ํ™˜๊ฒฝ(API ์„œ๋ฒ„, ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค, Kafka ์†Œ๋น„์ž ๋“ฑ)์— ๋งค์šฐ ์ž˜ ๋งž๋‹ค.

Virtual Threads (๊ฐ€์ƒ ์Šค๋ ˆ๋“œ, Project Loom)

  • ๊ฐ€์žฅ ํฐ ๋ณ€ํ™”, ๊ธฐ์กด ์Šค๋ ˆ๋“œ ๋ชจ๋ธ์„ ํ˜์‹ ์ ์œผ๋กœ ๊ฐœ์„ 
  • ๊ธฐ์กด java.lang.Thread๋Š” OS ์ปค๋„ ์Šค๋ ˆ๋“œ์— ๋งคํ•‘๋˜์–ด ์ˆ˜์ฒœ ๊ฐœ ์ด์ƒ ์ƒ์„ฑ ์‹œ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ ๋ฐœ์ƒ
  • Virtual Thread๋Š” JVM ๋‚ด๋ถ€ ์Šค์ผ€์ค„๋ง ๊ธฐ๋ฐ˜ โ†’ ์ˆ˜๋ฐฑ๋งŒ ๊ฐœ ์ƒ์„ฑ ๊ฐ€๋Šฅ
  • ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ์˜ค๋ฒ„ํ—ค๋“œ ๊ฐ์†Œ, Thread starvation ํ˜„์ƒ ๊ฐ์†Œ
  • I/O ์ค‘์‹ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (์˜ˆ: HTTP ์„œ๋ฒ„, DB ์—ฐ๋™, Kafka consumer)์—์„œ Thread ์ˆ˜๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ์ค„์—ฌ์คŒ
  • ๊ธฐ์กด Thread๋กœ 1๋งŒ ๊ฐœ ์š”์ฒญ ์ฒ˜๋ฆฌ ์‹œ CPU ์‚ฌ์šฉ๋ฅ  80%+, Virtual Thread๋กœ 1๋งŒ ๊ฐœ ์ฒ˜๋ฆฌ ์‹œ CPU 30% ์ˆ˜์ค€, TPS 2~4๋ฐฐ ์ƒ์Šน

GC ๊ฐœ์„  (Garbage Collector ์ตœ์ ํ™”)

  • G1 GC: ๊ธฐ๋ณธ GC๋กœ ์„ค์ •๋˜๋ฉฐ, pause time ์˜ˆ์ธก ๊ฐ€๋Šฅ
  • ZGC: low-latency GC๋กœ 10ms ์ด๋‚ด GC pause ์ œ๊ณต
  • Shenandoah: Red Hat ์ง€์›, ๋ณ‘ํ–‰ ์ฒ˜๋ฆฌ ๊ฐ•ํ™”

G1/ZGC๋Š” JDK 21์—์„œ ์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ์ด ๊ทน๋Œ€ํ™”๋จ:GC throughput 5~10% ์ฆ๊ฐ€, GC pause time์€ ๋” ์งง์•„์ง (ํŠนํžˆ ZGC)

๊ธฐํƒ€ JVM ์„ฑ๋Šฅ ์ตœ์ ํ™”

  • JIT Compiler ๊ฐœ์„  (C2): ๋ฃจํ”„ ์ตœ์ ํ™”, ๋ฉ”์„œ๋“œ ์ธ๋ผ์ด๋‹ ํ–ฅ์ƒ
  • Escape Analysis ํ–ฅ์ƒ: ๊ฐ์ฒด๋ฅผ ํž™์ด ์•„๋‹Œ ์Šคํƒ์— ํ• ๋‹น โ†’ GC ๋ถ€๋‹ด ๊ฐ์†Œ
  • String Templates (Preview): ๋ฌธ์ž์—ด ๊ฒฐํ•ฉ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  • Pattern Matching๊ณผ ๊ฐ™์€ ์–ธ์–ด์  ๊ตฌ์กฐ๋Š” ์ฝ”๋“œ์˜ ํšจ์œจ์„ฑ๊ณผ ๋ช…ํ™•์„ฑ ์ฆ๊ฐ€

Native Memory Tracking, CDS (Class Data Sharing) ๊ฐœ์„ 

  • CDS: ๊ณตํ†ต ํด๋ž˜์Šค ์˜์—ญ์„ ๊ณต์œ ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ๊ฐ„ ๋‹จ์ถ•
  • Native Memory Tracking: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํŒŒ์•…๊ณผ ํŠœ๋‹์— ์œ ๋ฆฌ

์ตœ์ ์˜ ์ปจํ…Œ์ด๋„ˆ ํ˜ธํ™˜์„ฑ

JDK 21์€ ์ปจํ…Œ์ด๋„ˆ ๋Ÿฐํƒ€์ž„(Kubernetes ๋“ฑ)์˜ CPU/Memory limits๋ฅผ ์ •ํ™•ํžˆ ๊ฐ์ง€ํ•˜๊ณ  JVM ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ž๋™ ์กฐ์ •

์˜ˆ: -XX:+UseContainerSupport๊ฐ€ ์ž๋™ ํ™œ์„ฑํ™”

์ปจํ…Œ์ด๋„ˆ ์ตœ์ ํ™”๋œ GC ๋™์ž‘๊ณผ CRaC(Coordinated Restore at Checkpoint) ๋“ฑ ์ตœ์‹  ๊ธฐ๋Šฅ ์ผ๋ถ€๋„ ์ง€์› ์˜ˆ์ •

Lakehouse์—์„œ JDK ์„ ์ •

๊ตฌ์„ฑ ์š”์†ŒJDK ๋ฒ„์ „GC ์ถ”์ฒœ๋น„๊ณ 
TrinoJDK 17G1GC์•ˆ์ •์„ฑ๊ณผ ์„ฑ๋Šฅ ๊ท ํ˜•. ZGC๋Š” ์‹คํ—˜์ ์œผ๋กœ ๊ฐ€๋Šฅ
SparkJDK 17G1GCStructured Streaming์—์„œ ์•ˆ์ •์  ๋™์ž‘. ํŠนํžˆ IcebergSink
IcebergN/A (๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)JVM ๊ธฐ๋ฐ˜ ์•ฑ์— ๋”ฐ๋ฆ„Spark/Trino๊ฐ€ ๊ด€๋ฆฌ
MinIOGo ์–ธ์–ด ๊ธฐ๋ฐ˜JVM ์•„๋‹˜JDK/GC์™€ ๋ฌด๊ด€

Virtual Thread

Virtual Thread๋Š” Java 19๋ถ€ํ„ฐ ํ”„๋ฆฌ๋ทฐ๋กœ ๋„์ž…๋˜์—ˆ๊ณ , Java 21์—์„œ ์ •์‹ ๊ธฐ๋Šฅ์œผ๋กœ ์ฑ„ํƒ๋œ lightweight thread์ด๋‹ค. ๊ธฐ์กด์˜ Platform Thread์™€๋Š” ๋‹ค๋ฅด๊ฒŒ, OS ์Šค๋ ˆ๋“œ์— ์ง์ ‘ ๋งคํ•‘๋˜์ง€ ์•Š์•„์„œ ์ˆ˜์ฒœ, ์ˆ˜๋งŒ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•ด๋„ ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

๊ตฌ๋ถ„ Platform Thread Virtual Thread
๊ธฐ๋ฐ˜ OS ์Šค๋ ˆ๋“œ Java ์Šค์ผ€์ค„๋Ÿฌ์— ์˜ํ•ด ๊ด€๋ฆฌ
์ƒ์„ฑ ๋น„์šฉ ๋†’์Œ ๋‚ฎ์Œ
๋™์‹œ ์‹คํ–‰ ์ˆ˜ ์ œํ•œ์  ์ˆ˜์ฒœ~์ˆ˜๋งŒ ๊ฐœ๋„ ๊ฐ€๋Šฅ
๋ชฉ์  ์ „ํ†ต์  ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋Œ€๊ทœ๋ชจ ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ (ex. ์›น์„œ๋ฒ„ ์š”์ฒญ ํ•ธ๋“ค๋ง ๋“ฑ)

public class ManyVirtualThreads {
    public static void main(String[] args) throws InterruptedException {
        int threadCount = 10_000;

        for (int i = 0; i < threadCount; i++) {
            Thread.startVirtualThread(() -> {
                try {
                    Thread.sleep(100); // ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์‹œ ์œ ์šฉ
                    System.out.println("Thread: " + Thread.currentThread());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        Thread.sleep(2000); // ์ „์ฒด ์‹คํ–‰ ๋Œ€๊ธฐ
    }
}

Virtual thread๋Š” ๋ธ”๋กœํ‚น IO๋ณด๋‹ค๋Š” ๋น„๋™๊ธฐ/๋…ผ๋ธ”๋กœํ‚น IO์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ๋” ํฐ ํšจ๊ณผ๋ฅผ ๋ณธ๋‹ค.synchronized ๊ฐ™์€ ๊ธฐ์กด ๋ฝ ๋ฉ”์ปค๋‹ˆ์ฆ˜์€ virtual thread์˜ ์žฅ์ ์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

Java๊ฐ€ ์šด์˜์ฒด์ œ(OS) ์ˆ˜์ค€์—์„œ์˜ ์Šค๋ ˆ๋“œ ๊ด€๋ฆฌ์—์„œ JVM ๋‚ด๋ถ€ ์Šค์ผ€์ค„๋ง์œผ๋กœ ๋ฐ”๋€Œ์—ˆ๋‹ค.

๊ธฐ์กด Platform Thread์˜ ํ•œ๊ณ„

Platform Thread๋Š” OS ์Šค๋ ˆ๋“œ 1:1 ๋งคํ•‘ ๊ตฌ์กฐ์ด๋‹ค. new Thread()๋กœ ๋งŒ๋“ค๋ฉด JVM์ด OS์—๊ฒŒ ์Šค๋ ˆ๋“œ๋ฅผ ์š”์ฒญํ•ด์„œ ์ปค๋„ ๋ฆฌ์†Œ์Šค๊ฐ€ ํ• ๋‹น๋œ๋‹ค.

์ด๋กœ ์ธํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ์ด ์ƒ๊ธด๋‹ค.

  • ์ƒ์„ฑ/์ œ๊ฑฐ ๋น„์šฉ์ด ๋น„์Œˆ (์‹œ์Šคํ…œ ์ฝœ์ด ํ•„์š”)
  • ์Šค๋ ˆ๋“œ ์ˆ˜ ์ œํ•œ์ด ์žˆ์Œ (๋ช‡ ์ฒœ ๊ฐœ ์ˆ˜์ค€์ด ํ•œ๊ณ„)
  • ๋ธ”๋กœํ‚น I/O๋‚˜ Thread.sleep()์€ OS ์Šค๋ ˆ๋“œ๋ฅผ ์ ์œ ํ•จ (๋‚ญ๋น„!)

Virtual Thread์˜ ์›๋ฆฌ

Virtual Thread๋Š” JVM ๋‚ด๋ถ€์˜ lightweight ์Šค๋ ˆ๋“œ์ด๋‹ค. OS ์Šค๋ ˆ๋“œ์— ์ง์ ‘ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๊ณ , JVM์ด ๋ช‡ ๊ฐœ์˜ ๊ณ ์ •๋œ carrier thread๋ฅผ ํ†ตํ•ด ๋งŽ์€ virtual thread๋ฅผ multiplexing ํ•ด์ค€๋‹ค.

  • Java Continuations (Continuation Stack):
    ์‹คํ–‰ ์ค‘์ด๋˜ Virtual Thread์˜ ์Šคํƒ ํ”„๋ ˆ์ž„์„ ์ €์žฅํ•˜๊ณ  ์ค‘๋‹จํ•  ์ˆ˜ ์žˆ์Œ.
    ์ฆ‰, Thread.sleep() ํ•˜๋ฉด ์Šคํƒ ์ €์žฅํ•˜๊ณ , carrier thread๋Š” ๋‹ค๋ฅธ virtual thread ์ฒ˜๋ฆฌํ•˜๋Ÿฌ ๊ฐ.

  • User-mode Scheduling:
    OS ๋Œ€์‹  JVM์ด thread ์ „ํ™˜์„ ๋‹ด๋‹น โ†’ context switching์ด ๋งค์šฐ ๋น ๋ฆ„.

  • Non-blocking APIs์™€์˜ ํ†ตํ•ฉ:
    ๊ธฐ์กด blocking I/O API (sleep, Socket.read)๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” JVM์ด ์•Œ์•„์„œ virtual thread friendlyํ•˜๊ฒŒ ๋™์ž‘์‹œํ‚ด.

virtual thread ์‚ฌ์šฉ ์œ ์˜์ 

Block์ด ์ผ์–ด๋‚˜๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ํ˜ธ์ถœ์€ ๋ฌธ์ œ ์†Œ์ง€

Virtual Thread๋Š” Java ์ฝ”๋“œ ๋‚ด์˜ ๋ธ”๋กœํ‚น์€ ๊ฐ์ง€ํ•˜๊ณ  ํšŒํ”ผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, JNI ํ˜ธ์ถœ, ํŒŒ์ผ I/O, native socket, ๋™๊ธฐ JDBC ๋“ฑ์€ OS ์Šค๋ ˆ๋“œ ์ˆ˜์ค€์—์„œ ๋ธ”๋กœํ‚น๋˜์–ด Virtual Thread์˜ ์žฅ์ ์ด ์‚ฌ๋ผ์ง„๋‹ค.

virtualThreadExecutor.submit(() -> {
    // ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” native ๋ธ”๋กœํ‚น ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ -> ์‹ค์ œ OS thread๊ฐ€ ์ ์œ ๋จ
    someBlockingNativeFunction(); 
});

๊ฐ€๋Šฅํ•˜๋ฉด ๋น„๋™๊ธฐ I/O ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค.

Thread-local, InheritableThreadLocal ๊ด€๋ จ ๋™์ž‘ ์ฐจ์ด

Virtual Thread๋Š” thread-local์„ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฒฉ๋ฆฌํ•˜๋ฏ€๋กœ ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
ThreadLocal ๋Œ€์‹  ScopedValue ์‚ฌ์šฉํ•œ๋‹ค. (Java 21๋ถ€ํ„ฐ ํ”„๋ฆฌ๋ทฐ)

๋””๋ฒ„๊น…/๋ชจ๋‹ˆํ„ฐ๋ง ๋„๊ตฌ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ

๊ธฐ์กด APM, thread dump ๋„๊ตฌ๋“ค์ด ์ˆ˜๋งŒ ๊ฐœ์˜ Virtual Thread๋ฅผ ๊ฐ๋‹น ๋ชป ํ•˜๊ฑฐ๋‚˜ ์ •ํ™•ํ•œ ์ •๋ณด ์ œ๊ณต ๋ชปํ•œ๋‹ค.
์ตœ์‹  ๋„๊ตฌ jcmd, jfr ๋“ฑ์œผ๋กœ ๋ถ„์„ํ•œ๋‹ค.

Virtual Thread๋Š” CPU-bound์—๋Š” ํฐ ๋„์›€ ์•ˆ ๋จ

Virtual Thread๋Š” I/O-bound ์ž‘์—… ์ตœ์ ํ™”์— ํƒ์›”ํ•˜๋‚˜ CPU-bound ์ž‘์—…์€ ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜ ๋Š˜๋ฆฐ๋‹ค๊ณ  ์„ฑ๋Šฅ์ด ์˜ค๋ฅด์ง€ ์•Š์Œ (์˜คํžˆ๋ ค ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๋น„์šฉ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ)

ExecutorService๊ฐ€ ๊ธฐ์กด ์ฝ”๋“œ์™€ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ์Œ

  • ์ผ๋ถ€ ํ”„๋ ˆ์ž„์›Œํฌ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ Executors.newCachedThreadPool()์„ Virtual Thread๋กœ ๋ฐ”๊ฟจ์„ ๋•Œ, ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฌด์ œํ•œ ์ƒ์„ฑ๋˜์–ด ์‹œ์Šคํ…œ ๊ณผ๋ถ€ํ•˜ ๋ฐœ์ƒ ๊ฐ€๋Šฅ์„ฑ ์žˆ๋‹ค.
  • Executors.newVirtualThreadPerTaskExecutor() ์‚ฌ์šฉ ์‹œ ๋ถ€ํ•˜๋ฅผ ๊ณ ๋ คํ•ด ์ œํ•œ ์„ค์ • ํ•„์š”

0๊ฐœ์˜ ๋Œ“๊ธ€