5. 샤드 라우팅의 mod-N 리해시 폭풍과 핫키 쏠림 (그리고 동시 변경 레이스)

난이도 최상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// ============================================================================
// [코드리뷰 문제] C# - 엔티티 라우팅의 샤드 분배(해시 % N)와 노드 증감
// ----------------------------------------------------------------------------
// 시나리오 (서버-서버/분산 - 샤딩 라우터):
//   - 월드의 엔티티(플레이어, 보스, 채팅채널 등)는 여러 존 서버(샤드)에 나눠 배치된다.
//   - 게이트웨이의 ShardRouter 가 엔티티 키로 "어느 샤드가 담당인지"를 계산해 라우팅한다.
//   - 샤드 수는 운영 중에 바뀐다: 트래픽이 늘면 증설(Added), 장애가 나면 제거(Removed).
//   - Route 는 매 패킷마다 여러 워커 스레드에서 매우 자주 호출된다.
//
// 상황:
//   - 인기 이벤트로 특정 보스/채널(소수의 키)에 트래픽이 폭증한다.
//   - 같은 시간대에 샤드 1대를 증설(또는 장애로 1대 제거)한다.
//
// 과제:
//   (A)의 라우팅 계산이 "키 → 샤드" 매핑을 어떻게 정하는지, 그리고 (B)에서 노드 수가
//   바뀔 때 기존 키들의 매핑이 어떻게 되는지 분석하라. 인기 키 소수에 트래픽이 몰릴 때의
//   샤드별 부하와, Route 와 노드 증감이 동시에 일어날 때의 동작도 함께 설명하라.
//   수정안과 더 나은 설계를 제시하라.
//   (먼저 직접 리뷰를 적은 뒤 answer.md 와 대조할 것)
// ============================================================================

using System.Collections.Generic;

public sealed class ShardNode
{
    public string Id;
    public ShardNode(string id) { Id = id; }
}

public sealed class ShardRouter
{
    private readonly List<ShardNode> _nodes = new();   // 운영 중 증감되는 샤드 목록

    public ShardNode Route(long entityKey)
    {
        int n = _nodes.Count;
        int idx = (int)((uint)entityKey.GetHashCode() % (uint)n);   // (A) 키 → 샤드
        return _nodes[idx];
    }

    public void OnNodeAdded(ShardNode node)
    {
        _nodes.Add(node);            // (B) 샤드 수 변경 (증설)
    }

    public void OnNodeRemoved(ShardNode node)
    {
        _nodes.Remove(node);         // (B) 샤드 수 변경 (장애/축소)
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.