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

๋ฐœํ–‰: (2026๋…„ 1์›” 3์ผ ์˜คํ›„ 01:07 GMT+9)
12 min read
์›๋ฌธ: Dev.to

Iโ€™m happy to translate the article for you, but Iโ€™ll need the full text youโ€™d like translated. Could you please paste the content (excluding the source line you already provided) here? Once I have it, Iโ€™ll translate it into Korean while preserving all formatting, markdown, and technical terms.

์™œ ์ด ๊ธ€์„ ์“ฐ๋Š”๊ฐ€

๋„คํŠธ์›Œํฌ ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์ง‘์ค‘ํ•˜๋Š” ์—”์ง€๋‹ˆ์–ด

๋‚˜๋Š” ์ตœ๊ทผ์— ์‹ค์‹œ๊ฐ„ ๋น„๋””์˜ค ์ŠคํŠธ๋ฆฌ๋ฐ ํ”Œ๋žซํผ์—์„œ ๋งค์šฐ ๊นŒ๋‹ค๋กœ์šด ๋„คํŠธ์›Œํฌ ์„ฑ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋‹ค๋ฃจ๋Š” ์ž‘์—…์„ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์–‘ํ•œ ์›น ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์„ฑ๋Šฅ์„ ์žฌ๊ฒ€ํ† ํ•˜๊ณ , ๋„คํŠธ์›Œํฌโ€ฏIO๋ฅผ ๋ฒค์น˜๋งˆํ‚นํ•˜๊ณ  ํŠœ๋‹ํ•˜๋Š” ์ฒด๊ณ„์ ์ธ ๋ฐฉ๋ฒ•์„ ๊ณ ์•ˆํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๊ณต์œ ๋ฅผ ์œ„ํ•ด ์ •๋ฆฌํ•˜๊ณ  ์ •์ œํ•œ ๊ฐ„๊ฒฐํ•œ ๋ฒ„์ „์˜ ์ž๋ฃŒ์ž…๋‹ˆ๋‹ค.

๋„คํŠธ์›Œํฌโ€ฏIO ์ตœ์ ํ™”์˜ ํ•ต์‹ฌ ์š”์†Œ

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

์ข…ํ•ฉ ๋ฒค์น˜๋งˆํฌ ๊ฒฐ๊ณผ

1๏ธโƒฃ ์ดˆ๋‹น ์š”์ฒญ ์ˆ˜ (์ฒ˜๋ฆฌ๋Ÿ‰) ๋ฐ ์ง€์—ฐ ์‹œ๊ฐ„

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๏ธโƒฃ ์ „์†ก๋ฅ  ๋ฒค์น˜๋งˆํฌ (๋Œ€์šฉ๋Ÿ‰ ํŽ˜์ด๋กœ๋“œ ์‹œ๋‚˜๋ฆฌ์˜ค)

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

์ œ๋กœโ€‘์นดํ”ผ โ€“ ํ•ต์‹ฌ ๊ธฐ์ˆ 

Hyperlane์˜ ์ œ๋กœโ€‘์นดํ”ผ ๊ตฌํ˜„ (Rust)

// Zeroโ€‘copy network IO implementation
async fn zero_copy_transfer(
    input: &mut TcpStream,
    output: &mut TcpStream,
    size: usize,
) -> Result {
    // Use the `sendfile` system call for zeroโ€‘copy
    let bytes_transferred = sendfile(
        output.as_raw_fd(),
        input.as_raw_fd(),
        None,
        size,
    )?;
    Ok(bytes_transferred)
}

๋ฉ”๋ชจ๋ฆฌ ๋งคํ•‘ ํŒŒ์ผ ์ „์†ก (Rust)

use std::fs::File;
use std::io::Write;
use memmap2::Mmap;

/// Transfer a file using `mmap`.
fn mmap_file_transfer(file_path: &str, stream: &mut TcpStream) -> Result {
    let file = File::open(file_path)?;
    // SAFETY: the file is not mutated while the mapping lives.
    let mmap = unsafe { Mmap::map(&file)? };

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

TCPโ€‘์†Œ์ผ“ ํŠœ๋‹

// TCP ๋งค๊ฐœ๋ณ€์ˆ˜ ์ตœ์ ํ™” (Rust)
fn optimize_tcp_socket(socket: &TcpSocket) -> Result {
    // Nagle ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋น„ํ™œ์„ฑํ™” โ€“ ์ž‘์€ ํŒจํ‚ท์˜ ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ค„์ž…๋‹ˆ๋‹ค.
    socket.set_nodelay(true)?;

    // ์†Œ์ผ“ ๋ฒ„ํผ ํฌ๊ธฐ ์ฆ๊ฐ€.
    socket.set_send_buffer_size(64 * 1024)?;
    socket.set_recv_buffer_size(64 * 1024)?;

    // TCP Fast Open ํ™œ์„ฑํ™” (OS๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ).
    socket.set_tcp_fastopen(true)?;

    // keepโ€‘alive ์„ค์ • ์กฐ์ •.
    socket.set_keepalive(true)?;
    Ok(())
}

๋น„๋™๊ธฐ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ

use futures::future::join_all;

/// ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
async fn batch_async_io(requests: Vec<YourRequestType>) -> Result<Vec<YourResponseType>> {
    let futures = requests.into_iter().map(|req| async move {
        // ๊ฐ ์š”์ฒญ์€ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
        process_request(req).await
    });

    // `join_all`์€ ๋ชจ๋“  future๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
    let results = join_all(futures).await;

    // ์„ฑ๊ณต์ ์ธ ์‘๋‹ต์„ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค.
    let mut responses = Vec::with_capacity(results.len());
    for result in results {
        responses.push(result?);
    }
    Ok(responses)
}

ํ”Œ๋žซํผโ€‘๋ณ„ ๊ด€์ฐฐ

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

// node_example.js
const http = require('http');
const fs   = require('fs');

const server = http.createServer((req, res) => {
    // `fs.readFile`๋Š” ์ „์ฒด ํŒŒ์ผ์„ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋“œ โ†’ ์ถ”๊ฐ€ ๋ณต์‚ฌ ๋ฐœ์ƒ.
    fs.readFile('large_file.txt', (err, data) => {
        if (err) {
            res.writeHead(500);
            res.end('Error');
            return;
        }
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end(data); // ๋ฐ์ดํ„ฐ๊ฐ€ ์ปค๋„ โ†’ ์œ ์ € โ†’ ๋„คํŠธ์›Œํฌ ๋ฒ„ํผ๋กœ ๋ณต์‚ฌ๋จ.
    });
});

server.listen(60000);

๋ฌธ์ œ ๋ถ„์„

์ด์Šˆ์˜ํ–ฅ
๋ฐ์ดํ„ฐ ๋ณต์‚ฌ ๋‹ค์ค‘ ๋ฐœ์ƒ (์ปค๋„ โ†’ ์œ ์ € โ†’ ๋„คํŠธ์›Œํฌ)CPU ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€
ํŒŒ์ผ I/O ์ฐจ๋‹จ (API๊ฐ€ ๋น„๋™๊ธฐ์ž„์—๋„)์ด๋ฒคํŠธ ๋ฃจํ”„ ์ •์ง€
์ „์ฒด ํŒŒ์ผ ๋ฒ„ํผ๋งํฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
ํ๋ฆ„ ์ œ์–ด ๋ถ€์žฌ์ „์†ก ์†๋„ ์กฐ์ ˆ์ด ์–ด๋ ค์›€

Go โ€“ ๊ฐ•์  ๋ฐ ์ œํ•œ

// go_example.go
package main

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

func handler(w http.ResponseWriter, r *http.Request) {
    // ํŒŒ์ผ์„ ์‘๋‹ต์— ์ง์ ‘ ์ŠคํŠธ๋ฆฌ๋ฐ.
    file, err := os.Open("large_file.txt")
    if err != nil {
        http.Error(w, "File not found", http.StatusNotFound)
        return
    }
    defer file.Close()

    // `io.Copy`๋Š” ์—ฌ์ „ํžˆ ๋ฒ„ํผ ๊ฐ„ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰.
    if _, err = io.Copy(w, file); err != nil {
        fmt.Println("Copy error:", err)
    }
}

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

์žฅ์  ๋ถ„์„

์žฅ์ ์ด์œ 
๊ฐ€๋ฒผ์šด goroutine์ž‘์€ ์Šคํƒ ์„ฑ์žฅ์œผ๋กœ ๋Œ€๊ทœ๋ชจ ๋™์‹œ์„ฑ์„ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
ํ’๋ถ€ํ•œ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (net/http)๊ฒฌ๊ณ ํ•˜๊ณ  ๊ฒ€์ฆ๋œ ๋„คํŠธ์›Œํ‚น ๊ธฐ๋ณธ ์š”์†Œ ์ œ๊ณต
io.Copy๋Š” ๋น„๊ต์  ํšจ์œจ์ ๊ฐ€๋Šฅํ•  ๊ฒฝ์šฐ splice/sendfile์„ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ

๋‹จ์  ๋ถ„์„

๋‹จ์ ์ด์œ 
๋งŽ์€ ๊ฒฝ๋กœ์—์„œ ์—ฌ์ „ํžˆ ๋ฐ์ดํ„ฐ ๋ณต์‚ฌ ๋ฐœ์ƒio.Copy๊ฐ€ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ๋ณต์‚ฌ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Œ
๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ์••๋ ฅ๋งŽ์€ ์ž„์‹œ ๋ฒ„ํผ๊ฐ€ GC ์ผ์‹œ ์ •์ง€๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Œ
goroutine ์Šคํƒ ํฌ๊ธฐ (์ดˆ๊ธฐ 2โ€ฏKB)๋งŽ์€ ์—ฐ๊ฒฐ์ด ์‚ด์•„ ์žˆ์„ ๋•Œ ์ƒ๋‹นํ•ด์งˆ ์ˆ˜ ์žˆ์Œ

Rust โ€“ ๊ณ ์„ฑ๋Šฅ ๋„คํŠธ์›Œํฌ I/O์— ์ž์—ฐ์Šค๋Ÿฌ์šด ์ ํ•ฉ

// rust_example.rs (excerpt)
use std::io::prelude::*;
use std::net::TcpListener;
use std::fs::File;
use memmap2::Mmap;

async fn handle_connection(mut stream: TcpStream) -> std::io::Result<()> {
    // ์˜ˆ์‹œ: ํŒŒ์ผ์„ ๋ฉ”๋ชจ๋ฆฌ ๋งคํ•‘ํ•˜๊ณ  ์ถ”๊ฐ€ ๋ณต์‚ฌ ์—†์ด ์ „์†ก.
    let file = File::open("large_file.txt")?;
    let mmap = unsafe { Mmap::map(&file)? };
    stream.write_all(&mmap)?;
    Ok(())
}

Rust๊ฐ€ ๋‹๋ณด์ด๋Š” ์ด์œ 

  • ์ œ๋กœโ€‘์ฝ”์ŠคํŠธ ์ถ”์ƒํ™” โ€“ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์ด ์ปดํŒŒ์ผ ์‹œ ๋ณด์žฅ.
  • ์„ธ๋ฐ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ, ์ˆ˜๋ช…, ์‹œ์Šคํ…œ ์ฝœ ์ œ์–ด.
  • ์šฐ์ˆ˜ํ•œ async ์ƒํƒœ๊ณ„ (tokio, hyper, hyperlane ๋“ฑ) ๊ฐ€ ์ œ๋กœโ€‘์นดํ”ผ API์™€ ์›ํ™œํžˆ ํ†ตํ•ฉ.

์ฃผ์š” ๋‚ด์šฉ

  1. ์ œ๋กœโ€‘์นดํ”ผ(sendfile, splice, mmap ๋“ฑ)๋Š” ๊ฐ€์žฅ ํฐ ์ˆœ์ˆ˜ ์ฒ˜๋ฆฌ๋Ÿ‰ ํ–ฅ์ƒ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  2. TCP ํŠœ๋‹(Nagle ๋น„ํ™œ์„ฑํ™”, ๋ฒ„ํผ ํ™•๋Œ€, Fast Open ํ™œ์„ฑํ™”)์€ ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ค„์ด๊ณ  ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆด ๋•Œ ์•ˆ์ •์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.
  3. ๋น„๋™๊ธฐ ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜์ง€ ์•Š๊ณ  ๋ฉ€ํ‹ฐโ€‘์ฝ”์–ด CPU๋ฅผ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. ์–ธ์–ด๋ณ„ ํŠธ๋ ˆ์ด๋“œโ€‘์˜คํ”„:
    • Node.js โ€“ ๊ฐ„๋‹จํ•˜์ง€๋งŒ ์ถ”๊ฐ€ ๋ณต์‚ฌ์™€ ์ด๋ฒคํŠธ ๋ฃจํ”„ ๊ฒฝ์Ÿ์œผ๋กœ ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.
    • Go โ€“ ๋›ฐ์–ด๋‚œ ๋™์‹œ์„ฑ ๋ชจ๋ธ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ณต์‚ฌ์™€ GC ์ผ์‹œ ์ •์ง€๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
    • Rust โ€“ ๋ฉ”๋ชจ๋ฆฌ์™€ ์‹œ์Šคํ…œ ์ž์›์— ๋Œ€ํ•œ ์ตœ์  ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ดˆ์ €์ง€์—ฐ ์„œ๋น„์Šค์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ธฐ์ˆ (์ œ๋กœโ€‘์นดํ”ผ, ์ ์ ˆํ•œ ์†Œ์ผ“ ์„ค์ •, ๋น„๋™๊ธฐ ํŒŒ์ดํ”„๋ผ์ธ)์„ ๊ฒฐํ•ฉํ•˜๋ฉด ์œ„์˜ ๋ฒค์น˜๋งˆํฌ ํ‘œ์—์„œ ๋ณด์—ฌ์ค€ ๋ฐ”์™€ ๊ฐ™์ด ๋„คํŠธ์›Œํฌโ€ฏIO ์„ฑ๋Šฅ์„ ํ•˜๋“œ์›จ์–ด ํ•œ๊ณ„์— ๊ฐ€๊น๊ฒŒ ๋Œ์–ด์˜ฌ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์ฝ”๋“œ ์ƒ˜ํ”Œ

ํด๋ผ์ด์–ธํŠธ ํ•ธ๋“ค๋Ÿฌ โ€“ mmap์„ ์ด์šฉํ•œ ์ œ๋กœโ€‘์นดํ”ผ ํŒŒ์ผ ์ „์†ก (Rust)

async fn handle_client(mut stream: TcpStream) -> Result {
    // Open the file and memoryโ€‘map it
    let file = File::open("large_file.txt")?;
    let mmap = unsafe { Mmap::map(&file)? };

    // Send the whole mapped region
    stream.write_all(&mmap)?;
    stream.flush()?;

    Ok(())
}

์„œ๋ฒ„ ์ง„์ž…์  (Rust)

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

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

    Ok()
}

์žฅ์  ๋ถ„์„

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

๋น„๋””์˜คโ€‘์ŠคํŠธ๋ฆฌ๋ฐ ์ตœ์ ํ™”

์ฒญํฌ ์ „์†ก (Rust)

async fn stream_video_chunked(
    file_path: &str,
    stream: &mut TcpStream,
    chunk_size: usize,
) -> 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(())
}

์—ฐ๊ฒฐ ์žฌ์‚ฌ์šฉ (Rust)

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);
        }
    }
}

๋ฐฐ์น˜ ์ฒ˜๋ฆฌ (Rust)

async fn batch_trade_processing(trades: Vec<Trade>) -> 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 ๊ธฐ์ˆ 

DPDK (Data Plane Development Kit)

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

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

RDMA (Remote Direct Memory Access)

// 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);
}

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
    }
}

Source: โ€ฆ

์ตœ์ข… ์ •๋ฆฌ

์‹ค์ œ ๋„คํŠธ์›Œํฌโ€‘IO ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํ”„๋ ˆ์ž„์›Œํฌ๋ณ„ ๋šœ๋ ทํ•œ ์ฐจ์ด๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค:

  • Hyperlane โ€“ ์ œ๋กœโ€‘์นดํ”ผ ์ „์†ก๊ณผ ์„ธ๋ฐ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋›ฐ์–ด๋‚˜ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ „์†ก์— ์ตœ์ ํ™”๋ฉ๋‹ˆ๋‹ค.
  • Tokio โ€“ ๋†’์€ ๋™์‹œ์„ฑ, ์ž‘์€ ํŽ˜์ด๋กœ๋“œ์˜ ๋น„๋™๊ธฐ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๊ฐ•์ ์„ ๋ณด์ž…๋‹ˆ๋‹ค.

Rust์˜ ์†Œ์œ ๊ถŒ ๋ชจ๋ธ๊ณผ ์ œ๋กœโ€‘์ฝ”์ŠคํŠธ ์ถ”์ƒํ™”๋Š” ๊ณ ํšจ์œจ์ ์ด๊ณ  ์•ˆ์ „ํ•œ ๋„คํŠธ์›Œํฌ ์Šคํƒ์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒฌ๊ณ ํ•œ ๊ธฐ๋ฐ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๐Ÿ“ฆ ์†Œํ”„ํŠธ์›จ์–ด ํŒจํ‚ค์ง•์ด๋ž€?

๊ฐœ์š”: ์†Œํ”„ํŠธ์›จ์–ด ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์—์„œ Packaging์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œโ€”compiled code, ์ด๋ฏธ์ง€, configuration files ๋ฐ ...์˜ ์ตœ์ข… ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.