본문 바로가기
카테고리 없음

대용량 데이터 처리

by keisoft 2024. 12. 9.

대용량 데이터를 처리하기 위해 스트림 방식으로 데이터를 전송 및 처리하는 예제를 아래에 제공합니다. 이는 메모리 사용량을 줄이고, 효율적으로 데이터를 처리할 수 있는 방법입니다.


C# 서버 코드

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;

[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpPost("stream-data")]
    public async Task StreamData()
    {
        // 응답의 ContentType을 JSON으로 설정
        Response.ContentType = "application/json";

        var testData = new TestData
        {
            key = "exampleKey",
            data = new DataClass
            {
                chartkey = 1,
                chartdatalist = GenerateLargeChartData()
            }
        };

        // JSON 데이터를 스트림으로 직렬화
        await JsonSerializer.SerializeAsync(Response.Body, testData, new JsonSerializerOptions
        {
            WriteIndented = false // JSON 크기를 줄이기 위해 줄 바꿈 제거
        });

        await Response.Body.FlushAsync(); // 스트림 완료
    }

    private List<ChartData> GenerateLargeChartData()
    {
        var chartDataList = new List<ChartData>();
        for (int i = 0; i < 2000000; i++)
        {
            chartDataList.Add(new ChartData { x = i * 1.1f, y = i * 2.2f });
        }
        return chartDataList;
    }
}

public class TestData
{
    public string key { get; set; }
    public DataClass data { get; set; }
}

public class DataClass
{
    public int chartkey { get; set; }
    public List<ChartData> chartdatalist { get; set; }
}

public class ChartData
{
    public float x { get; set; }
    public float y { get; set; }
}

JavaScript 클라이언트 코드

async function fetchStreamData() {
    // Fetch API로 스트림 데이터 요청
    const response = await fetch('https://yourapi.com/api/test/stream-data', {
        method: 'POST'
    });

    if (!response.ok) {
        console.error('HTTP Error:', response.status);
        return;
    }

    // 스트림 데이터 처리
    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let jsonText = "";

    while (true) {
        // 스트림의 데이터 청크를 읽음
        const { done, value } = await reader.read();
        if (done) {
            break; // 스트림이 끝났을 경우 루프 종료
        }
        // 받은 데이터 청크를 문자열로 디코딩
        jsonText += decoder.decode(value, { stream: true });
    }

    try {
        // 최종적으로 전체 JSON 문자열을 파싱
        const jsonData = JSON.parse(jsonText);
        console.log(jsonData);
    } catch (error) {
        console.error('JSON Parsing Error:', error);
    }
}

fetchStreamData();

코드 설명

C# 서버

  1. JsonSerializer.SerializeAsync 사용:
    • 대량 데이터를 직렬화하며, 클라이언트로 스트림 방식으로 데이터를 전송합니다.
  2. Response.Body.FlushAsync():
    • 직렬화된 데이터를 클라이언트에 강제적으로 보내도록 요청합니다.
  3. 대량 데이터 생성:
    • GenerateLargeChartData 메서드를 통해 200만 개의 데이터를 생성.

JavaScript 클라이언트

  1. fetch 사용:
    • 서버에 스트림 데이터를 요청합니다.
  2. response.body.getReader():
    • 스트림을 읽기 위해 Reader를 사용.
  3. TextDecoder:
    • 스트림 데이터를 텍스트 형식으로 변환.
  4. JSON 조립:
    • 받은 청크 데이터를 모두 합친 후, JSON으로 파싱하여 처리.

장점

  • 스트림 방식은 전체 데이터를 메모리에 저장하지 않고, 청크 단위로 처리하여 메모리 사용량을 최소화합니다.
  • JavaScript와 C# 모두 네트워크 대역폭과 처리 성능을 최적화합니다.

이 방식으로 대용량 데이터 전송 문제를 효과적으로 해결할 수 있습니다.