채팅 시스템 성능 향상시키기

두 DB 특징

RDBMS (PostgreSQL)

  • 구조화된 스키마와 엄격한 데이터 일관성.
  • ACID 트랜잭션 보장.
  • 복잡한 조인 연산 지원.
  • 수직적 확장(Scale-up) 중심.
  • 정규화된 데이터 구조.

NoSQL (MongoDB)

  • 유연한 스키마 (Schema-less).
  • 수평적 확장(Scale-out) 용이.
  • 문서 기반 데이터 모델.
  • 높은 쓰기/읽기 처리량.
  • 실시간 데이터 처리에 최적화.

 

채팅 시스템 MongoDB 도입 배경

  1. 높은 쓰기 성능
    • 시간 채팅에서 발생하는 대량의 메시지 저장에 유리.
    • 샤딩을 통한 수평적 확장 용이.
  2. 읽기 성능 향상
    • 채팅 이력 조회 시 조인 없이 단일 컬렉션에서 조회 가능.
    • 인덱싱을 통한 빠른 검색.
  3. 데이터 구조 최적화
    • 채팅 메시지는 정규화가 필요 없는 문서 형태로 저장하기 적합.
    • 시지, 시간, 사용자 정보 등을 하나의 문서로 저장 가능.

 

실제 적용 코드

using HolyShitServer.Src.DB.Configuration;
using HolyShitServer.Src.DB.MongoEntities;
using Microsoft.Extensions.Configuration;
using MongoDB.Driver;

namespace HolyShitServer.Src.Services;

public class MongoDbService
{
  private readonly IMongoCollection<ChatMessages> _chatMessages;

  public MongoDbService(IConfiguration configuration)
  {
    var mongoConfig = configuration.GetSection("MongoDb").Get<MongoDbConfig>();
    
    // MongoDB 설정 최적화
    var settings = MongoClientSettings.FromUrl(new MongoUrl(mongoConfig?.ConnectionString));
    settings.WriteConcern = WriteConcern.Unacknowledged; // 빠른 쓰기 위해
    settings.ReadPreference = ReadPreference.Primary; // 읽기 성능 향상
    settings.MaxConnectionPoolSize = 100; // 커넥션 풀 크기 증가
    settings.ServerSelectionTimeout = TimeSpan.FromSeconds(5);
    
    // 인덱스 생성 옵션 설정
    var client = new MongoClient(settings);
    var database = client.GetDatabase(mongoConfig?.DatabaseName);
    _chatMessages = database.GetCollection<ChatMessages>("chat_messages");

    // CreatedAt 필드에 인덱스 생성 (내림차순)
    var indexKeys = Builders<ChatMessages>.IndexKeys.Descending(x => x.CreatedAt);
    var indexOptions = new CreateIndexOptions { Background = true };
    _chatMessages.Indexes.CreateOne(new CreateIndexModel<ChatMessages>(indexKeys, indexOptions));
  }

  public async Task SaveChatMessageAsync(ChatMessages message)
  {
    await _chatMessages.InsertOneAsync(message);
  }

  public async Task<List<ChatMessages>> GetChatMessagesAsync(int limit = 100)
  {
    // CreatedAt 인덱스를 활용한 빠른 조회
    return await _chatMessages.Find(_ => true)
      .Sort(Builders<ChatMessages>.Sort.Descending(x => x.CreatedAt))
      .Limit(limit)
      .ToListAsync();
  }
}


////////////////////////////////////

...
await mongoDbService.SaveChatMessageAsync(chatMessage);

 

성능 최적화 전략

  • WriteConcern 최적화로 쓰기 성능 향상.
  • 커넥션 풀 크기 조정.
  • 인덱스 생성으로 조회 성능 개선.

PostgreSQL MongoDB 개선율 지표

초기 응답시간 333ms 118ms 64% ↓
최종 평균시간 8.58ms 1.72ms 80% ↓
최소 지연시간 2ms 0ms 100% ↓
최대 지연시간 333ms 118ms 64% ↓

 

읽기 성능 향상과 동시에 쓰기 성능 또한 초당 1000건 처리량에서 대략 5000건 처리량(약 5배 증가)까지 향상된 것을 확인할 수 있었다.

 

 

 

 

 

 

 

 

'Side Projects' 카테고리의 다른 글

Node.js로 구현하는 AI 챗봇 비교 분석: Gemini vs Grok vs OpenAI  (0) 2025.03.05
체스말 이동하기 로직  (0) 2025.02.21
Git Actions?  (0) 2025.02.16
DI(의존성 주입)?  (0) 2025.01.12
분산서버 확립하기  (0) 2025.01.10