2024. 3. 19. 16:52ㆍ기술 창고/Java
분산 시스템의 알고리즘과 설계를 진행하기 이전에, 분산 시스템에서 가장 기본적이고 공통적인 두 가지 용어부터 알아보겠습니다.
(1) 노드 (node)
노드는 분산 시스템의 일부로 동작하는 시스템에서 실행되는 각 프로세스입니다.
분산 시스템에서는 두 노드 사이에 선분이 존재하면 두 프로세스가 네트워크를 통해 서로 통신할 수 있다는 뜻입니다.
(2) 클러스터 (cluster)
클러스터는 서로 연결된 노드의 모음입니다.
한 클러스터의 노드들은 동일한 작업을 수행하며 일반적으로 동일한 코드로 실행됩니다.
보통 우리는 분석해야하거나 복잡한 계산이 필요한 데이터의 양이 매우 많을 경우, 이 작업을 수행하기 위해 노드가 모여 있는 특정 클러스터로 넘기길 원합니다.
여기서 문제는, 어느 노드에서 어떤 작업을 수행할 것인지 모른다는 점입니다.
분산 시스템의 가장 큰 이점은 작업을 병렬화하고, 각 노드가 공동의 목표를 위해 독립적으로 동작할 수 있다는 것입니다.
이 작업들을 수동으로 분배해서 각 노드에 별도의 작업을 할당할 수도 있습니다.
하지만 수동으로 분배하는 것은 확장성 면에서 매우 효율성이 좋지 않다고 볼 수 있습니다.
우리는 초당 수천 개의 작업을 요청받을 수도 있기 때문에 작업을 분산하기 위한 프로그램이 필요합니다.
전부 수동으로 분배하는 대신에 노드 하나를 직접 선택해 리더나 마스터로 지정하여 마스터로 지정된 노드가 작업 분배와 결과 수집을 담당하게 할 수도 있습니다.
이 방식을 사용한다면 처음 얘기한 수동 분배방식보다는 낫지만, 문제는 마스터 노드를 포함한 모든 노드가 언제든 작업 수행에 실패할 수 있습니다.
대규모 분산 시스템에는 당연히 장애가 발생하지만 언제 발생하는지가 문제입니다.
리더 노드가 배포하지 않거나 결과를 수집하지 않으면 클러스터 전체가 동작하지 않게 되는 것이죠.
리더 지정 방식의 문제점을 해결하기 위해서는 리더 노드를 직접 지정하고 모든 노드가 리더의 상태를 예의 주시할 수 있도록 알고리즘을 구축해야 합니다.
리더 노드가 동작할 수 없다면, 나머지 노드들이 마스터를 다시 지정할 수 있도록 말입니다.
동작이 중지된 이전 리더 노드가 다시 클러스터에 복귀하게 되었을 때에는 자신이 리더 노드가 아니라는 점을 알아채고 작업을 돕는 일반 노드로 참여하게 합니다.
이러한 알고리즘을 구성해야만 비로소 우리가 원하는 분산 시스템이 설계가 되는 것입니다.
주키퍼 (Zookeeper)
주키퍼는 분산 시스템을 위해 특별히 설계된 고성능의 분산 코디네이터입니다.
많은 회사에서 사용되고 있고, 카프카, 하둡, HBase 와 같은 범용 프로젝트와 다양한 프로젝트에서 사용됩니다.
주키퍼는 클러스터에 알고리즘을 구현할 때, 시각적으로 볼 수 있도록 추상화 계층을 제공합니다.
주키퍼 장점
(1)
주키퍼는 그 자체로 분산 시스템이며, 호환성 높은 알고리즘을 사용하여 높은 가용성과 신뢰성을 보장합니다.
운영될 때는 일반적으로 3개 이상의 노드로 구성된 클러스터로 실행됩니다.
이런 특성 덕분에 주키퍼 노드 하나를 잃어도 시스템이 온전히 작동하도록 유지할 수 있습니다.
노드들이 서로 통신하여 작업을 조정하는 대신 노드들이 주키퍼 서버와 직접 통신하도록 하는 방식으로 주키퍼를 사용하게 될 것입니다.
(2)
주키퍼는 사용하기 쉬운 소프트웨어 추상화 도구와 데이터 모델을 제공합니다.
마치 트리 구조처럼 보여 파일 시스템과 아주 비슷하고, 이 트리 또는 가상 파일 시스템의 각 요소를 Z노드라고 합니다.
Z노드는 파일과 디렉터리의 중간 형태이며, 데이터를 저장할 수도 있고 디렉터리처럼 하위 노드를 가질 수도 있습니다.
Z노드에는 영구 노드와 임시 노드, 두 가지 유형이 있습니다.
영구 Z노드는 세션이 끊어져도 남아있습니다.
프로그램이 주키퍼와 연결이 끊어졌다가 다시 연결되도 우리의 프로그램이 만든 영구 Z노드는 모든 하위 데이터와 함께 그대로 유지됩니다.
임시 Z노드는 정반대의 특징을 가지고 있습니다.
해당 Z노드를 만든 응용 프로그램이 주키퍼와 연결이 끊어지는 즉시 삭제됩니다.
여기서, 임시 Z노드가 임시 노드를 생성한 다른 노드가 중단되었는지 확인할 수 있는 유용한 도구라는 것을 알 수 있습니다.
리더 선출 알고리즘 설계
(1)
첫 번째 단계에서는 주키퍼와 연결된 모든 노드가 리더 후보에 자원합니다.
각 노드는 선거에 출마하기 위해 자신을 나타내는 Z노드를 election 부모 노드 밑에 추가합니다.
주키퍼는 전체 순서를 관리하므로 추가 순서에 따라 각 Z노드의 이름을 지정할 수 있습니다.
(2)
두 번째 단계에서는 각 노드가 Z노드 생성을 마친 후 election 부모 노드에게 현재 자식들을 물어봅니다.
노드 순서는 주키퍼가 우리에게 제공하기 때문에 각 노드는 election 부모 노드의 자식 노드를 자신이 Z노드를 생성하기 전에 생성된 모든 Z노드를 볼 수 있습니다.
(3)
세 번째 단계에서는 현재 노드가 만든 Z노드의 숫자가 가장 작다면 해당 노드가 리더라는 것을 알 수 있습니다.
반대로, 현재 노드인 Z노드의 숫자가 가장 작지 않다면 그 노드는 리더가 아니라는 것을 알 수 있습니다.
그런 노드는 새로 뽑힌 리더 노드의 지시를 기다립니다.
이것이 우리가 리더 선출 알고리즘의 기본 설계 과정입니다.
이렇게 해서 분산 시스템을 위한 코디네이터인 주키퍼에 대해 간단히 알아보고, 분산 시스템을 위한 설계 알고리즘 중 하나인 리더 선출 알고리즘에 대해 알아보았습니다.
'기술 창고 > Java' 카테고리의 다른 글
[Java] 주키퍼 서버 / 클라이언트 (다운로드 및 설정) (0) | 2024.03.20 |
---|---|
[Java] Java를 활용한 분산 시스템 (0) | 2024.03.19 |
[Java] record (0) | 2023.05.30 |
[Java] equalsIgnoreCase("~") (0) | 2023.04.03 |
[Java] System.out.println 메소드 지양 이유 (0) | 2023.02.01 |