분산 쿼리 (distributed query)

여러 노드에 분산된 데이터를 대상으로 쿼리를 실행하고 결과를 얻는 과정.

분산 쿼리 처리의 핵심 단계:

  1. 쿼리 분석 및 최적화
    사용자가 쿼리를 요청하면, 시스템은 먼저 전체 데이터베이스 시스템에서 가장 효율적인 실행 계획을 수립한다.
    이 과정에서 다음과 같은 요소들을 고려한다:

    • 데이터의 물리적 위치
    • 네트워크 대역폭과 지연 시간
    • 각 노드의 처리 능력
    • 데이터 전송 비용
      예를 들어, 다음과 같은 쿼리가 있다고 가정해보면,
    1
    2
    3
    4
    
    SELECT customers.name, orders.order_date
    FROM customers JOIN orders 
    ON customers.id = orders.customer_id
    WHERE orders.amount > 1000;
    

    이 쿼리가 서울과 부산에 분산된 데이터베이스에서 실행된다면, 시스템은 다음과 같은 실행 계획을 수립할 수 있다:

    1. 부산 노드에서 orders 테이블의 필터링을 먼저 수행
    2. 필터링된 결과를 서울 노드로 전송
    3. 서울 노드에서 최종 조인 연산 수행
  2. 병렬 처리 전략
    분산 환경에서는 여러 노드가 동시에 작업을 수행할 수 있다.
    주요 병렬 처리 전략은 다음과 같다:
    1. 인트라-연산 병렬성(Intra-operation parallelism):
    하나의 연산을 여러 노드에서 동시에 처리한다.
    예를 들어, 테이블 스캔을 여러 노드에서 동시에 수행할 수 있다.
    2. 인터-연산 병렬성(Inter-operation parallelism):
    서로 다른 연산들을 파이프라인 형태로 동시에 처리한다.
    예를 들어, 한 노드에서 조인을 수행하는 동안 다른 노드에서는 정렬을 수행할 수 있다.

  3. 데이터 전송 최적화
    분산 환경에서 가장 큰 병목은 보통 네트워크 통신.
    따라서 다음과 같은 최적화 기법들이 사용된다:
    1. 세미조인(Semijoin):

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    -- 원래 쿼리
    SELECT *
    FROM TableA JOIN TableB 
    ON TableA.id = TableB.id;
    
    -- 세미조인을 사용한 최적화
    -- 1단계: TableB에서 필요한 id만 추출
    SELECT DISTINCT id FROM TableB;
    
    -- 2단계: 추출된 id와 매칭되는 TableA 데이터만 가져옴
    SELECT * FROM TableA 
    WHERE id IN (SELECT DISTINCT id FROM TableB);
    
    1. 데이터 복제(Replication):
      자주 사용되는 데이터는 여러 노드에 복제하여 네트워크 전송을 최소화한다.
  4. 트랜잭션 관리
    분산 환경에서의 트랜잭션 관리는 2단계 커밋(Two-Phase Commit) 프로토콜을 주로 사용한다:
    1. 준비 단계(Prepare Phase):
    모든 참여 노드들에게 트랜잭션 커밋 준비를 요청한다.
    2. 커밋 단계(Commit Phase):
    모든 노드가 준비되었다고 응답하면 최종 커밋을 수행한다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    # 의사 코드로 표현한 2단계 커밋
    def two_phase_commit(transaction, nodes):
        # 준비 단계
        for node in nodes:
            ready = node.prepare(transaction)
            if not ready:
                return rollback_all(nodes)
    
        # 커밋 단계
        for node in nodes:
            success = node.commit(transaction)
            if not success:
                return rollback_all(nodes)
    
        return True
    
  5. 장애 처리
    분산 환경에서는 다양한 장애가 발생할 수 있다.
    주요 장애 처리 전략은 다음과 같다:

    • 노드 실패: 다른 노드로 작업을 재할당
    • 네트워크 지연: 타임아웃 설정 및 재시도 메커니즘 구현
    • 부분 실패: 트랜잭션 롤백 및 복구 절차 수행

참고 및 출처