Study/TIL(Today I Learned)

24.08.01 C#, 데이터베이스 샤딩

에린_1 2024. 8. 1. 19:55
728x90

C#

델리게이트(Delegate)

  • 메서드를 참조할 수 있는 형식 안전한 개체이다.
  • 델리게이트는 메서드를 변수처럼 저장할 수 있게 해주며, 메서드에 대한 참조를 호출 시점까지 연기하여 동적으로 메서드를 호출할 수 있는 유연성을 제공한다. 이는 콜백 함수, 이벤트 처리기 및 기타 다양한 패턴에서 유용하게 사용할 수 있다.

델리게이트의 주요 특징

  1. 형식 안정성
    • 델리게이트는 특정 메서드 시그니처(반환 타입과 매개변수 목록)를 정의한다.
    • 델리게이트가 참조할 수 있는 메서드는 반드시 이 시그니처와 일치해야 한다.
  2. 다중 캐스팅
    • 델리게이트는 여러 메서드를 호출할 수 있다.
    • 델리게이트 인스턴스에 여러 메서드를 추가하면, 델리게이트를 호출할 때 해당 메서드들이 차례로 호출된다.
  3. 익명 메서드 및 람다식 지원
    • 델리게이트는 익명 메서드 또는 람다식과 함께 사용할 수 있다.

델리게이트 정의

  • 델리게이트는 메서드 시그니처와 반환 타입을 포함하는 형식을 정의한다.
public delegate void MyDelegate(string message)
  • 이 델리게이트는 string 타입의 매개변수를 받고, void를 반환하는 메서드를 참조할 수 있다.

사용 사례

  1. 이벤트 처리
    • 델리게이트는 C#에서 이벤트를 구현하는 기본 메커니즘이다.
    • 이벤트는 특정 작업이 발생할 때 호출되는 메서드를 나타내기 위해 델리게이트를 사용한다.
  2. 콜백 메서드
    • 비동기 작업이 완료되었을 때 호출되는 메서드와 같이 콜백 메서드를 정의하는 데 사용된다.
  3. LINQ
    • 델리게이트는 람다식을 통해 LINQ 쿼리에서 자주 사용된다.
    • 예를 들어, Func<T, TResult>와 Action<T>는 LINQ 쿼리에서 자주 사용되는 델리게이트 유형이다.

yield return

  • C#에서 이터레이터 메서드를 구현할 때 사용되는 키워드이다.
  • 이터레이터 메서드는 IEnumerable 또는 IEnumerable<T>를 구현하여 호출자가 요소를 순차적으로 반복(iterate)할 수 있도록 한다.
  • yield return은 메서드의 실행을 멈추고 호출자에게 현재 값을 반환한 후, 다음 호출 시 해당 위치에서 실행을 재개할 수 있게 한다.

주요 기능

  1. 순차적 데이터 반환
    • yield return을 사용하여 데이터를 하나씩 반환할 수 있다. 호출자는 이터레이터를 사용하여 데이터 시퀀스를 순차적으로 요청할 수 있다.
  2. 상태 저장
    • yield return은 메서드의 실행 상태를 저장한다. 이후 호출 시 저장된 상태에서 실행을 재개한다.
  3. 지연된 실행
    • 이터레이터는 실제로 반복자에 의해 요청되기 전까지 실행되지 않는다. 이는 데이터 시퀀스를 미리 계산하지 않고, 필요할 때마다 계산하여 반환하는 지연된 실행 방식을 제공한다.

동작 원리

  1. 이터레이터 상태 저장
    • yield return이 호출되면 현재 메서드의 상태(로컬 변수 값, 현재 실행 위치 등)가 저장된다.
  2. 이터레이터 일시 중지
    • yield return 이후의 코드는 나중에 호출자가 다음 요소를 요청할 때 까지 실행되지 않는다.
  3. 다음 요소 요청
    • 호출자가 반복을 계속할 때마다 메서드가 저장된 상태에서 재개되어 다음 yield return을 만날 때까지 실행된다.
  4. 종료
    • 모든 yield return 문을 실행한 후, 메서드가 종료되면 이터레이션이 끝난다.

활용

  • 컬렉션 생성
    • 복잡한 데이터 생성 로직을 단순화할 수 있다. 예를 들어, 특정 조건을 만족하는 요소들만 반환할 수 있다.
  • 상태 기반 순회
    • 상태를 기반으로 순회를 중단하고 재개할 수 있다. 예를 들어, 트리 구조의 노드를 순회할 때 유용하다.
  • 지연된 평가
    • 컬렉션을 미리 계산하지 않고, 필요할 때마다 계산하여 메모리 사용을 최적화할 수 있다.

예외 처리 및 yield break

  • yield return과 함께 yield break를 사용하여 이터레이션을 조기에 종료할 수 있다. 예외가 발생하거나 특정 조건이 충족되지 않으면 yield break를 호출하여 이터레이터를 종료할 수 있다.

SortedDictionary<TKey, TValue>

  • .NET에서 제공하는 제네릭 컬렉션 클래스 중 하나로, 키와 값의 쌍을 저장하고 키를 기준으로 자동으로 정렬하는 사전(Dictionary)이다.
  • 이 클래스는 System.Collections.Generic 네임스페이스에 포함되어 있으며, 키가 정렬 순서로 저장되어야 하는 시나리오에서 유용하다.

주요 특징

  1. 키의 정렬
    • 키를 기준으로 자동으로 정렬한다. 기본적으로 키는 기본 제공된 비교자(기본적으로 IComparable<TKey> 구현 또는 지정된 IComparer<TKey>)를 사용하여 정렬된다.
  2. 키와 값의 쌍
    • 다른 사전 컬렉션과 마찬가지로 키와 값의 쌍을 저장한다. 각 키는 고유하며, 동일한 키를 두 번 저장할 수 없다.
  3. 빠른 검색
    • 키에 대한 검색, 추가, 삭제가 모두 로그(log) 시간 내에 수행된다. 이는 내부적으로 이진 탐색 트리 구조를 사용하기 때문이다.
  4. 정렬된 열거
    • 컬렉션을 열거할 때 키의 정렬된 순서대로 열거하게 된다.

주요 메서드 및 속성

  • Add(TKey key, TValue value)
    • 지정한 키와 값 쌍을 사전에 추가한다.
  • Remove(TKey key)
    • 지정한 키를 가진 항목을 제거한다.
  • TryGetValue(TKey key, out TValue value)
    • 지정한 키가 있는 경우 값을 가져온다.
  • ContainsKey(TKey key)
    • 지정한 키가 있는지 확인한다.
  • ContainsValue(TValue value)
    • 지정한 값이 있는지 확인한다.
  • Clear()
    • 모든 항목을 제거한다.
  • Count
    • 사전에 있는 키-값 쌍의 수를 가져온다
  • Keys
    • 정렬된 키의 컬렉션을 가져온다.
  • Values
    • 정렬된 값의 컬렉션을 가져온다.

사용 시 고려 사항

  • 성능
    • SortedDictionary는 검색, 추가 및 삭제 작업에 대해 O(log n)의 시간 복잡도를 갖는다.
    • 이는 키의 순서가 중요하고, 삽입/삭제가 빈번하지 않은 경우에 적합하다.
  • 메모리 사용량
    • 내부적으로 이전 탐색 트리를 사용하기 때문에 일반적인 Dictionary<TKey, TValue> 보다 약간 더 많은 메모리를 사용할 수 있다
  • 정렬 기준
    • 기본적으로 키의 기본 비교자(키가 IComparable를 구현하는 경우)를 사용하여 정렬된다.
    • 사용 지정 비교자를 사용하려면 SortedDictionary 생성자에 IComparaer<TKey>를 제공할 수 있다.

데이터베이스 샤딩

  • 대규모 데이터베이스를 여러 머신에 저장하는 프로세스이다.
  • 단일 머신 또는 데이터베이스 서버는 제한된 양의 데이터만 저장하고 처리할 수 있다. 데이터베이스 샤딩은 데이터를 샤드라고 하는 더 작은 청크로 분할하고 여러 데이터베이스 서버에 저장함으로써 이러한 한계를 극복한다.
  • 모든 데이터베이스 서버의 기본 기술은 일반적으로 동일하며 함께 작동하여 대량의 데이터를 저장하고 처리한다.

샤딩

  • 분할된 데이터 청크를 논리적 샤드라고 한다. 논리적 샤드를 저장하는 시스템을 물리적 샤드 또는 데이터베이스 노드라고 한다. 하나의 물리적 샤드는 여러 개의 논리적 샤드를 포함할 수 있다.

샤드 키

  • 소프트웨어 개발자는 샤드 키를 사용하여 데이터 세트를 분할하는 방법을 결정한다.
  • 데이터 세트의 열은 함께 그룹화되어 샤드를 구성하게 될 데이터 행을 결정한다.
  • 데이터베이스 설계자는 기존 열에서 샤드 키를 선택하거나 새 샤드 키를 만든다.

비공유 아키텍처

  • 데이터베이스 샤딩은 비공유 아키텍처를 기반으로 작동한다.
  • 각 물리적 샤드는 독립적으로 작동하여 다른 샤드를 인식하지 못한다.
  • 요청한 데이터가 들어 있는 물리적 샤드만 해당 데이터를 병렬로 처리한다.
  • 소프트웨어 계층은 이러한 여러 샤드에서의 데이터 저장 및 액세스를 조율한다. 예를 들어 일부 유형의 데이터베이스 기술에는 자동 샤딩 기능이 내장되어 있다. 소프트웨어 개발자가 올바른 샤드에서 정보를 저장하거나 검색하는 샤딩 코드를 애플리케이션에 작성할 수도 있다.

중요한 이유

  • 애플리케이션이 성장함에 따라 애플리케이션 사용자 수와 애플리케이션에 저장되는 데이터의 양도 시간이 길수록 증가한다.
  • 데이터 볼륨이 너무 커지고 애플리케이션을 사용하여 동시에 정보를 읽거나 저장하려고 하는 사용자가 너무 많아지면 데이터베이스에서 병목 현상이 발생한다. 이로인해 애플리케이션 속도가 느려지고 고객 경험에 영향을 미치게 된다. 이에 대한 솔루션의 하나로, 여러 샤드에서 더 작은 데이터 세트를 병렬로 처리하는 데이터베이스 샤딩을 사용하면 이 문제를 해결할 수 있다.

이점

응답 시간 개선

  • 대규모의 단일 데이터베이스에서는 데이터를 검색하는 데 시간이 오래 걸린다. 데이터베이스 관리 시스템은 올바른 데이터를 찾기 위해 여러 행을 검색해야 한다.
  • 그에 비해 데이터 샤드는 전체 데이터베이스보다 행 수가 적다. 따라서 샤딩된 데이터베이스에서는 특정 정보를 검색하거나 쿼리를 실행하는 데 걸리는 시간이 단축된다.

전체 서비스 중단 방지

  • 데이터베이스를 호스팅하는 컴퓨터에서 장애가 발생하면 데이터베이스를 사용하는 애플리케이션에서도 오류가 발생한다.
  • 데이터베이스 샤딩은 데이터베이스의 일부를 다른 컴퓨터에 배포함으로써 이 같은 문제를 방지한다. 컴퓨터 중 하나에서 장애가 발생하더라도 정상 작동하는 다른 샤드를 사용하여 작동할 수 있으므로 애플리케이션이 중단되지 않는다.
  • 또한, 샤딩은 샤드 간 데이터 복자와 함께 사용되는 경우가 많다. 즉, 샤드 중 하나를 사용할 수 없게 되더라도 대체 샤드에서 데이터에 액세스하고 복원할 수 있다.

효율적인 크기 조정

  • 데이터베이스가 확장되면 더 많은 컴퓨팅 리소스를 소비하고 결국 스토리지의 최대 용량에 도달하게 된다. 이 경우 조직은 데이터베이스 샤딩을 사용하여 더 많은 컴퓨팅 리소스를 추가함으로써 데이터베이스의 확장을 지원할 수 있다.
  • 유지 관리를 위해 애플리케이션을 종료하지 않고도 런타임에 새 샤드를 추가할 수 있다.

샤딩 방법

범위 기반 샤딩

  • 범위 기반 샤딩 또는 동적 샤딩은 값의 범위에 따라 데이터베이스 행을 분할한다. 그러면 데이터베이스 설계자가 각 범위에 샤드 키를 할당한다.
  • 장점
    • 구현의 이점이 있다.
  • 단점
    • 데이터 값에 따라 단일 물리적 노드에서 데이터가 오버로드될 수 있다.

해시 샤딩

  • 해시 함수라는 수학 공식을 사용하여 데이터베이스의 각 행에 샤드 키를 할당한다.
  • 해시 함수는 행에서 정보를 가져와 해시 값을 산출한다.
  • 애플리케이션은 이 해시 값을 샤드 키로 사용하고 해당하는 물리적 샤드에 정보를 저장한다.
  • 소프트웨어 개발자는 해시 샤딩을 사용하여 데이터베이스의 정보를 여러 샤드 간에 고르게 분산할 수 있다.
  • 장점
    • 물리적 샤드 간 데이터를 고르게 분산한다.
  • 단점
    • 정보의 의미에 따라 데이터베이스를 분할하지는 않기 때문에 소프트웨어 개발자가 컴퓨팅 환경에 물리적 샤드를 더 추가할 때 해시 값을 재할당하는 데 어려움을 겪을 수 있다.

디렉터리 샤딩

  • 조회 테이블을 사용하여 데이터베이스 정보를 해당하는 물리적 샤드와 매칭한다.
  • 조회 테이블은 데이터베이스 열을 샤드 키에 연결하는 스프레드시트의 테이블과 같다.
  • 장점
    • 유연성이 좋다. 각 샤드는 데이터베이스의 의미 있는 표현이며 범위에 의해 제한되지 않는다.
  • 단점
    • 조회 테이블에 잘못된 정보가 포함되어 있으면 디렉터리 샤딩이 실패한다.

지리적 샤딩

  • 지리적 위치에 따라 데이터베이스 정보를 분할하고 저장한다.
  • 장점
    • 샤드와 요청하는 고객 간의 거리가 짧아 애플리케이션이 정보를 더 빠르게 검색할 수 있다.
    • 데이터 액세스 패턴이 주로 지리적 위치를 기반으로 하는 경우 이 기법이 효과적이다.
  • 단점
    • 데이터가 고르지 않게 분산될 수 있다.

고른 데이터 분산을 위해 최적화하는 방법

  • 다른 샤드의 로드가 낮은데 특정 물리적 샤드에서만 데이터 오버로드가 발생하면, 해당 샤드는 데이터베이스 핫스팟이 된다. 핫스팟이 발생하면 데이터베이스의 검색 프로세스 속도가 저하되므로 데이터 샤딩의 의미가 사라진다.
  • 샤드 키를 적절히 선택하면 여러 샤드에 데이터를 고르게 분산할 수 있다. 데이터베이스 설계자는 샤드 키를 선택할 때 다음 요소를 고려해야 한다.

카디널리티

  • 카디널리티는 샤드 키의 가능한 값을 설명한다.
  • 별도의 열 지향 데이터베이스에 따라 가능한 최대 샤드 수를 결정한다. 예를 들어 데이터베이스 설계자가 예/아니요 값을 가지는 데이터 필드를 샤드 키로 선택할 경우 샤드 수는 2개로 제한된다.

빈도

  • 특정 샤드에 특정 정보가 저장될 확률이다.

단순 변화

  • 샤드 키의 변화율이다.
  • 샤드 키가 단순 증가하거나 단순 감소하면 샤드의 균형이 맞지 않게 된다.

문제점

데이터 핫스팟

  • 데이터 분포가 고르지 않아 일부 샤드가 불균형하게 된다. 예를 들어 A로 시작하는 고객 이름을 포함하는 단일 물리적 샤드는 다른 샤드보다 많은 데이터를 수신한다. 따라서 이 물리적 샤드는 다른 샤드보다 더 많은 컴퓨팅 리소스를 사용한다.

운영 복잡성

  • 데이터베이스 샤딩은 운영의 복잡성을 유발한다. 개발자가 단일 데이터베이스를 관리하는 것이 아니라 여러 데이터베이스 노드를 관리해야 한다. 정보를 검색할 떄 개발자는 여러 샤드를 쿼리하고 정보를 결합해야 한다. 이러한 검색 작업은 분석을 복잡하게 만들 수 있다.

인프라 비용

  • 조직에서 물리적 샤드로 추가하는 컴퓨터가 많을수록 인프라 비용이 더 많이 발생한다. 온프레미스 데이터 센터의 시스템 수를 늘리면 유지 관리 비용이 가중될 수 있다.

애플리케이션 복잡성

  • 대부분의 데이터베이스 관리 시스템에는 샤딩 기능이 내장되어 있지 않다. 따라서 데이터베이스 설계자와 소프트웨어 개발자가 데이터베이스를 수동으로 분할하고 분산하고 관리해야 한다.
728x90

'Study > TIL(Today I Learned)' 카테고리의 다른 글

24.08.05 C#  (0) 2024.08.05
24.08.02 C#, DEV  (0) 2024.08.02
24.07.31 C#  (0) 2024.07.31
24.07.30 C#, 배치 파일과 도스 명령어, 게임 서버  (1) 2024.07.30
24.07.29 C#, 게임 서버  (0) 2024.07.29