Page History
AKKA의 라우팅은 액터에서 발생하는 메시지를 다양한 장치를 이용하여 분배적략을 분배처리 전략을 세울수 있습니다.
로컬에서는 로컬에만 사용시에는 동시성/병렬성 문제를 해결할수 있으며 클러스터내에서도 동일하게 작동하기 때문에클라우드 분산컴퓨팅 환경에서도 동일한 컨셉으로 이벤트처리 분배 전략을 세울수 있는것이 장점입니다병렬처리에 대한 도메인 문제를 해결할때 이용할수 있으며
클러스터내에서 이용이된다고 하면 분산처리에 대한 문제를 해결할때 사용할수 있습니다.
Info |
---|
분배와 배분은 글자 순서만 바꾸어놓았을 뿐이데 경제학 기준 다른의미를 가지고 있습니다. 일반적으로 배분은 자원을 투입하는 경제활동의 앞 부분에서 일어나고, 분배는 생산의 결과물이 나온 뒤에 소득을 나누는 과정을 의미합니다.
IT산업군에서는 router 은 데이터 전송시 최적 경로를 선택하는장치를 의미하며 경제용어와 비교하면 자원(트래픽 또는 작업)을 나누는 것이기 때문에 배분기라고 표현하는것이 의미상 가까우나 분배기란 용어를 일반적으로 더 많이 사용합니다.
여기서는 분배란 단어를 채택해 AKKA가 제공하는 유용한 라우팅에 알아보겠습니다. |
라우터와 관련된 용어 정리
- 라우팅 : 분배로직분배를 결정하는 로직
- 라우터 : 분배지점 , 분배기분배가 발생하는 지점으로 라우팅에의해 경로또는 작업자가 결정됩니다.
- 라우티 : 분배된 작업이 도달하는 최종위치 또는 작업자
테스트 시나리오
- 작업 노드는 5개를 지정 여러 라우팅을 테스테스트
- 분배기에 50개의 작업 이벤트를 한꺼번에 발생시킴
- 작업노드중 특정 1노드는 항상 300ms 지연을 시킨다.
- 동일작성된 코드를 라우터만 변경하여 수행
...
SmallestMailbox
메시지가 덜 쌓인(큐 가용성이 높은) 라우티에 우선적으로 메시지를 보냅니다.
BalancingRouting
MailBox와 유사하게 작동하지만, 바쁜 라우트에서 유휴 라우트로 작업을 재분배하려고 덜바쁜 유휴 라우티로 작업 분배하려고 시도하는 라우터.
액터 코드
Code Block |
---|
@Override public Receive createReceive() { return receiveBuilder() .match( WorkMessage.class, message -> { String pathName = self().path().name(); messageCount++; log.info("[{}] ChildActor InMessage : {} - {}", pathName, message, messageCount); // Routee가 a일때 임의 지연 if(pathName.equals("$a")){ log.info("SomeBlocking - 300ms"); Thread.sleep(300); } _probe.tell("completed", ActorRef.noSender()); }) .build(); } |
- 라우티의 이름은 a/b/c/d/e 이며 a의 라우티에 임의 300ms 지연처리
- round robbing 순차분배 기준 각 라우티는 10개의 작업을 분배받습니다.분배받일수 있습니다. ( a의 경우 300 * 10 지연이 필연발생 )
라우팅 정의
Code Block |
---|
akka.actor.deployment { /router1 { router = round-robin-pool nr-of-instances = 5 } /router2 { router = random-pool nr-of-instances = 5 } /router3 { router = balancing-pool nr-of-instances = 5 pool-dispatcher { attempt-teamwork = off } } /router4 { router = balancing-pool nr-of-instances = 5 pool-dispatcher { executor = "thread-pool-executor" # allocateThread exactlyPool을 5 threads for this pool지정할수도 있습니다. thread-pool-executor { core-pool-size-min = 5 core-pool-size-max = 5 } } } /router5 { router = smallest-mailbox-pool nr-of-instances = 5 }} |
...
라우터 생성코드
Code Block |
---|
ActorRef router = actorSystem.actorOf(FromConfig.getInstance() .props(WorkerActor.Props(probe.getRef())), routerName); @Test public void RoundRobinRoutingTest(){ RouterByNameTest("router1"); } @Test public void RandomRoutingTest(){ RouterByNameTest("router2"); } @Test public void BalancingRoutingTest(){ RouterByNameTest("router3"); } |
라우팅을 코드로 정의할수 있지만 설정화로 완전하게 분리할수있습니다. 라우팅 생성은 정의된
테스트 결과
...
해당 테스트 시나리오에서 아래와 같은 테스트 결과가 나왔으며~ BalancingRouting 이 전체 처리가 동일제약 조건으로, BalancingRouting 의 전체 처리완료시간이 가장 빨랐습니다.
라우팅 | 총완료시간 | Note |
---|---|---|
RoundRobin | 3초 294ms | 총완료시간은 제일늦은 라우티와 동일합니다. ( 10 * 300ms) |
Random | 2초 942ms | 랜덤이기때문에 늦거나 빠를수도 있습니다. 늦은 라우티에 작업량이 운좋게 할당이 안된경우 라운드 로빈보다 빠르게 작동합니다. |
SmallestMailBox | 3초 272ms | 메시지큐가 덜 쌓인 쪽에 작업량을 할당하지만 RobundRobin과 유사하게 작동되었습니다. 이벤트가 한꺼번에 시도되었기때문에 지금과같은 테스트 시나리오에서 성능적 이점이 없습니다. 지속 운영중 쌓인 메시지큐에 차이가 발생했을때 조금씩 벌어지는경우 메시지 우선순위 역전기능이 함께이용되어 이점을 볼수 있습니다. |
BalancingRouting | 490ms | 느린 라우티를 자동검출하여 라우티에서 1개의 Task만 수행되었으며 작업 분배 되었으며~ 결과적으로 가장 빠르게 작동되었습니다. 쌓인 개수가 아닌 라우티내 메시지처리 지연상황(메시지 밀림)을 고려 처리 지연발생된 라우티에게 메시지를 보내지 않으려고 균형을 맞추는것으로 보입니다. |
...
라우티에 분배우선순위를 낮춰 균형을 맞춥니다. | ||
라우티에 연결된 Worker에서 블락킹 IO가 존재하고 순차완료 보장이 필요하지만 완료시간이 일정하지 않을때 제한된 풀에서 동시처리 능력을 올려야할 활용가능합니다.
- 블락킹이 발생한 a에게 작업을 안준다기보다~ 가급적 덜 바쁜 유휴(idle) 라우티에게 이벤트를 분배 시도하는 컨셉입니다.
Info |
---|
"측정 할 수 없다면 관리할 수 없다" - 피터 드러커 유닛테스트에서 모듈단위 성능테스트를 측정하는것은 복잡한 도메인일수록 필요하지만 복잡하다는 이유로 포기하게 됩니다. 시스템의 성능 테스트에서도 마찬가지로 측정되지 않으면 개선할수 없으며 모니터링툴과 같이 측정을 할수 있는 유틸리티가 중요합니다. 다음 영상은 성능테스트가 왜 어렵고 어떠한 전략을 가져야할지에 대해 참고할수 있는 참고영상이며 다양한 언어및 플랫폼에서 Bench라는 모듈을 이용해 유닛테스트 단계에서 활용할수 있습니다. 링크 : https:// |
...
샘플코드및 이론참고
위에서 소개된 라우터 외에 다음과 같은 특수 종류의 라우터도 제공됩니다.
Broadcast
선택장치가 없으며 전체 라우티에게 전송
TailChopping
작업처리가 제일늦은 라우티를 잠시 쉬게해서 휴식이 끝나면 다시 합류를 시킵니다.
ScatterGatherFirstCompleted
모두에게 작업을 전달하고 응답이 가장 빠른 하나의 값을 선택합니다.
ConsistentHashing
이벤트속성에 해싱을 추가함으로 동일 키인경우 일정노드를 선택함과 동시에 자동 분배처리하는 전략으로
동일한 키를 처리하는 작업자(노드)가 계속 바뀌는것이아닌 유지가 되는것이 성능에 유리할때 이용될수 있습니다.
스케일아웃이 되는 작업어플리케이션이라 할지라도 성능이 가장 빠른 로컬캐시전략(Inmemory)을 이용할수 있습니다.psmon/java-labs/tree/master/springweb/src/test/java/com/webnori/springweb/akka/router