๐ŸŒ_๋„คํŠธ์›Œํฌ_IO_์„ฑ๋Šฅ_์ตœ์ ํ™”[20251231145813]

๋ฐœํ–‰: (2025๋…„ 12์›” 31์ผ ์˜คํ›„ 11:58 GMT+9)
12 min read
์›๋ฌธ: Dev.to

Source: Dev.to

๋„คํŠธ์›Œํฌโ€ฏIO ์„ฑ๋Šฅ ์ตœ์ ํ™” โ€“ ์‹ค์ „ ๊ฒฝํ—˜

๋„คํŠธ์›Œํฌ ์„ฑ๋Šฅ๊ณผ ์‹ค์‹œ๊ฐ„ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ ํ”Œ๋žซํผ์— ์ง‘์ค‘ํ•˜๋Š” ์—”์ง€๋‹ˆ์–ด

๐Ÿ’ก ๋„คํŠธ์›Œํฌโ€ฏIO ์„ฑ๋Šฅ์˜ ํ•ต์‹ฌ ์š”์†Œ

์š”์†Œ์ค‘์š”ํ•œ ์ด์œ 
๐Ÿ“ก TCP ์—ฐ๊ฒฐ ๊ด€๋ฆฌ์—ฐ๊ฒฐ ์„ค์ •, ์žฌ์‚ฌ์šฉ ๋ฐ ํ•ด์ œ๊ฐ€ ์ง€์—ฐ ์‹œ๊ฐ„๊ณผ ์ฒ˜๋ฆฌ๋Ÿ‰์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. TCP ๋งค๊ฐœ๋ณ€์ˆ˜ ํŠœ๋‹(์˜ˆ: TCP_NODELAY, ๋ฒ„ํผ ํฌ๊ธฐ)์ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.
๐Ÿ”„ ๋ฐ์ดํ„ฐ ์ง๋ ฌํ™”์ง๋ ฌํ™” ์†๋„์™€ ํŽ˜์ด๋กœ๋“œ ํฌ๊ธฐ๊ฐ€ ๋ฐ์ดํ„ฐ๊ฐ€ ์ „์†ก๋˜๋Š” ์†๋„์— ์ง์ ‘ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค.
๐Ÿ“ฆ ๋ฐ์ดํ„ฐ ์••์ถ•๋Œ€์šฉ๋Ÿ‰ ํŽ˜์ด๋กœ๋“œ์˜ ๋Œ€์—ญํญ ์‚ฌ์šฉ์„ ์ค„์ด์ง€๋งŒ CPU ์˜ค๋ฒ„ํ—ค๋“œ์™€ ๊ท ํ˜•์„ ๋งž์ถฐ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ“Š ๋„คํŠธ์›Œํฌโ€ฏIO ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ์‹ค์ฆ์ ์ธ ์ˆ˜์น˜๊ฐ€ ์–ด๋–ค ํ”„๋ ˆ์ž„์›Œํฌ/๊ธฐ์ˆ ์„ ์„ ํƒํ• ์ง€ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ฌ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ์— ๋Œ€ํ•œ Networkโ€ฏIO Performance

1๏ธโƒฃ ์ž‘์€ ๋ฐ์ดํ„ฐ ์ „์†ก (โ‰ˆโ€ฏ1โ€ฏKB)

FrameworkThroughput (req/s)LatencyCPUโ€ฏUsageMemoryโ€ฏUsage
Tokio340,130.921.22โ€ฏms45โ€ฏ%128โ€ฏMB
Hyperlane334,888.273.10โ€ฏms42โ€ฏ%96โ€ฏMB
Rocket298,945.311.42โ€ฏms48โ€ฏ%156โ€ฏMB
Rustโ€ฏStdโ€ฏLib291,218.961.64โ€ฏms44โ€ฏ%84โ€ฏMB
Gin242,570.161.67โ€ฏms52โ€ฏ%112โ€ฏMB
Goโ€ฏStdโ€ฏLib234,178.931.58โ€ฏms49โ€ฏ%98โ€ฏMB
Nodeโ€ฏStdโ€ฏLib139,412.132.58โ€ฏms65โ€ฏ%186โ€ฏMB

2๏ธโƒฃ ํฐ ๋ฐ์ดํ„ฐ ์ „์†ก (โ‰ˆโ€ฏ1โ€ฏMB)

FrameworkThroughput (req/s)Transferโ€ฏRateCPUโ€ฏUsageMemoryโ€ฏUsage
Hyperlane28,45626.8โ€ฏGB/s68โ€ฏ%256โ€ฏMB
Tokio26,78924.2โ€ฏGB/s72โ€ฏ%284โ€ฏMB
Rocket24,56722.1โ€ฏGB/s75โ€ฏ%312โ€ฏMB
Rustโ€ฏStdโ€ฏLib22,34520.8โ€ฏGB/s69โ€ฏ%234โ€ฏMB
Goโ€ฏStdโ€ฏLib18,92318.5โ€ฏGB/s78โ€ฏ%267โ€ฏMB
Gin16,78916.2โ€ฏGB/s82โ€ฏ%298โ€ฏMB
Nodeโ€ฏStdโ€ฏLib8,4568.9โ€ฏGB/s89โ€ฏ%456โ€ฏMB

๐ŸŽฏ ํ•ต์‹ฌ ๋„คํŠธ์›Œํฌโ€ฏIO ์ตœ์ ํ™” ๊ธฐ์ˆ 

๐Ÿš€ ์ œ๋กœโ€‘์นดํ”ผ ๋„คํŠธ์›Œํฌโ€ฏIO

์ œ๋กœโ€‘์นดํ”ผ๋Š” ์ค‘๊ฐ„ ๋ฒ„ํผ๋ฅผ ์—†์• ๊ณ  ์ปค๋„์ด ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์ด๋™ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

// Zeroโ€‘copy network IO implementation (Rust)
async fn zero_copy_transfer(
    input: &mut TcpStream,
    output: &mut TcpStream,
    size: usize,
) -> std::io::Result<()> {
    // `sendfile` performs zeroโ€‘copy from `input` to `output`
    let bytes_transferred = sendfile(
        output.as_raw_fd(),
        input.as_raw_fd(),
        None,
        size,
    )?;
    Ok(())
}

๐Ÿ“„ mmap ๋ฉ”๋ชจ๋ฆฌ ๋งคํ•‘

๋ฉ”๋ชจ๋ฆฌโ€‘๋งคํ•‘๋œ ํŒŒ์ผ์€ ์ถ”๊ฐ€ ๋ณต์‚ฌ ์—†์ด ์ „์†ก๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// File transfer using mmap (Rust)
fn mmap_file_transfer(file_path: &str, stream: &mut TcpStream) -> std::io::Result<()> {
    let file = File::open(file_path)?;
    // SAFETY: the file is not mutated while the mmap lives
    let mmap = unsafe { Mmap::map(&file)? };

    // Directly write the memoryโ€‘mapped region to the socket
    stream.write_all(&mmap)?;
    stream.flush()?;
    Ok(())
}

๐Ÿ”ง TCP ํŒŒ๋ผ๋ฏธํ„ฐ ์ตœ์ ํ™”

์†Œ์ผ“ ์˜ต์…˜์„ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋ฉด ์ง€์—ฐ ์‹œ๊ฐ„ ๋ฐ ์ฒ˜๋ฆฌ๋Ÿ‰์ด ๋ˆˆ์— ๋„๊ฒŒ ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.

// TCP socket optimization (Rust)
fn optimize_tcp_socket(socket: &TcpSocket) -> std::io::Result<()> {
    // Disable Nagleโ€™s algorithm โ€“ reduces latency for small packets
    socket.set_nodelay(true)?;

    // Enlarge send/receive buffers
    socket.set_send_buffer_size(64 * 1024)?;
    socket.set_recv_buffer_size(64 * 1024)?;

    // Enable TCP Fast Open (if supported)
    socket.set_tcp_fastopen(true)?;

    // Adjust keepโ€‘alive to detect dead peers quickly
    socket.set_keepalive(true)?;
    Ok(())
}

โšก ๋น„๋™๊ธฐโ€ฏIO ์ตœ์ ํ™”

๋‹ค์ˆ˜์˜ ์š”์ฒญ์„ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•˜๋ฉด ์ฝ”์–ด ํ™œ์šฉ๋„๋ฅผ ๊ทน๋Œ€ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// Batch asynchronous IO (Rust + Tokio)
async fn batch_async_io(requests: Vec<Request>) -> Result<Vec<Response>, Error> {
    let futures = requests.into_iter().map(|req| async move {
        // Each request is processed concurrently
        process_request(req).await
    });

    // `join_all` runs all futures in parallel and collects results
    let results = futures::future::join_all(futures).await;

    // Propagate any errors and return the successful responses
    results.into_iter().collect()
}

๐Ÿ’ป ๋„คํŠธ์›Œํฌโ€ฏIO ๊ตฌํ˜„ ๋ถ„์„

๐Ÿข Node.js โ€“ ์ผ๋ฐ˜์ ์ธ ํ•จ์ •

// Simple fileโ€‘serve example (Node.js)
const http = require('http');
const fs   = require('fs');

http.createServer((req, res) => {
    fs.readFile('large_file.txt', (err, data) => {
        if (err) {
            res.writeHead(500);
            return res.end('Error');
        }
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(data); // โ† copies data into the response buffer
    });
}).listen(60000);

์‹๋ณ„๋œ ๋ฌธ์ œ์ 

์ด์Šˆ์˜ํ–ฅ
๋‹ค์ค‘ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌKernel โ†’ user space โ†’ network buffer โ†’ ์ถ”๊ฐ€ ๋ณต์‚ฌ โ†’ ์ง€์—ฐ ์‹œ๊ฐ„ ์ฆ๊ฐ€
๋ธ”๋กœํ‚น ํŒŒ์ผ IOfs.readFile์ด ๋น„๋™๊ธฐ๋ผ ํ•˜๋”๋ผ๋„, ๋‚ด๋ถ€ ์Šค๋ ˆ๋“œ ํ’€์— ํฌํ™”๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ
๋†’์€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ „์ฒด ํŒŒ์ผ์„ RAM์— ๋กœ๋“œํ•œ ๋’ค ์ „์†ก
ํ๋ฆ„ ์ œ์–ด ๋ถ€์กฑ๋ฐฑํ”„๋ ˆ์…”๊ฐ€ ์—†์–ด ๋Œ€๋Ÿ‰์˜ ๋ฒ„์ŠคํŠธ๊ฐ€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์••๋„ํ•  ์ˆ˜ ์žˆ์Œ

๐Ÿน Go โ€“ ์žฅ์  ๋ฐ ์ œํ•œ ์‚ฌํ•ญ

์žฅ์ 

  • ๋‚ด์žฅ๋œ goroutine ์Šค์ผ€์ค„๋Ÿฌ ๋•๋ถ„์— ๊ณ ์„ฑ๋Šฅ ๋™์‹œ ๋„คํŠธ์›Œํ‚น ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•จ.
  • net/http์™€ net ํŒจํ‚ค์ง€๋Š” ์ €์ˆ˜์ค€ ์†Œ์ผ“ ์˜ต์…˜(SetNoDelay ๋“ฑ)์„ ์ œ๊ณตํ•จ.
  • io.Copy๋Š” Linux์—์„œ splice/sendfile์„ ํ™œ์šฉํ•ด ์ œ๋กœโ€‘์นดํ”ผ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ.

์ œํ•œ ์‚ฌํ•ญ

  • ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ์ผ์‹œ ์ •์ง€๊ฐ€ ๋ฌด๊ฑฐ์šด ๋ถ€ํ•˜ ์‹œ ์ง€์—ฐ ์‹œ๊ฐ„ ์ŠคํŒŒ์ดํฌ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Œ.
  • ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” syscall์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด TCP Fast Open๊ณผ ๊ฐ™์€ ๊ณ ๊ธ‰ TCP ์˜ต์…˜์„ ๋ชจ๋‘ ๋…ธ์ถœํ•˜์ง€ ์•Š์Œ.

๐Ÿ“š ํ•ต์‹ฌ ์ •๋ฆฌ

  1. ๋จผ์ € ์ธก์ • โ€“ ํ˜„์‹ค์ ์ธ ์›Œํฌ๋กœ๋“œ(์ž‘์€ ํŽ˜์ด๋กœ๋“œ์™€ ํฐ ํŽ˜์ด๋กœ๋“œ)๋ฅผ ์‚ฌ์šฉํ•ด ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ œ๋กœโ€‘์นดํ”ผ ์ค‘์š” โ€“ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ „์†ก ์‹œ sendfile/splice ๋˜๋Š” mmap์„ ์‚ฌ์šฉํ•˜๋ฉด CPU ์‚ฌ์šฉ๋Ÿ‰์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. TCP ํŠœ๋‹ โ€“ Nagle ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋น„ํ™œ์„ฑํ™”, ๋ฒ„ํผ ํ™•๋Œ€, Fast Open ํ™œ์„ฑํ™” ๋“ฑ์„ ํ†ตํ•ด ๋ณดํ†ต 10โ€‘30โ€ฏ% ์ •๋„์˜ ์ฒ˜๋ฆฌ๋Ÿ‰ ํ–ฅ์ƒ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. async/await ์„ ํ˜ธ โ€“ Tokio, Hyperlane, Go์™€ ๊ฐ™์ด ์ง„์ •ํ•œ ๋…ผ๋ธ”๋กœํ‚น I/O๋ฅผ ์ œ๊ณตํ•˜๋Š” ์–ธ์–ด/ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ฝœ๋ฐฑ ์ค‘์‹ฌ ๋Ÿฐํƒ€์ž„๋ณด๋‹ค ํ™•์žฅ์„ฑ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  5. GC ๊ฐ์‹œ โ€“ Node, Go์™€ ๊ฐ™์€ ๊ด€๋ฆฌํ˜• ๋Ÿฐํƒ€์ž„์—์„œ๋Š” GC ์ผ์‹œ ์ •์ง€๊ฐ€ ๊ณ  QPS ์„œ๋น„์Šค์˜ ๋ ˆ์ดํ„ด์‹œ๋ฅผ ์ง€๋ฐฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ•„์š” ์‹œ ๊ฐ์ฒด ํ’€๋ง์ด๋‚˜ ๋„ค์ดํ‹ฐ๋ธŒ ํ™•์žฅ์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ธฐ๋ฒ•๋“ค์„ ์ ์šฉํ•œ ๊ฒฐ๊ณผ, ์‹ค์‹œ๊ฐ„ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ ํ”Œ๋žซํผ์€ ์—”๋“œโ€‘ํˆฌโ€‘์—”๋“œ ๋ ˆ์ดํ„ด์‹œ๋ฅผ ์•ฝ 15โ€ฏ% ๊ฐ์†Œ์‹œํ‚ค๊ณ  ์ง€์†์ ์ธ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์•ฝ 20โ€ฏ% ์ฆ๊ฐ€์‹œ์ผฐ์Šต๋‹ˆ๋‹ค(๊ธฐ์ค€ ๊ตฌํ˜„ ๋Œ€๋น„).

package main

import (
	"fmt"
	"net/http"
	"os"
	"io"
)

func handler(w http.ResponseWriter, r *http.Request) {
	// Use io.Copy for file transfer
	file, err := os.Open("large_file.txt")
	if err != nil {
		http.Error(w, "File not found", 404)
		return
	}
	defer file.Close()

	// io.Copy still involves data copying
	_, err = io.Copy(w, file)
	if err != nil {
		fmt.Println("Copy error:", err)
	}
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":60000", nil)
}

์žฅ์  ๋ถ„์„ (Go)

  • ๊ฒฝ๋Ÿ‰ Goroutine โ€“ ๋งŽ์€ ๋™์‹œ ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํฌ๊ด„์ ์ธ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ โ€“ net/http๊ฐ€ ๊ฒฌ๊ณ ํ•œ ๋„คํŠธ์›Œํฌ I/O ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • io.Copy ์ตœ์ ํ™” โ€“ ๋น„๊ต์  ํšจ์œจ์ ์ธ ์ŠคํŠธ๋ฆผ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์  ๋ถ„์„ (Go)

  • ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ โ€“ io.Copy๋Š” ์—ฌ์ „ํžˆ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • GC ์˜ํ–ฅ โ€“ ๋งŽ์€ ์ž„์‹œ ๊ฐ์ฒด๊ฐ€ GC ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ โ€“ Goroutine ์Šคํƒ์ด ์ดˆ๊ธฐ ํฌ๊ธฐ๊ฐ€ ๋น„๊ต์  ํฝ๋‹ˆ๋‹ค.

๐Ÿš€ Rust์˜ ๋„คํŠธ์›Œํฌ I/O ์žฅ์ 

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::fs::File;
use memmap2::Mmap;

async fn handle_client(mut stream: TcpStream) -> std::io::Result<()> {
    // Use mmap for zeroโ€‘copy file transfer
    let file = File::open("large_file.txt")?;
    let mmap = unsafe { Mmap::map(&file)? };

    // Directly send memoryโ€‘mapped data
    stream.write_all(&mmap)?;
    stream.flush()?;
    Ok(())
}

fn main() -> std::io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:60000")?;

    for stream in listener.incoming() {
        let stream = stream?;
        tokio::spawn(async move {
            if let Err(e) = handle_client(stream).await {
                eprintln!("Error handling client: {}", e);
            }
        });
    }

    Ok(())
}

์žฅ์  ๋ถ„์„ (Rust)

  • Zeroโ€‘Copy Support โ€“ mmap๊ณผ sendfile์„ ํ†ตํ•ด ์ œ๋กœโ€‘๋ณต์‚ฌ ์ „์†ก์„ ๋‹ฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Memory Safety โ€“ ์†Œ์œ ๊ถŒ ์‹œ์Šคํ…œ์ด ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • Asynchronous I/O โ€“ async/await๊ฐ€ ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • Precise Control โ€“ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ ๋ฐ I/O ์ž‘์—…์— ๋Œ€ํ•œ ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๐ŸŽฏ Production Environment Network I/O Optimization Practice

๐Ÿช Video Streaming Platform Optimization

Chunked Transfer

// Video chunked transfer
async fn stream_video_chunked(
    file_path: &str,
    stream: &mut TcpStream,
    chunk_size: usize,
) -> std::io::Result<()> {
    let file = File::open(file_path)?;
    let mmap = unsafe { Mmap::map(&file)? };

    // Send video data in chunks
    for chunk in mmap.chunks(chunk_size) {
        stream.write_all(chunk).await?;
        stream.flush().await?;

        // Control transmission rate
        tokio::time::sleep(Duration::from_millis(10)).await;
    }

    Ok(())
}

Connection Reuse

// Video stream connection reuse
struct VideoStreamPool {
    connections: Vec<TcpStream>,
    max_connections: usize,
}

impl VideoStreamPool {
    async fn get_connection(&mut self) -> Option<TcpStream> {
        if self.connections.is_empty() {
            self.create_new_connection().await
        } else {
            self.connections.pop()
        }
    }

    fn return_connection(&mut self, conn: TcpStream) {
        if self.connections.len() < self.max_connections {
            self.connections.push(conn);
        }
    }

    async fn create_new_connection(&self) -> Option<TcpStream> {
        // Placeholder for actual connection creation logic
        None
    }
}

Batch Processing Optimization

// Trade data batch processing
async fn batch_trade_processing(trades: Vec<Trade>, socket: &UdpSocket) -> std::io::Result<()> {
    // Batch serialization
    let mut buffer = Vec::new();
    for trade in trades {
        trade.serialize(&mut buffer)?;
    }

    // Batch sending
    socket.send(&buffer).await?;
    Ok(())
}

๐Ÿ”ฎ ๋ฏธ๋ž˜ ๋„คํŠธ์›Œํฌ I/O ๊ฐœ๋ฐœ ํŠธ๋ Œ๋“œ

๐Ÿš€ ํ•˜๋“œ์›จ์–ด ๊ฐ€์† ๋„คํŠธ์›Œํฌ I/O

DPDK ๊ธฐ์ˆ 

// DPDK network I/O example
fn dpdk_packet_processing() {
    // Initialize DPDK
    let port_id = 0;
    let queue_id = 0;

    // Directly operate on network card to send and receive packets
    let packet = rte_pktmbuf_alloc(pool);
    rte_eth_rx_burst(port_id, queue_id, &mut packets, 32);
}

RDMA ๊ธฐ์ˆ 

// RDMA zeroโ€‘copy transfer
fn rdma_zero_copy_transfer() {
    // Establish RDMA connection
    let context = ibv_open_device();
    let pd = ibv_alloc_pd(context);

    // Register memory region
    let mr = ibv_reg_mr(pd, buffer, size);

    // Zeroโ€‘copy data transfer
    post_send(context, mr);
}

๐Ÿ”ง Intelligent Network I/O Optimization

Adaptive Compression

// Adaptive compression algorithm
fn adaptive_compression(data: &[u8]) -> Vec<u8> {
    // Choose compression algorithm based on data type
    if is_text_data(data) {
        compress_with_gzip(data)
    } else if is_binary_data(data) {
        compress_with_lz4(data)
    } else {
        data.to_vec() // No compression
    }
}

๐ŸŽฏ ์š”์•ฝ

Through this practical network I/O performance optimization, I have deeply realized the huge differences in network I/O among different frameworks.

  • Hyperlane๋Š” ์ œ๋กœโ€‘๋ณต์‚ฌ ์ „์†ก ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋›ฐ์–ด๋‚˜๋ฉฐ, ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ „์†ก ์‹œ๋‚˜๋ฆฌ์˜ค์— ํŠนํžˆ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • Tokio๋Š” ๋น„๋™๊ธฐ I/O ์ฒ˜๋ฆฌ์—์„œ ๋…ํŠนํ•œ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด, ๊ณ ๋™์‹œ์„ฑ ์†Œ๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ „์†ก์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • Rust์˜ ์†Œ์œ ๊ถŒ ์‹œ์Šคํ…œ๊ณผ ์ œ๋กœโ€‘์ฝ”์ŠคํŠธ ์ถ”์ƒํ™”๋Š” ๋„คํŠธ์›Œํฌ I/O ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๊ฒฌ๊ณ ํ•œ ๊ธฐ๋ฐ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

GitHub Homepage: hyperlane-dev/hyperlane

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•  ๋ฉ”๋ชจ๋ฆฌ Part 3

์ง€๋ฆฌ์  ์š”์ธ: NUMA ์ง€์› ์ด์ „ ๊ธฐ์‚ฌ โ€œํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์•Œ์•„์•ผ ํ•  ๋ฉ”๋ชจ๋ฆฌ โ€“ Part 2โ€์—์„œ ์šฐ๋ฆฌ๋Š” ๊ฐ€์ƒ ๋ฉ”๋ชจ๋ฆฌ์™€ ๊ทธ๊ฒƒ์ด โ€ฆ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค.