ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

์ฝ”๋“œ๋ ˆ๋ฒจ์—์„œ ํŒŒ์ผ ์ „์†ก ๋“ฑ local storage(e.g. disk)์—์„œ ํŒŒ์ผ์„ ์ฝ์–ด์„œ ์™ธ๋ถ€๋กœ ๋ณด๋‚ด๋Š” ๋กœ์ง์„ ๊ตฌ์„ฑํ–ˆ๋‹ค๋ฉด ์–ด๋–ค ๊ณผ์ •์„ ๊ฑฐ์น˜๊ฒŒ ๋ ๊นŒ์š”?

๋ณดํ†ต ํฌ๊ฒŒ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋„๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

1. OS kernel context์—์„œ local storage์— ์žˆ๋Š” ํŒŒ์ผ์„ ์ฝ์–ด Read Buffer์— ๋‹ด๊ณ 
2. Application context์—์„œ ํŒŒ์ผ ๋ฐ์ดํ„ฐ๋ฅผ Application Buffer์— ์˜ฌ๋ฆฌ๊ณ  ๋‹ค์‹œ kernel context์˜ Socket Buffer๋กœ ์ „๋‹ฌ
3. NIC Buffer๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€๋กœ ์ „์†ก

 

์—ฌ๊ธฐ์„œ Buffer ๊ฐ„ ์—ฐ๊ฒฐ์— ์ฃผ๋ชฉํ•ด๋ณผ๊นŒ์š”?

์œ„์— ํฌ์ปค์Šคํ•œ ๋ถ€๋ถ„์„ ์‚ดํŽด๋ณด๋ฉด Application Buffer์— ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ ๋” ๋ณต์ œํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทผ๋ฐ ์ด ๋ถ€๋ถ„ ๋‚ญ๋น„๊ฐ™์€๋ฐ ์ข€ ํšจ์œจํ™”ํ•ด๋ณผ ์ˆœ ์—†์„๊นŒ? ๋ผ๋Š” ๊ด€์ ์—์„œ ๋ฐœ์ „๋œ ๊ฒŒ ๋ฐ”๋กœ Zero Copy ์ž…๋‹ˆ๋‹ค.

Zero Copy์— ๋Œ€ํ•ด ๋ณธ๊ฒฉ์ ์œผ๋กœ ์•Œ์•„๋ณด๊ธฐ ์ „์— DMA copy์™€ CPU copy์˜ ์ฐจ์ด์— ๋Œ€ํ•ด์„œ ์งง๊ฒŒ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

DMA(Direct Memory Access) copy vs CPU copy

DMA(Direct Memory Access)๋Š” CPU์˜ ๊ฐœ์ž… ์—†์ด ์ฃผ๋ณ€์žฅ์น˜์™€ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์ด์— ์ง์ ‘ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋Šฅ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

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

๋ฐ˜๋ฉด์— CPU copy๋Š” CPU๋ฅผ ์ ์œ ํ•ด์•ผ ํ•˜๋ฏ€๋กœ ์—ฌ๊ธฐ์„œ ์˜ค๋Š” ์ฐจ์ด์ ์„ ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒ๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ DMA๋Š” ํŠนํžˆ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋งŽ์€ ํ˜„๋Œ€ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์—์„œ ๊ฝค ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ๋ฐ์ดํ„ฐ ์ง‘์•ฝ์ ์ธ ์ž‘์—…๊ณผ ์ž…์ถœ๋ ฅ์ด ๋งŽ์€ ์‹œ์Šคํ…œ์—์„œ๋Š” ๋”์šฑ๋” ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฑธ ์ดํ•ดํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ Zero Copy์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณผ๊นŒ์š”?

Zero Copy

Zero Copy๋Š” ๋ง ๊ทธ๋Œ€๋กœ application buffer๋กœ copyํ•  ํ•„์š” ์—†์ด kernel context์—์„œ ๋ฐ”๋กœ Socket Buffer์— ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

Zero Copy๋ฅผ ์ ์šฉํ•˜๋ฉด ํฌ๊ฒŒ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๋„๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ application context์˜ buffer๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  kernel context์—์„œ๋งŒ ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋™ํ•˜๋Š” ๊ฑธ ํ™•์ธํ•ด๋ณด์„ธ์š”.
(transferTo()๋Š” ๋‹จ์ˆœํžˆ ํ‘œํ˜„์„ ์œ„ํ•ด Java methed name๋ฅผ ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค)

Context Switch์™€ Zero Copy

์œ„์—์„œ ์‚ดํŽด๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฆฌ์†Œ์Šค ์ธก๋ฉด์—์„œ ์ด์ ์ด ์žˆ์„ ๊ฑฐ๋ผ๋Š” ์˜ˆ์ธก์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฐ ๊ตฌ์กฐ๋Š” OS์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ ๊ณผ์ •์—์„œ๋„ ์ด์ ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ ๋ฐฉ์‹์˜ ํŒŒ์ผ ์ „์†ก์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.

์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ user mode์™€ kenel mode๋ฅผ ์˜ค๊ฐ€๋Š” ์Šค์œ„์นญ ํšŸ์ˆ˜๋ฅผ ์ฃผ๋ชฉํ•ด๋ณด๋ฉด,
์ด 4๋ฒˆ์˜ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด Zero Copy์˜ ๊ฒฝ์šฐ๋Š” ์–ด๋–จ๊นŒ์š”?

์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๋ณด๋ฉด Kernel mode์—์„œ ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด 2๋ฒˆ๋งŒ ์ผ์–ด๋‚˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ ‡๋“ฏ Zero Copy๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ์ด ์ค„์–ด๋“ค๋ฉด์„œ ์‹œ์Šคํ…œ ์†๋„ ํ–ฅ์ƒ์˜ ํšจ๊ณผ๋„ ๊ฐ€์ ธ๊ฐˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

Zero Copy์˜ ๋‹จ์ 

Zero Copy๋Š” ์„ฑ๋Šฅ์  ์ด์ ์„ ๊ฐ€์ ธ์˜ค๋Š” ๊ฑด ๋ถ„๋ช…ํ•˜์ง€๋ฉด ํŠน์ • ์š”๊ตฌ์‚ฌํ•ญ์—์„œ๋งŒ ์œ ํšจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ค‘๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์˜ ๊ฒฝ์šฐ๋Š” ์–ด๋–จ๊นŒ์š”?

๋ฐ์ดํ„ฐ ์ˆ˜์ •์„ ์œ„ํ•ด application memory์— ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฎ๊ฒจ์•ผํ•˜๋ฏ€๋กœ application context์˜ buffer๋กœ copy๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ zero copy๋Š” kernel context์˜ buffer์—์„œ๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฎ๊ธฐ๋ฏ€๋กœ ๋ฐ์ดํ„ฐ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋Š” ์•”ํ˜ธํ™”, ์••์ถ• ๋“ฑ์˜ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฑธ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ์ž‘์€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด์„œ๋Š” ์˜คํžˆ๋ ค ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๊ณ ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  NIC(Network Interface Card)๋“ฑ ํ•˜๋“œ์›จ์–ด ์ง€์›์— ํฌ๊ฒŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค. 

์˜ˆ๋ฅผ ๋“ค์–ด NIC๊ฐ€ ์ฒดํฌ์„ฌ ์ƒ์„ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ปค๋„์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ด์„œ ์ œ๋กœ ์นดํ”ผ์˜ ์ด์ ์ด ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
(*์ฒดํฌ์„ฌ: ๋ฐ์ดํ„ฐ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณดํ˜ธํ•˜๊ณ  ์˜ค๋ฅ˜๋ฅผ ๊ฒ€์ถœํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•)

 

Zero Copy์˜ ํ™œ์šฉ ์‚ฌ๋ก€

Zero Copy๋Š” ์ฃผ๋กœ ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ๊ณ ๋ฏผ๋“ค์„ ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง ๋ถ„์•ผ์—์„œ ์ฃผ๋กœ ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.
๋Œ€ํ‘œ์ ์œผ๋กœ kafka์—์„œ๋„ zero copy๋ฅผ ํ™œ์šฉํ•ด ๋ฉ”์‹œ์ง€ ์ „์†ก์„ ํšจ์œจํ™”ํ•ฉ๋‹ˆ๋‹ค.

 

Kotlin S3 upload์— zero copy ์ ์šฉํ•˜๊ธฐ?

์‚ฌ์‹ค ํ˜„ ์‹œ์ ์—์„œ AWS Java/Kotlin SDK๋Š” zero copy๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Java/Kotlin์—์„œ zero copy๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” java.nio.channels ํŒจํ‚ค์ง€๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ, AWS Java/Kotlin SDK์—์„œ๋Š” ์•„์ง ํ•ด๋‹น ํŒจํ‚ค์ง€๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฑธ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.
๊ด€๋ จ ๋‚ด์šฉ์ด ์ข€ ๋” ๊ถ๊ธˆํ•˜์‹  ๋ถ„๋“ค์€ https://github.com/aws/aws-sdk-java-v2/issues/3928 ๋ฅผ ์ฐธ๊ณ ํ•ด ๋ณด์‹œ๋Š” ๊ฑธ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์‹  AWS Java/Kotlin SDK๋Š” ๋ฉ€ํ‹ฐํŒŒํŠธ ์—…๋กœ๋“œ๋ฅผ ์ง€์›ํ•ด์„œ ๋‚˜๋ฆ„์˜ ์ตœ์ ํ™”๊ฐ€ ๋˜์–ด์žˆ๋‹ค๊ณ  ํ•˜๋‹ˆ ๋ฏฟ๊ณ  ์‚ฌ์šฉํ•ด๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค :)

 

 

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์—ฌ๊ธฐ๊นŒ์ง€ zero copy์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ดค์Šต๋‹ˆ๋‹ค.
์ €๋Š” ์ฃผ๋กœ ์„œ๋ฒ„ ๊ฐœ๋ฐœ์„ ํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ตœ๊ทผ์— ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง, AI ๋ถ„์•ผ๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์—ฌ๋Ÿฌ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์–ป๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ณผ์ •์—์„œ ์œ ๊ธฐ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜๋Š” ๊ฒƒ๋“ค์ด ๋ณด์ด๊ณ  ์ข€ ๋” ์ข‹์€ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค๊ณ„ํ•˜๊ธฐ ์œ„ํ•œ ๊ด€์ ๋“ค์„ ์ตํ˜€๊ฐ€๋Š” ๊ฒƒ ๊ฐ™์•„์š”.
์—ฌ๋Ÿฌ๋ถ„๋“ค๋„ ๋‚ด๊ฐ€ ์ž˜ ๋ชจ๋ฅด๋Š” ๋ถ„์•ผ๋„ ์•Œ์•„๋ณด๋ฉด์„œ ์„ธ์ƒ์„ ๋ณด๋Š” ๊ด€์ ์„ ํ’๋ถ€ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์‹œ๋Š” ๊ฑด ์–ด๋–จ๊นŒ์š”?

์ง€๊ธˆ๊นŒ์ง€ ๊ธด ๊ธ€ ์ฝ์–ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค :)

 

Reference

๋ฐ˜์‘ํ˜•