관리 메뉴

HAMA 블로그

예제로 보는 아카(akka) - 11. 클러스터 (분산컴퓨팅) 본문

Akka

예제로 보는 아카(akka) - 11. 클러스터 (분산컴퓨팅)

[하마] 이승현 (wowlsh93@gmail.com) 2016. 10. 11. 13:34

Akka 공식문서 번역


- 개념 참고

- 예제 참고



Akka Cluster 

이전에 원격 액터에 접속하는 방식을 배웠었다. 원격 액터에 접근 하기위해서는 그 액터에 대한 특정위치를 액터 셀렉션을 통해서 얻어서 메세지를 보냈지만 이 포스트를 통해 알게 될 아카 클라우드는 액터들이 구름상에 어디 있는지 중요하지 않고 어딘가의 액터에게 메세지를 보낼 때 필요하다. 실행시간에 그런 노드들은 자연스럽게 참여 했다가 빠질 수 도 있다. 즉 확장성과 탄력성을 보장한다. 역할을 구분해서 그룹핑 할 수 도 있지만 주로 동일한 작업을 분산시켜서 사용 할 때 필요하다.  예를들어 맵/리듀스 (워드카운팅) 같은거 말이다. 


개념 


아카 클러스터는 단일지점 장애와 단일지점 병목을 없앤 중앙화 되지 않은 내구성 강한 peer to peer 기반 클러스터 멤버쉽을 제공한다.  gossip 프로토콜과 오토마틱  failure detector을 이용한다.
node
클러스터의 논리 구성원. 물리적 머신에는 여러 개의 노드가있을 수 있습니다. hostname : port : uid tuple에 의해 정의됩니다.
cluster
멤버십 서비스를 통해 서로 조인 된 노드 세트입니다.
leader
리더로 작동하는 클러스터의 단일 노드입니다. 클러스터 통합 및 멤버 상태 전환 관리.

Membership


클러스터는 일련의 구성원 노드로 구성됩니다. 각 노드의 식별자는 hostname : port : uid tuple입니다. Akka 응용 프로그램은 각 노드가 응용 프로그램의 일부를 호스팅하는 클러스터를 통해 배포 할 수 있습니다. 클러스터 멤버쉽과 애플리케이션의 해당 노드에서 실행중인 액터는 분리됩니다. 노드는 액터를 호스팅하지 않고 클러스터의 구성원이 될 수 있습니다. 클러스터 결합은 결합 명령을 클러스터의 노드 중 하나에  행하여 시작됩니다.

노드 식별자는 내부적으로 해당 호스트 이름 : 포트에서이 액터 시스템 인스턴스를 고유하게 식별하는 UID도 포함합니다. Akka는 UID를 사용하여 신뢰할 수있는 원격 감시를 시작할 수 있습니다. 즉, 동일한 액터 시스템은 해당 클러스터에서 제거 된 후에는 다시 클러스터에 참여할 수 없습니다. 동일한 호스트 이름 : 포트를 가진 액터 시스템을 클러스터에 다시 가입 시키려면 액터 시스템을 중지하고 동일한 호스트 이름 : 포트를 가진 새 호스트를 시작해야합니다. 그러면 다른 UID가 수신됩니다.

클러스터 멤버쉽 상태는 특수 CRDT이며, 이는 단조 병합 기능을 가짐을 의미합니다. 다른 노드에서 동시 변경이 발생하면 항상 업데이트를 병합하고 동일한 최종 결과로 수렴 할 수 있습니다.


gossip

Akka에서 사용 된 클러스터 멤버쉽은 Amazon의 Dynamo 시스템과 특히 Basho의 'Riak 분산 데이터베이스'에서 채택 된 접근 방식을 기반으로합니다. 클러스터 멤버십은 클러스터의 현재 상태가 클러스터를 통해 무작위로 가십 (gossip)되는 가십 프로토콜 (Gossip Protocol)을 사용하여 전달되며 최신 버전을 보지 못한 멤버를 우선으로합니다.


Vector clock

벡터 시계는 분산 시스템에서 이벤트의 부분 순서를 생성하고 인과 관계 위반을 탐지하는 데이터 구조 및 알고리즘 유형입니다.
우리는 험담을하는 동안 벡터 시계를 사용하여 클러스터 상태의 차이를 조정하고 병합합니다. 벡터 시계는 (노드, 카운터) 쌍의 집합입니다. 클러스터 상태에 대한 각 업데이트에는 벡터 시계 업데이트가 수반됩니다.

Gossip Convergence 

클러스터에 대한 정보는 특정 시점에서 노드에서 로컬로 수렴합니다. 이는 노드가 관찰중인 클러스터 상태가 클러스터의 다른 모든 노드에서 관찰되었음을 증명할 수있는 경우입니다. 컨버전스는 가십 동안 현재 상태 버전을 본 노드 집합을 전달하여 구현됩니다. 이 정보는 가십 개요에서 본 세트라고합니다. 모든 노드가 보이는 집합에 포함되면 수렴됩니다.
모든 노드에 도달 할 수없는 동안 가십 컨버전스는 발생할 수 없습니다. 노드를 다시 연결할 수 있어야하거나 아래쪽 및 제거 된 상태로 이동해야합니다 (아래의 멤버십주기 섹션 참조). 이는 리더가 클러스터 멤버십 관리를 수행하는 것을 차단하고 클러스터의 최상위에서 실행되는 응용 프로그램에는 영향을 미치지 않습니다. 예를 들어 이는 네트워크 파티션에서 더 많은 노드를 클러스터에 추가 할 수 없음을 의미합니다. 노드는 결합 할 수 있지만 파티션이 치료되거나 도달 할 수없는 노드가 다운 될 때까지 업 상태로 이동하지 않습니다.


failure detector 

장애 감지기는 노드가 나머지 클러스터에서 도달 할 수 없는지 감지하려고합니다. 이를 위해 우리는 Hayashibara et al.의 The Phi Accrual Failure Detector의 구현을 사용하고 있습니다.

누적 실패 감지기는 모니터링 및 해석을 분리합니다. 따라서 광범위한 시나리오에 적용 할 수 있으며 일반적인 장애 감지 서비스를 구축하는 데 더 적합합니다. 그 아이디어는 다른 노드로부터받은 하트 비트로부터 계산 된 실패 통계의 이력을 유지하고 여러 요소를 취하여 교육 된 추측을 시도하고, 시간이 지남에 따라 축적되는 방식을 고려하여보다 나은 결과를 도출하는 것입니다 특정 노드가 위 또는 아래에 있는지 추측하십시오. 질문에 "예"또는 "아니오"로 대답하는 것보다 "노드가 다운 되었습니까?" 노드가 다운되었을 가능성을 나타내는 phi 값을 반환합니다.
계산의 기초가되는 임계 값은 사용자가 구성 할 수 있습니다. 낮은 임계 값은 많은 잘못된 의구심을 유발하는 경향이 있지만 실제 충돌시 빠른 탐지를 보장합니다. 반대로 높은 임계 값은 실수를 적게 생성하지만 실제 충돌을 감지하는 데 더 많은 시간이 필요합니다. 기본 임계 값은 8이며 대부분의 상황에 적절합니다. 그러나 Amazon EC2와 같은 클라우드 환경에서는 때때로 이러한 플랫폼에서 발생하는 네트워크 문제를 고려하여 값을 12로 늘릴 수 있습니다.
클러스터에서 각 노드는 몇 개의 (기본 최대 5 개) 다른 노드로 모니터되며, 이들 중 하나가 도달 할 수 없다고 노드를 감지하면 해당 정보가 가십을 통해 클러스터의 나머지 부분으로 확산됩니다. 즉, 한 노드 만 노드를 도달 할 수 없음으로 표시하여 나머지 클러스터가 해당 노드에 도달 할 수 없음을 표시해야합니다.

모니터링 할 노드는 해시 된 노드 링의 이웃 노드에서 선택됩니다. 이는 랙 및 데이터 센터에서 모니터 할 가능성을 높이기위한 것이지만 모든 노드에서 순서가 동일하므로 전체 범위를 보장합니다.
하트 비트는 1 초마다 전송되고 하트 비트는 요청 / 응답 핸드 셰이크에서 수행되며 응답은 장애 감지기에 대한 입력으로 사용됩니다.
장애 감지기는 노드가 다시 도달 할 수 있는지 여부를 감지합니다. 도달 할 수없는 노드를 모니터하는 모든 노드가 다시 도달 가능하다고 감지하면가 s을 전파 한 후 클러스터는 도달 가능한 것으로 간주합니다.

시스템 메시지를 노드에 배달 할 수없는 경우 격리 된 후 다시 연결할 수 없습니다. 너무 많은 승인되지 않은 시스템 메시지 (예 : 감시, 종료, 원격 액터 배포, 원격 부모가 감독하는 행위자의 실패)가있는 경우 이러한 상황이 발생할 수 있습니다. 그런 다음 노드를 아래쪽 또는 제거 된 상태 (아래의 멤버십주기 섹션 참조)로 이동해야하고 액터 시스템을 다시 시작해야 클러스터에 다시 참가할 수 있습니다.

Leader

가십 수렴 후 클러스터의 리더를 결정할 수 있습니다. 리더 선출 프로세스가 없기 때문에 리더는 가십 컨버전스가있을 때마다 항상 임의의 노드에 의해 결정 론적으로 인식 될 수 있습니다. 리더는 단지 역할 일 뿐이며 모든 노드가 리더가 될 수 있으며 컨버전스 라운드간에 변경할 수 있습니다. 리더는 정렬 순서대로 정렬 된 첫 번째 노드로 리더의 기본 멤버 상태가 올라가고 떠나는 리더십 역할을 수행 할 수 있습니다 (멤버 상태에 대한 자세한 내용은 아래의 멤버십주기 섹션 참조).

리더의 역할은 구성원을 클러스터 안팎으로 이동시키고 구성원을 위쪽 상태로 변경하거나 구성원을 제거 된 상태로 종료하는 것입니다. 현재 리더 동작은 가십 컨버전스로 새로운 클러스터 상태를 수신하는 경우에만 트리거됩니다.

리더는 장애 감지기가 도달 할 수없는 것으로 간주되는 노드를 "자동으로"끄도록 구성된 경우 전원을 공급받습니다. 이는 도달 할 수없는 시간이 지나면 도달 할 수없는 노드 상태를 자동으로 종료로 설정하는 것을 의미합니다.

Seed Nodes

시드 노드는 클러스터에 합류하는 새 노드에 대한 컨택 포인트로 구성됩니다. 새 노드가 시작되면 모든 시드 노드에 메시지를 보낸 다음 먼저 응답하는 시드 노드에 조인 명령을 보냅니다.
시드 노드 구성 값은 실행중인 클러스터 자체에 영향을 미치지 않으며 조인 명령을 보낼 접촉 지점을 찾는 데 도움이되므로 클러스터에 가입하는 새 노드에만 관련됩니다. 새 구성원은이 명령을 시드 노드뿐만 아니라 클러스터의 현재 구성원에게 보낼 수 있습니다.

Gossip Protocol

푸시 풀 가십의 변형은 클러스터 주변에서 보내지는 가십 정보의 양을 줄이기 위해 사용됩니다. 푸시 - 풀 가십에서는 실제 버전이 아닌 실제 값을 나타내는 다이제스트가 전송됩니다. 가십의 수령인은 최신 버전이있는 값을 되돌려 보낼 수 있으며 버전이 오래된 버전도 요청할 수 있습니다. Akka는 하나의 공유 상태를 버전 관리 용 벡터 시계와 함께 사용하므로 Akka에서 사용되는 푸시 풀 가십의 변형은이 버전을 사용하여 필요에 따라 실제 상태를 푸시합니다.
주기적으로 기본값은 매 1 초이며, 각 노드는 다른 임의의 노드를 선택하여 가십 라운드를 시작합니다. 노드의 1/2 미만이 표시된 집합에있는 경우 (새 상태를 본 경우) 클러스터는 매초마다 한 번씩 3 번 시도합니다. 이 조정 된 가십 간격은 상태가 변경된 후 초기 보급 단계에서 수렴 프로세스를 가속화하는 방법입니다.
노드의 선택은 무작위이지만 현재 상태 버전을 보지 못했을 수있는 노드쪽으로 치우쳐 있습니다. 가십 교환의 각 라운드 동안 수렴하지 않을 때 보이는 세트의 일부가 아닌 노드에 대해 가십을 만들기 위해 확률이 0.8 (구성 가능)입니다. 즉, 아마도 이전 버전의 상태를가집니다. 그렇지 않으면 임의의 임의의 라이브 노드로 가십.

이 편향된 선택은 주 변경 후 늦게 보급 단계에서 수렴 과정을 가속화하는 방법입니다.
400 노드 이상의 클러스터 (구성 가능하고 경험적 증거에 의해 제안 됨)의 경우, 동시 발생 가십 요청이 너무 많은 단일 스트라 우는 사람을 피하기 위해 확률이 점차 감소합니다. 가십 수신기는 너무 오랫동안 사서함에 대기열에 포함 된 메시지를 삭제하여 너무 많은 동시 메시지로부터 자신을 보호하는 메커니즘도 가지고 있습니다.

클러스터가 수렴 된 상태에있는 동안 고자는 가십 버전을 포함하는 작은 가십 상태 메시지를 선택한 노드로 보냅니다. 클러스터에 변화가 생기 자마자 (비 융합을 의미 함) 편향된 가십으로 다시 돌아갑니다.
상태 또는 가십 상태의 수령인은 험담 버전 (벡터 시계)을 사용하여 다음 사항을 결정할 수 있습니다.

그것은 가십 상태의 새로운 버전을 가지고있다.
그것은 상태의 오래된 버전을 가지고 있으며,이 경우 수령인은 가십 스테이트의 버전을 돌려 보내서 고치퍼에게 현재 상태를 요청합니다 충돌하는 가십 버전이 있습니다.이 경우 서로 다른 버전이 병합되어 다시 전송됩니다.
수령인과 가십이 같은 버전이라면 가십 상태는 전송되거나 요청되지 않습니다.

가십의 주기적 특성은 상태 변경과 같은 훌륭한 일괄 처리 효과를가집니다. 하나의 노드로 여러 노드를 빠르게 결합하면 하나의 상태 변경 만 클러스터의 다른 구성원으로 확산됩니다.
가십 메시지는 protobuf로 직렬화되며 페이로드 크기를 줄이기 위해 gzip으로 처리됩니다.

Membership Lifecycle

노드는 결합 상태에서 시작됩니다. 새로운 노드가 가십 컨버전스 (gossip convergence)를 통해 합류하는 것을 모든 노드가 확인하면 리더는 구성원 상태를 위로 설정합니다.
노드가 안전하고 예상 된 방식으로 클러스터를 떠나는 경우에는 퇴실 상태로 전환됩니다. 리더가 떠나는 상태의 노드에서 컨버전스를 확인하면 리더는 노드를 이탈 상태로 전환합니다. 모든 노드가 종료 상태 (수렴)를 보게되면 리더는 노드를 클러스터에서 제거하여 제거 된 노드로 표시합니다.
노드에 도달 할 수없는 경우 가십 컨버전스가 가능하지 않으므로 리더 동작도 불가능합니다 (예 : 노드가 클러스터의 일부가 될 수 있음). 앞으로 나아갈 수 있으려면 도달 할 수없는 노드의 상태를 변경해야합니다. 그것은 다시 도달 할 수있게되거나 아래로 표시되어야합니다. 노드가 클러스터에 다시 참여하려면 액터 시스템을 재시작해야하며 조인 프로세스를 다시 거쳐야합니다. 클러스터는 리더를 통해 구성된 도달 불가능 시간 이후에 노드를 자동 종료 할 수 있습니다. 도달 할 수없는 노드의 새로운 개체가 클러스터에 다시 참여하려고하면 이전 개체는 아래로 표시되고 수동 화 없이는 새 화신이 클러스터에 다시 참여할 수 있습니다.

노트
자동 실행 기능을 활성화하고 장애 감지 기능이 트리거되면 도달 할 수 없게 된 노드를 종료하기위한 조치를 취하지 않으면 시간이 지남에 따라 많은 단일 노드 클러스터로 끝날 수 있습니다. 이것은 도달 할 수없는 노드가 나머지 클러스터를 도달 할 수없는 것으로 인식하고 자체 리더가되어 고유 한 클러스터를 형성한다는 사실에 있습니다.
앞에서 언급했듯이 노드에 도달 할 수 없다면 가십 수렴이 불가능하므로 모든 리더 활동도 불가능합니다. akka.cluster.allow-weakly-up-members를 활성화하면 컨버전스에 아직 도달하지 않은 상태에서 새 참여 노드를 승격시킬 수 있습니다. 이 조인 노드는 WeaklyUp으로 승격됩니다. 가십 수렴에 도달하면 리더는 약한 회원을 위로 이동시킵니다.
네트워크 파티션의 반대쪽에있는 구성원은 새 구성원의 존재에 대해 알지 못합니다. WeaklyUp 회원은 정족수 결정에 포함시키지 마십시오.
 

State Diagram for the Member States (akka.cluster.allow-weakly-up-members=off)

../_images/member-states.png


State Diagram for the Member States (akka.cluster.allow-weakly-up-members=on)

../_images/member-states-weakly-up.png


예제 

다음 예제를 기반으로 설명 된다.  akka-sample-cluster-app

의존성 

먼저 의존성 라이브러리를 build.sbt 에 추가한다. 

"com.typesafe.akka" %% "akka-cluster" % akkaVersion


클라우드 설정 

akka {
actor {
provider = cluster
}
remote {
log-remote-lifecycle-events = off
netty.tcp {
hostname = "127.0.0.1"
port = 0
}
}

cluster {
seed-nodes = [
"akka.tcp://ClusterSystem@127.0.0.1:2551",
"akka.tcp://ClusterSystem@127.0.0.1:2552"]

auto-down-unreachable-after = 10s

}
}

커스텀 클러스터 프로바이더를 설정하고 , 리모트 섹션에 TCP/IP 상에서 Akka 를 사용할 수 있게 설정한다. 
클러스터 섹션에는 특정 서버의 포트 2551과 2552에 노드가 있다는것을 설정해준다. 

.. 음 클러스터는 너무 내용이 많군요 ..아래 링크를 참고하세요. 
akka in action 이라는 책에서 잘 정리하였습니다.


Comments