Kubernetes/Kubernetes Advanced

📌 [StatefulSet 심화편 #18] StatefulSet에서 Sharding(샤딩) 적용 방법

ygtoken 2025. 3. 14. 10:17
728x90

 

1️⃣ 개요

 

StatefulSet을 사용하여 대규모 데이터를 효율적으로 관리하려면, 단순한 리더-팔로워(Replica) 방식만으로는 한계가 있습니다.

특히, 데이터가 지속적으로 증가하고, 높은 트래픽을 처리해야 하는 경우 Sharding(샤딩) 기법이 필수적입니다.

 

이번 글에서는 StatefulSet에서 Sharding을 적용하는 방법과, 데이터베이스(MongoDB, Elasticsearch, Kafka) 및 분산 시스템에서의 샤딩 활용 전략을 설명하겠습니다. 🚀

 


2️⃣ Sharding(샤딩)이란?

 

📌 Sharding(샤딩)의 개념

Sharding은 데이터를 여러 개의 작은 단위(Shard)로 나누어 저장하고 관리하는 기술입니다.

이를 통해 수평 확장(Scalability) 이 가능해지고, 대규모 데이터베이스나 메시지 큐 시스템의 성능을 극대화할 수 있습니다.

 

📌 Sharding이 필요한 주요 이유

이유 설명
데이터 증가 대응 하나의 데이터베이스에 저장할 수 없는 대량 데이터를 여러 노드에 분산 저장
읽기/쓰기 성능 향상 특정 Shard에서만 요청을 처리하여 부하 분산
고가용성(HA) 제공 특정 노드 장애 발생 시 다른 Shard에서 서비스 지속 가능

StatefulSet과 Sharding을 조합하면, 분산 데이터베이스 및 메시지 브로커 시스템의 확장성을 극대화할 수 있습니다.

 


3️⃣ StatefulSet 기반 Sharding 적용 사례

 

✅ 1. MongoDB Sharded Cluster 구성

 

MongoDB에서는 Sharded Cluster 방식으로 Sharding을 지원합니다.

이를 위해 Config Server, Query Router(Mongos), Shard 노드로 구성해야 합니다.

 

📌 MongoDB Sharding 아키텍처

Config Server: 샤드 정보를 저장하는 메타데이터 관리 노드

Query Router(Mongos): 클라이언트 요청을 적절한 Shard로 전달하는 역할

Shard 노드: 실제 데이터를 저장하는 StatefulSet

 

📌 MongoDB Shard 노드 StatefulSet 예제

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb-shard
spec:
  serviceName: mongodb-shard
  replicas: 3
  selector:
    matchLabels:
      app: mongodb-shard
  template:
    metadata:
      labels:
        app: mongodb-shard
    spec:
      containers:
        - name: mongodb
          image: mongo:latest
          args: ["--shardsvr", "--replSet", "shard-rs"]
          volumeMounts:
            - name: mongo-data
              mountPath: /data/db
  volumeClaimTemplates:
    - metadata:
        name: mongo-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi

 

📌 MongoDB Sharding 초기화

kubectl exec -it mongodb-shard-0 -- mongo --eval "rs.initiate()"
kubectl exec -it mongodb-shard-0 -- mongo --eval "sh.addShard('shard-rs/mongodb-shard-0.mongodb-shard:27017')"

이제 MongoDB에서 데이터가 자동으로 샤드 노드로 분산됩니다.

 


✅ 2. Elasticsearch Shard 구성

 

Elasticsearch에서는 Primary Shard와 Replica Shard를 구성하여 데이터 검색 성능을 최적화할 수 있습니다.

 

📌 Elasticsearch StatefulSet 예제 (Sharding 설정 포함)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
spec:
  serviceName: elasticsearch
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.10.2
          env:
            - name: "discovery.type"
              value: "single-node"
          volumeMounts:
            - name: elastic-data
              mountPath: /usr/share/elasticsearch/data
  volumeClaimTemplates:
    - metadata:
        name: elastic-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 50Gi

 

📌 Elasticsearch에서 Shard 상태 확인

kubectl exec -it elasticsearch-0 -- curl -X GET "localhost:9200/_cat/shards?v"

Elasticsearch의 샤드 개수를 조정하여 검색 성능을 최적화할 수 있습니다.

 


✅ 3. Kafka Partition을 활용한 Sharding 구성

 

Kafka는 토픽(Topic)을 여러 개의 Partition으로 분할하여 샤딩을 지원합니다.

각 Partition은 서로 다른 노드에 배포되며, 병렬로 데이터를 처리할 수 있습니다.

 

📌 Kafka StatefulSet 예제 (Partition 기반 Sharding 설정)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: kafka
spec:
  serviceName: kafka
  replicas: 3
  selector:
    matchLabels:
      app: kafka
  template:
    metadata:
      labels:
        app: kafka
    spec:
      containers:
        - name: kafka
          image: wurstmeister/kafka:latest
          env:
            - name: KAFKA_BROKER_ID
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: KAFKA_ZOOKEEPER_CONNECT
              value: "zookeeper:2181"
  volumeClaimTemplates:
    - metadata:
        name: kafka-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 20Gi

 

📌 Kafka Partition 개수 확인

kubectl exec -it kafka-0 -- kafka-topics.sh --list --zookeeper zookeeper:2181

Kafka의 Partition을 활용하면 대량의 메시지를 분산 처리할 수 있습니다.

 


4️⃣ Sharding 운영 시 고려해야 할 사항

 

✅ 1. Shard 키(Shard Key) 설계

 

Sharding을 적용할 때 Shard Key를 잘못 선택하면 특정 Shard에만 데이터가 집중될 수 있음

 

📌 MongoDB Shard Key 예제

db.collection.createIndex({ user_id: "hashed" })
sh.shardCollection("mydb.users", { user_id: "hashed" })

Shard Key는 데이터 분포를 균등하게 분산할 수 있도록 설계해야 합니다.

 


✅ 2. 데이터 이동(Rebalancing) 문제

 

샤드가 추가되거나 삭제될 경우 기존 데이터의 균형을 다시 조정해야 함

 

📌 MongoDB에서 데이터 리밸런싱 실행

sh.enableBalancing("mydb.users")

Sharding 적용 후 데이터가 특정 Shard에 집중되지 않도록 리밸런싱을 수행해야 합니다.

 


🔥 5️⃣ 결론

 

StatefulSet과 Sharding을 조합하면 대량 데이터를 효과적으로 분산 및 관리 가능

MongoDB는 Sharded Cluster 구조, Elasticsearch는 Primary & Replica Shard, Kafka는 Partition 기반으로 Sharding 가능

Shard Key를 잘못 설정하면 특정 노드에 부하가 집중될 수 있으므로 주의해야 함

Shard 추가/삭제 시 데이터 Rebalancing을 수행하여 부하를 균등하게 분산해야 함

728x90