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++
// ============================================================================
// [코드리뷰 문제] C++ - 엔티티 라우팅의 샤드 분배(해시 % N)와 노드 증감
// ----------------------------------------------------------------------------
// 시나리오 (서버-서버/분산 - 샤딩 라우터):
// - 월드의 엔티티(플레이어, 보스, 채팅채널 등)는 여러 존 서버(샤드)에 나눠 배치된다.
// - 게이트웨이의 ShardRouter 가 엔티티 키로 "어느 샤드가 담당인지"를 계산해 라우팅한다.
// - 샤드 수는 운영 중에 바뀐다: 트래픽이 늘면 증설(addNode), 장애가 나면 제거(removeNode).
// - route 는 매 패킷마다 여러 워커 스레드에서 매우 자주 호출된다.
//
// 상황:
// - 인기 이벤트로 특정 보스/채널(소수의 키)에 트래픽이 폭증한다.
// - 같은 시간대에 샤드 1대를 증설(또는 장애로 1대 제거)한다.
//
// 과제:
// (A)의 라우팅 계산이 "키 → 샤드" 매핑을 어떻게 정하는지, (B)에서 노드 수가 바뀔 때
// 기존 키들의 매핑이 어떻게 되는지 분석하라. 인기 키 소수에 트래픽이 몰릴 때의 샤드별
// 부하와, route 와 노드 증감이 동시에 일어날 때의 동작도 함께 설명하라. 수정안과 더
// 나은 설계를 제시하라.
// (먼저 직접 리뷰를 적은 뒤 answer.md 와 대조할 것)
// ============================================================================
#include <cstdint>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
struct ShardNode {
std::string id;
};
class ShardRouter {
public:
ShardNode& route(int64_t entityKey) {
size_t n = nodes_.size();
size_t idx = std::hash<int64_t>{}(entityKey) % n; // (A) 키 → 샤드
return nodes_[idx];
}
void addNode(const ShardNode& node) {
nodes_.push_back(node); // (B) 샤드 수 변경 (증설)
}
void removeNode(const std::string& id) {
nodes_.erase(std::remove_if(nodes_.begin(), nodes_.end(),
[&](const ShardNode& s){ return s.id == id; }),
nodes_.end()); // (B) 샤드 수 변경 (장애/축소)
}
private:
std::vector<ShardNode> nodes_; // 운영 중 증감되는 샤드 목록
}; 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.
내 리뷰 · C++
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.