Materialized Views:

  • 정의:
    • Materialized View(MV)는 쿼리 결과를 저장하고 있는 데이터베이스 객체입니다. 이렇게만 말하면 SQL 데이터베이스에만 국한된 개념처럼 보이지만 좀 더 넓은 개념의 의미로 보면 Materialized View는 데이터의 사본을 미리 계산하고 저장하여 성능을 향상시키는 기법입니다.
  • When to use:
    • 복잡한 쿼리: 여러 조인, 집계 및 계산을 포함하는 복잡한 쿼리라서 데이터를 직접 쿼리하기 어려울 때
    • 반복적인 읽기 작업: 자주 읽히는 데이터의 경우 Materialized View 기법을 통해서 읽기 성능을 향상 시킬 수 있습니다.
    • 데이터 집계: 집계 연산 (Aggregation, 합계, 평균, 개수 등) 에서 Materialized Views 를 통해 사전 집계된 결과를 제공해서 성능을 향상 시킬 수 있습니다.
    • 서로 다른 데이터 저장소의 기능을 활용하기 위해서. 예를 들면 쓰기에 효율적인 데이터 스토어는 데이터를 저장소 역할로 사용하고, 쿼리와 읽기 성능이 좋은 관계형 데이터 스토어에서 Materialized View 를 저장하는 식으로.
  • How to use:
    • SQL 에서의 Materialized View 는 Materialized View 객체를 생성하고, 갱신 전략과 그것에 맞는 갱신 주기를 설정하고 조회하면 됩니다.
    • 추가로 너무 자주 갱신할 경우 성능에 부담이 되고, 너무 늦게 갱신하면 오래된 데이터를 볼 수 있는 문제가 발생할 수 있습니다.
  • Considerations:
    • 갱신 오버헤드: 갱신 시 리소스가 소요되는 걸 고려해서 갱신 전략과 갱신 주기를 설정하세요.
    • Dsposability and Regeneratibility: Materialized View 가 없어지거나 만료되더라도 원본 데이터에서 다시 만들 수 있어야 합니다.
    • Consistency: Materialized View 는 원본 데이터로 만들어진 별도의 캐싱 데이터 이므로 데이터 일관성이 안 맞을 수 있습니다. 이것에 대한 고려도 필요합니다.
    • 원본 데이터가 단순하거나 쿼리하기 쉽다면 이 기법은 적절하지 않을 수 있습니다.

 

 

Indexing:

  • 정의:
    • 데이터베이스의 특정 열에 대해 검색 속도를 향상시키기 위해 데이터 구조를 사용하는 전략입니다.
  • When to use:
    • 빈번한 검색: 자주 검색되는 열에 대해 인덱스를 생성하면 검색 성능을 크게 향상시킬 수 있습니다.
    • JOIN 및 WHERE 절: JOIN이나 WHERE 절에서 자주 사용되는 열에 인덱스를 생성하면 쿼리 성능이 향상됩니다.
    • 정렬과 그룹화: ORDER BY나 GROUP BY 구문에서 자주 사용되는 열에 인덱스를 생성하면 성능이 개선될 수 있습니다.
  • How to use:
    • 데이터베이스에서 인덱스를 사용하는 방법은 간단합니다. 인덱스로 사용할 테이블 칼럼을 선택하고 생성만 하면 사용됩니다.
  • Considerations:
    • 인덱스 오버헤드: 인덱스 생성 및 유지 관리에는 추가 저장 공간과 CPU 자원이 필요합니다. 인덱스가 많아지면 데이터 삽입, 업데이트, 삭제 작업의 성능이 저하될 수 있습니다.
    • 인덱스 선택: 모든 열에 인덱스를 생성하는 것은 바람직하지 않습니다. 자주 사용되는 열과 쿼리 성능에 중요한 열에 인덱스를 생성하는 것이 좋습니다.

 

 

Denormalziation

  • 정의:
    • 비정규화(Denormalization)는 데이터베이스의 성능을 향상시키기 위해 데이터를 중복 저장하는 전략입니다. 이는 데이터를 정규화하여 중복을 최소화하는 것과 반대되는 개념으로, 특정 쿼리 성능을 최적화하기 위해 데이터를 중복 저장하여 조인을 줄이고 조회 속도를 향상시킵니다.
  • When to use:
    • 읽기 성능 향상: 데이터 읽기 작업이 빈번하고, 읽기 성능이 중요할 때 비정규화를 통해 데이터를 중복 저장하여 조회 속도를 높일 수 있습니다.
    • 복잡한 조인 줄이기: 여러 테이블을 조인하는 복잡한 쿼리를 자주 실행해야 하는 경우, 비정규화를 통해 조인을 줄이고 쿼리 성능을 향상시킬 수 있습니다.
    • 데이터 통합: 서로 다른 데이터 소스에서 데이터를 통합하여 조회할 때, 비정규화를 통해 데이터를 하나의 테이블에 저장하고 조회 성능을 높일 수 있습니다.
  • How to use:
    • 비정규화를 적용하려면 먼저 어떤 데이터가 중복 저장될지 결정해야 합니다. 자주 사용되는 데이터를 식별하고, 해당 데이터를 중복 저장하여 조회 성능을 향상시킵니다.
  • Considerations:
    • 데이터 일관성: 데이터가 중복 저장되므로 일관성을 유지하기 어려울 수 있습니다. 데이터가 변경될 때마다 비정규화된 데이터를 업데이트해야 하므로, 이를 위한 추가적인 로직이 필요합니다
    • 저장 공간 증가: 비정규화는 데이터를 중복 저장하므로 저장 공간 요구량이 증가할 수 있습니다. 데이터베이스의 저장 공간을 충분히 확보해야 합니다.

 

 

Vertical Scaling:

  • 정의:
    • Vertical Scaling(수직적 확장)은 기존 서버나 데이터베이스의 하드웨어 사양을 업그레이드하여 성능을 향상시키는 방법입니다. 주로 CPU, RAM, 스토리지와 같은 자원을 추가하거나 교체하는 방식으로 이루어집니다.
  • When to use:
    • 단일 서버의 성능이 충분하지 않을 때: 현재 사용 중인 서버가 증가하는 데이터 처리량을 감당하지 못할 때 수직적 확장을 통해 성능을 향상시킬 수 있습니다.
    • 애플리케이션 구조가 수평적 확장을 지원하지 않을 때: 애플리케이션이 여러 서버에 분산될 수 없는 경우, 단일 서버의 성능을 높이는 것이 효과적입니다.
    • 쉽게 성능 향상이 필요할 때: 하드웨어 업그레이드는 상대적으로 쉽게 성능을 향상시킬 수 있는 방법입니다.
  • How to use:
    • 하드웨어 업그레이드: 서버의 CPU, RAM, 스토리지 등의 하드웨어를 업그레이드합니다.
    • 가상 머신 또는 클라우드 인스턴스 업그레이드: 클라우드 환경에서는 더 높은 사양의 인스턴스로 업그레이드할 수 있습니다.
  • Considerations:
    • 비용: 수직적 확장은 초기 비용이 높을 수 있습니다. 고성능 하드웨어는 높은 비용을 수반하므로 예산을 고려해야 합니다.
    • 확장 한계: 수직적 확장은 물리적 한계가 있습니다. 하드웨어의 최대 성능에 도달하면 더 이상 확장할 수 없으므로, 장기적인 확장성 계획을 고려해야 합니다.
    • 단일 장애점(Single Point of Failure): 단일 서버에 의존하는 경우, 해당 서버가 장애를 일으키면 전체 시스템이 영향을 받을 수 있습니다. 이 경우 고가용성 및 백업 계획을 수립하는 것이 중요합니다.

Caching:

  • 정의:
    • 캐싱 (Caching) 은 자주 조회되는 데이터를 임시 저장소에 저장하여 데이터베이스 접근을 줄이고 응답 시간을 단축시키는 전략입니다. 메모리나 고속 스토리지를 사용하여 데이터를 임시로 저장함으로써 데이터베이스 성능을 향상시킬 수 있습니다.
  • When to use:
    • 자주 조회되는 데이터: 특정 데이터가 자주 조회되는 경우, 캐싱을 통해 데이터베이스 부하를 줄이고 응답 시간을 개선할 수 있습니다.
    • 읽기 성능 최적화: 읽기 작업이 빈번하고, 빠른 응답 시간이 중요한 경우 캐싱을 통해 성능을 최적화할 수 있습니다.
    • 복잡한 쿼리 결과 캐싱: 복잡한 쿼리를 자주 실행해야 하는 경우, 쿼리 결과를 캐싱하여 성능을 향상시킬 수 있습니다.
    • API 응답 속도 개선: 웹 애플리케이션이나 API의 응답 속도를 개선하기 위해 캐싱을 사용할 수 있습니다.
  • How to use:
    • 캐시 설정: 캐시를 설정하려면 먼저 캐시 저장소를 선택합니다. Redis, Memcached, 로컬 메모리 등을 사용할 수 있습니다.
    • 캐시 정책 결정: 캐시 만료 시간(TTL, Time to Live)과 갱신 정책을 설정합니다. 캐시 만료 시간은 데이터의 유효 기간을 결정하며, 갱신 정책은 캐시 데이터가 만료되거나 갱신될 시점을 결정합니다.
    • 데이터 일관성 유지: 캐시된 데이터와 원본 데이터의 일관성을 유지하기 위한 전략을 마련합니다. 원본 데이터가 변경될 때 캐시를 갱신하거나 무효화하는 로직을 구현합니다.
  • Considerations:
    • 캐시 적중률(Cache Hit Rate): 캐시의 효율성을 높이기 위해 캐시 적중률을 모니터링합니다. 캐시 적중률이 낮다면 캐시 정책을 재검토하여 개선합니다.
    • 데이터 일관성: 캐시된 데이터는 원본 데이터가 변경되었을 때 일관성을 유지하기 어려울 수 있습니다. 데이터가 갱신될 때 캐시를 무효화하거나 갱신하는 전략이 필요합니다.
    • 캐시 오버헤드: 캐싱은 추가 저장 공간과 메모리 사용을 필요로 합니다. 캐시 크기를 적절히 관리하여 메모리 사용량을 최적화해야 합니다.
    • TTL 설정: 캐시 만료 시간을 적절히 설정하여 데이터의 최신성과 성능 사이의 균형을 맞춥니다. 너무 짧으면 캐시의 이점을 살리기 어렵고, 너무 길면 오래된 데이터를 반환할 위험이 있습니다.

 

 

Replication:

  • 정의:
    • 데이터베이스 복제(Replication)는 데이터베이스의 데이터를 다른 서버에 복제하여 고가용성 및 성능을 향상시키는 전략입니다. 복제된 데이터베이스는 읽기 작업을 분산시키고, 데이터베이스 장애 시에도 시스템을 지속적으로 운영할 수 있도록 합니다.
  • When to use:
    • 고가용성 요구: 시스템의 고가용성이 중요한 경우, 복제를 통해 장애 시에도 서비스가 중단되지 않도록 할 수 있습니다.
    • 읽기 성능 향상: 읽기 작업이 빈번한 경우, 여러 복제본으로 읽기 작업을 분산시켜 성능을 향상시킬 수 있습니다.
    • 백업 및 복구: 데이터를 다른 서버에 복제함으로써 백업 및 복구 작업을 용이하게 할 수 있습니다.
    • 지연시간 향상: 여러 지역에 걸쳐 데이터를 분산하여 사용자에게 더 가까운 서버에서 데이터를 제공할 수 있습니다.
  • How to use:
    • 마스터-슬레이브 복제: 한 서버(마스터)가 쓰기 작업을 처리하고, 다른 서버들(슬레이브)이 읽기 작업을 처리하도록 설정하도록 할 수 있습니다.
    • 다중 리더 복제: 두 개 이상의 서버가 모두 쓰기 및 읽기 작업을 처리할 수 있도록 설정하도록 할 수 있습니다.
    • 비동기 및 동기 복제: 비동기 복제는 성능이 좋지만 데이터 일관성이 떨어질 수 있고, 동기 복제는 데이터 일관성이 높지만 성능이 저하될 수 있습니다. 필요에 따라 선택합니다.
    • 멀티 스레딩 복제: 복제 작업을 병렬로 처리하여 성능을 향상시키는 방법입니다. 슬레이브 서버에서 여러 스레드를 사용하여 마스터의 데이터를 병렬로 복제합니다.
    • 리더 없는 복제(Leaderless Replication): 모든 노드가 동등한 역할을 하여 데이터 읽기 및 쓰기 작업을 분산 처리하는 방식입니다. 주로 NoSQL 데이터베이스에서 사용되며, 각 노드가 독립적으로 작동하여 고가용성과 확장성을 제공합니다.
  • Considerations:
    • 복제 지연: 네트워크 지연이나 복제 설정에 따라 데이터 복제에 시간이 걸릴 수 있습니다. 복제 지연이 발생한다면 최신 데이터 조회의 어려움, 복제 서버의 성능 저하 등이 일어날 수 있기 때문에 복제 지연을 최소화하기 위한 네트워크 설정 및 모니터링이 필요합니다.
    • 데이터 일관성: 비동기 복제는 실시간으로 데이터가 동기화되지 않으므로 일관성 문제가 발생할 수 있습니다. 동기 복제를 통해 데이터 일관성을 유지할 수 있지만 성능에 영향을 줄 수 있습니다.
    • 충돌 해결: 마스터-마스터 복제에서는 동일한 데이터에 대한 충돌이 발생할 수 있습니다. 충돌 해결 정책을 마련해야 합니다.

 

 

Shrading:

  • 샤딩(Sharding)은 데이터베이스를 여러 개의 작은 단위(샤드)로 분할하여 각각 독립적인 데이터베이스 서버에 저장하는 전략입니다. 각 샤드는 전체 데이터의 일부를 포함하며, 이를 통해 대규모 데이터베이스의 성능과 확장성을 향상시킬 수 있습니다.
  • When to use:
    • 데이터베이스 크기가 매우 큰 경우: 단일 서버가 전체 데이터를 처리하기 어려운 경우 샤딩을 통해 데이터베이스를 분할하여 처리 성능을 높일 수 있습니다.
    • 높은 트래픽: 많은 사용자가 동시에 데이터베이스에 접근할 때 샤딩을 통해 트래픽을 여러 서버에 분산시킬 수 있습니다.
    • 높은 쓰기/읽기 작업: 데이터 쓰기와 읽기 작업이 많은 경우, 샤딩을 통해 특정 샤드에서만 작업을 처리하여 성능을 최적화할 수 있습니다.
    • 데이터 분리 요구: 지리적 위치나 비즈니스 요구에 따라 데이터를 분리하여 저장해야 할 때 샤딩을 활용할 수 있습니다.
  • How to use:
    • 샤드 키 선택: 데이터를 분할할 기준이 되는 샤드 키를 선택합니다. 일반적으로 사용자 ID, 지역 코드, 타임스탬프 등이 샤드 키로 사용됩니다.
    • 샤딩 알고리즘 선택: 샤딩 알고리즘을 선택하여 데이터를 분할합니다. 주요 알고리즘으로는 다음과 같은 두 가지가 있습니다:
      • Range 기반 샤딩: 샤드 키의 범위에 따라 데이터를 분할합니다. 예를 들어, 특정 사용자 ID 범위마다 다른 샤드에 저장합니다.
      • Hashing 기반 샤딩: 샤드 키를 해싱하여 데이터를 분산합니다. 이 방식은 데이터를 고르게 분산시키는 데 유리합니다.
    • 데이터베이스 분할: 샤드 키를 기반으로 데이터를 여러 데이터베이스 서버에 분할 저장합니다.
    • Routing 로직 구현: 데이터베이스 시스템이 자동으로 샤딩을 지원하지 않는 경우, 애플리케이션 레벨에서 샤드 키를 이용해 데이터를 적절한 샤드에 라우팅하는 로직을 구현합니다. MongoDB와 같은 일부 데이터베이스는 이 로직을 자체적으로 지원합니다
  • Considerations:
    • 데이터 일관성: 여러 샤드에 데이터가 분산되므로, 트랜잭션을 처리할 때 데이터 일관성을 유지하는 것이 어려울 수 있습니다. 분산 트랜잭션 관리나 eventual consistency 모델을 고려해야 합니다.
    • 샤드 간 조인: 샤드 간 조인이 필요한 경우 성능 저하가 발생할 수 있습니다. 가능한 샤드 내에서 데이터를 처리하고, 샤드 간 조인을 최소화하는 설계를 고려해야 합니다.
    • 샤드 키 선택: 샤드 키를 적절히 선택하지 않으면 특정 샤드에 데이터가 집중되어 부하가 증가할 수 있습니다. 고르게 분산되는 샤드 키를 선택하는 것이 중요합니다.
    • 리밸런싱 문제: 데이터 분포가 불균형해질 때, 샤드 추가/제거가 발생할 때 리밸런싱 작업이 필요합니다. 이를 위해 데이터 이동 및 재분할 작업을 효율적으로 자동화하는 방법을 마련해야합니다.
    • Hot Spot 문제: 특정 샤드에 데이터가 집중되어 해당 샤드에 과부하가 발생하는 문제가 발생할 수 있습니다.

 

References: 

+ Recent posts