데이터의 유형

데이터를 수집함에 있어서 크게 두 분류로 나눌 수 있다.

Event기반으로 계속 흘러들어오는 데이터와 기존 시스템에 이미 적재되어 있는 데이터.


데이터의 활용

 흔히 말하는 빅데이터 분석은 실시간 데이터를 처리하는 것이 아니라 HDFS상에 적재되어 있는 데이터를 기반으로 Map/Reduce등의 병렬프로그래밍을 통하는 것이었으며 최근에는 실시간 분석에 대한 요구도 높아져서 이를 위한 오픈소스들도 많이 생겨나고 있다.

 기존에는 적재되어 있는 데이터를 기반으로 분석하는 것과 실시간 Event가 분리되어 왔다면

앞으로는 두 종류의 데이터가 하나로 합쳐져서 기존 데이터를 기반으로 모델을 구축한 뒤에, 실시간 데이터들을 모델에 적용하여 예측,분류,Anormaly Detection 등을 수행하게 된다.

 람다아키텍처에 대해서는 별도로 정리하도록 해야겠다.


데이터의 수집방법

 모델구축을 위해서는 대량의 데이터가 반드시 필요하여 이를 위해 대표적인 수집을 위한 오픈소스 툴로 Flume, Sqoop, Gobblin등이 있다. 현재 본인은 File,RDB의 데이터를 수집하기 위해서는 Gobblin을 사용하고, 그 외의 Event기반 데이터는 Flume을 사용하여 수집하고 있으며 메시지 유실, 분산처리 scale out을 위해서 Kafka를 사용하고 있다. 그리고 이러한 작업들을 스케쥴링하기 위해서 Oozie를 사용하고 있다.

 Hadoop Ecosystem에 따른 거의 보편적인 아키텍처라고 볼 수 있겠지만 실제로 사용해보면 많은 어려움이 있다. Cluster구조를 가져간다는 이야기는 결국 네트워크에 의한 멤버쉽 관리가 되어야 하며, 병렬처리를 위해서는 처리량의 분배가 균일하게 이루어져야 한다는 것이다. 테스트를 통해서 적절한 수치를 찾는 것도 쉽지 않은 일이며, 막상 결과가 나왔을때 설명가능한 이유를 찾지 못하는 경우도 있다;;

 그리고 수많은 오픈소스로 이루어져있기 때문에 개별 설정도 어렵고, 서로 연관관계 있는 오픈소스들의 설정이 꼬여있을때는 오류발생의 주 원인이 되며 관리하기도 매우 어렵다.



이미지 출처 : http://7246-presscdn-0-21.pagely.netdna-cdn.com/wp-content/uploads/2015/02/Apache-Hadoop-Ecosystem.jpg


사례참고 

 해당 내용에 대한 아키텍처 공유사례는 많지만 구체적인 수치와 유형별 장단점에 대한 내용은 찾기가 어렵다.

실제로 같은 구성요소를 사용하더라도 그 모습은 요구사항에 따라서 천차만별로 구현된다.

최근 cloudera에 공유된 좋은 사례가 있어서 살펴보았다. 

(http://blog.cloudera.com/blog/2016/03/building-benchmarking-and-tuning-syslog-ingest-architecture-at-vodafone-uk/)


0. Overview

syslog를 수집함에 있어서 다음과 같은 high-level의 아키텍처가 있다.

Flume, Kafka 모두 event기반으로 단위 건당 수바이트의 자료를 처리하기에 적합한 오픈소스이며 내부구조에 대해서는 공식사이트를 참고하는 것이 가장 좋다.



1. 구성요소

Flume

Source-Channel-Sink의 구조로 이루어져있다. 이미 다양한 유형의 데이터에 대해서 Source, Sink등이 구현되어 있어서 쉽게 가져다 사용할 수 있으며, 필요한 부분은 사용자 구미에 맞게 코딩할 수 있다.

해당 사례에서는 syslog source - memory channel - Kafka sink와 Kafka source - memory channel - HDFS sink 를 동시에 사용하고 있다. (Consolidation - https://flume.apache.org/FlumeUserGuide.html)


Kafka

Kafka는 pub/sub구조의 message queue로 볼 수 있는데, 저장소로 Disk공간을 쓰는 것이 특징이다. 따라서 메시지 유실이 되지 않는 것을 최우선으로 하는 시스템에서 사용한다. (그런데 메시지 유실이 되어도 됩니다 라는 시스템은 한번도 본적이 없다.;)


2. 검토요소

성능향상을 위해서는 다음과 같은 요소들을 검토할 필요가 있다.

  • Number of collection tier agents and nodes
  • Number of Kafka sinks per collector tier agent
  • Number of Kafka brokers
  • Number of Kafka topic partitions
  • Kafka broker interconnect network
  • Number of Kafka sources
  • Number of edge tier nodes and Flume Agents per node
  • Number of HDFS sinks
  • Batch-sizes on all of the sinks and sources

사이트에 자세한 내용들이 나와있으니 그냥 간단히 정리해보았다.


* Kafka

- partition의 수는 클러스터상의 디스크수와 최소한 같아야 한다.

- Kafka는 Broker를 통해서 모든 작업을 처리하기 때문에 Broker의 숫자와 메모리를 충분히 확보해주어야 한다. 

- Flume Sink(Kafka Producers)는 일반적으로 Cluster내의 하나의 Partition에 대해서 작업을 하기 때문에 성능을 확보하기 위해서는 충분히 많은 Sink를 갖는게 좋다. 그래야 Kafka Broker가 병렬처리가 원할해 진다.

Birthday problem과 같은 문제로 한 Partition에 2개이상 Sink가 접근할 가능성이 있다! write가 균등하게 되면 좋다.



- Flume Source(Kafka Consumers) : Producer나 Partition에 수에 명확한 관계는 없다. Consumer의 수가 Partition의 수보다 많을 경우 idle상태가 발생한다. Consumer의 수를 Partition보다 작게 하면 모든 Consumer가 일을 하게 된다. 



4개의 Sink가 하나의 Partition을 남겨두고 일을 해서 idle이 발생하고 Kafka Source가 놀고 있는 상황



* Flume - Kafka

Flume과 Kafka를 연계하여 사용할 수 있는 방식은 크게 두 가지가 있다.

1. Kafka Sink를 통해서 기록하고 Kafka Source를 통해서 읽어가는 경우

2. Flume Channel을 Kafka Channel로 사용하는 경우 (Channel의 type은 이외에도 memory, file 등이 있다.)

해당 사례에서는 Kafka channel의 throughput문제와 balanced configuration이 어려운 점을 주요 문제로 생각해서

Kafka Source , Sink방식을 채택했다고 한다. (memory channel의 유실 가능성을 염두하더라도..)



현재 본인은 2번 방식을 사용하고 있었는데. (일단 사용하기가 편하다. 세팅도 간단하고..) 

사용량이 늘어날 것을 감안하면 1번 방식으로 바꿔야 할듯 하다. 

1번도 그렇게 어렵지는 않다. Kafka Source나 Sink는 이미 있다.


3. 결론

Flume-Kafka를 적절하게 사용하기 위해서는 세팅이 필요하다는 내용을 다음과 같이 정리하고 있다.

  • Enough HDFS sinks to handle the output from the Kafka tier
  • A number of Kafka sources fewer than or equal to the number of partitions
  • Sufficient number of partitions that the sources are not the bottleneck, and also that all disks in the Kafka cluster are utilized
  • Enough Kafka sinks such that we have a good probability of not leaving one or more partitions, and hence sources, idle


향후 해야할 일

 빅데이터에 관련된 구성요소들은 거의 대부분 오픈소스이다. 그리고 많은 사람들이 오픈소스는 공짜이며 가져다 쓰기만 하면 된다고 한다. 그럼 빅데이터는 쉽겠네?? 아무나 다하겠네..

반은 맞고 반은 틀리다. 아무나 가져다가 편하게 쓸 수는 있지만...

 OS에 대한 기본적인 이해, Java기반의 어플리케이션 개발 Maven/Gradle기반의 CTIP환경, 요구사항에 맞는 아키텍처 설계 및 오픈소스 선정/커스터마이징 , 추후 버전변경에 따른 릴리즈 관리, 기존 레가시 시스템과의 연계등등 해야할 일도 많고, 기본적으로 소프트웨어관련 일정수준의 지식이 없이는 불가능하다.

(오픈소스를 한번이라도 열어보신분 들은 아시겠지만 정말 깔끔하다. OOP 5대원칙을 이해못하면 예쁘게 커스터마이징하기도 쉽지 않다. 거기다가 데이터분석, 머신러닝 등은 확률,통계,선형대수학 등등 우리를 괴롭혔던 공대수학이 최대의 적으로 등장한다. ㅋㅋ)


항상 공부해야 한다. 끝!



 소프트웨어들의 완성된 모습을 보면 그 소프트웨어를 만든 조직의 모습과 놀랄만큼 닮아있는 것을 보게 된다. 콘웨이법칙이라고 해서 나름 유명한 법칙이다.

 이는 단순히 모듈의 갯수나 레이어등을 말하는 것 뿐만 아니라 Responsibility나 Collaboration 방식까지도 매우 유사하게 된다.


 최근에 많은 기업들이 우수한 소프트웨어를 만들기 위해서 해외의 유명한 전문가들도 모셔오고, 강의도 듣고 BP를 찾아서 적용하기 위해서 노력한다. 그런데 가장 중요한 것은 문화이다.


 Top-Down방식으로 경영전략을 세우고, 조직별로 목표를 수립하고 KPI를 달성하기 위해서 일하면, 그러한 모습의 소프트웨어가 나온다. 정해진 프로세스를 준수했기 때문에 정해진 결과물이 나온다. 때로는 수준에 못 미치더라도 억지로 끌어올린다. 품질지표를 만족하는 결과물이 어떻게든 나온다.

그러나 그 소프트웨어의 수명은 조직의 수명과 동일하기 때문에 몇년뒤면 자연스럽게 사라지고 다시 다른 소프트웨어를 만들기 시작한다. 개발자는 그때 그때 필요한 부품에 불과하다.

이렇게 해서는 절대 좋은 소프트웨어가 만들어질 수 없다.


 하나의 소프트웨어 프로덕트가 어느정도의 안정성과 성능, 기능을 확보하려면 제품마다 다르겠지만 최소한 2년, 넉넉하게는 3~5년정도가 걸린다. 그리고 이러한 성장가능한 구조, 아키텍처를 세우는 것은 무엇보다도 중요하다.

 가장 피해야 할 시나리오는 다음과 같다. 최초 A사이트를 타겟으로 v 1.0 을 만들었다. 이후 B사이트가 새로 생겼다. 그런데 새로운 요건을 만족시키기 위해서는 v 1.0 로는 안되기 때문에 v 2.0을 만든다. 물론 v 1.0과는 호환이 안된다. C사이트가 새로 생겼다. 다시 v 3.0을 만든다. 버전별 유지보수는 시간이 흐를수록 불가능이 된다..


 그렇다고 좋은 아키텍처를 잡기위해서 초반에 마냥 시간을 보낼 수도 없다. 우리가 선정한 기술이 목표와 부합하는지 검증도 해야하고, MVP모델도 개발해야한다. 실제 적용도 빨리 해봐야 더 많은 요구사항을 뽑아낼 수 있다. 이러한 과정을 진행하기 위해서 우리는 시간이 매우 부족하기 때문에 애자일을 선호하게 된다.


 많은 사람들이 착각하는 것이 애자일을 하나의 방법론으로 이해하고, 과거해왔던 방식처럼 무언가를 자꾸 적용하고 표준 프로세스와 산출물을 만들려고 한다.

착각하면 안된다. 애자일의 핵심은 좋은 코드를 빠르게 만들어 내는 것에 중점을 두고, 이를 방해하는 것들을 없애는 것이다. 필요한 것을 넣는 것이 아니라 필요없는 것을 빼는 것이다. 꼭 필요한 것만 남기는 것이다.

애자일을 설명할 때 나오는 수많은 기법들이 있다.

이건 그냥  "우리가 이렇게 해봤더니 도움이 되더라.."  일뿐이다. 참고자료이지 정답은 아니다.

애자일 선언과 그 배경원칙들에 대해서 수십번 읽어보시고 곱씹어보시기를 추천드린다.


 기존에 개발팀이 개발하던 방식을 존중하고, 그들의 문화를 관찰해야 한다. 개발자 한명 한명의 성향까지도 고려해야 한다. 어느조직에나 딱 맞는 방법론이란 존재하지 않는다. 자신들만이 가지고 있는 방법을 더욱더 간결하게 다듬어서 맞춰가는 것이 애자일이다.


 실질적으로 이렇게 일하는 문화가 자리잡히면 자연스럽게 Bottom-Up으로 할 일들이 도출된다. 내가 이렇게 만들었더니 이러한 단점이 있더라. 이걸 어떻게 보완하면 좋을까? 서로 의견을 나누어서 더 나은방향으로 개선시킨다. 

 자신의 설계를 공유하고, 코드를 공유하며 Review한다. 자연스럽게 소프트웨어의 품질을 올라갈 수 밖에 없다.

 남들에게 뒤쳐지지 않기 위해서 스스로 학습하고 새로운 것을 항상 찾아본다. 냅두면 알아서 공부하고 자기가 만든 분신과도 같은 소프트웨어를 더욱 발전시키기 위해서 노력한다. 자기주도 학습이다.(self-self-self!!!)

다른사람들과 개발순서를 맞춰야 하기 때문에 자연스럽게 일정이 조정되고, 그 일정은 매우 타이트하다.

 스스로 세운 일정을 준수하는 것은 본인과의 약속이기 때문에 누가 시키지 않더라도 야근을 한다. 그리고 만족할만한 성과가 나온 날은 기분좋게 일찍 퇴근한다. 

다른 사람들은 속일 수 있을지 몰라도 나 자신은 속일 수 없다.

 개발자의 역량이 발전하고 다시 소프트웨어는 새로운 기능으로 무장한다.(개발자에게 있어서 소스는 분신과 같은 존재이다.)


왜 조직은 개인을 믿지 못하고 자꾸 관리하려 드는가? 이에 대해서는 각자 반성해볼 필요도 있다.

그동안 개인은 어떻게 일해왔길래 조직이 신뢰할 수 없는 것일까...


좋은 소프트웨어는 관리를 통해서 만들어질 수 없다.

좋은 아키텍처는 좋은 조직과 문화에서 만들어진다.


조직과 문화는 사람이 만들고 구성원은 계속 변화한다.

'Software Architecture' 카테고리의 다른 글

Apache NiFi In Depth #2 (Copy on write)  (0) 2017.11.02
Data 수집 아키텍처  (0) 2016.03.13
Communication_Offerings  (0) 2015.03.25
Go Reactive Systems  (0) 2015.03.25
scale out 이 가능한 architecture? micro service?  (0) 2015.03.25


현장에서 ThreadPool을 사용할 때 가장 많이 사용하는 것이 Spring에서 내장하고 있는 클래스들이다.

그런데 이 클래스들을 뜯어서 보니 Java에서 기본으로 제공하는 interface나 class와는 구조나 모임의 단위가 조금 달라보인다. google을 아무리 찾아봐도 만족할 만한 답이 없어서 시간이 나는동안 소스를 열어봤다.

가장 많이 사용하는 클래스들을 뽑아서 diagram을 그려봤다.

왼쪽에 Spring, 오른쪽이  Java이다.


1. Java

Java의 Concurrent 패키지에서는 순수하게 기능에 집중해서 작성한 것으로 보인다.

쉽게 가져가서 사용할 수 있는 구조를 위해서 많이 노력한 것으로 보이며 ISP의 원칙을 잘 지킨 것 같다.


a. Executor : Runnable 구동이 가능하며 execute 메소드를 사용한다.

b. ExecutorService : Executor를 상속받았다. Callable 구동이 가능하며 추가적으로 submit 메소드를 제공한다.

ThreadPool의 lifecycle에 관련된 메소드도 보인다.

c. ThreadPoolExecutor : 실제 개발자가 ThreadPool 사용을 위해서는 ThreadPoolExecutor를 생성해서 사용하며,

이를 좀 더 쉽게 사용할 수 있도록 Util성클래스인 Executors 를 제공한다.

d. ScheduledExecutorService : Schedule작업을 위한 인터페이스로 schedule 메소드가 정의되어 있다.



2. Spring

Spring의 경우에는 좀더 사용자의 측면에 접근해서 설계가 되어있는 모습이다.

내부구현은 Java에서 제공하는 class들을 멤버변수로 가지고 있어서 대부분 처리를 진행하고,

사용자가 좀더 편리하게 사용할 수 있도록 다양한 설정포인트를 제공한다.

Thread작업에 task라는 개념을 도입하여 재구성한 형태로 그 출발은 TaskExecutor이다.


a. TaskExecutor : java의 Executor와 완전히 동일하다. Spring에서의 확장을 위해서 만들었다.

b. SyncTaskExecutor : Runnable의 run메소드를 호출만 한다.

c. AsyncTaskExecutor : Runnable과 Callable의 구동이 가능하며, execute 메소드와 submit 메소드를 제공한다.

d. TaskScheduler : Schedule작업을 위한 인터페이스로 scheduler 메소드가 정의되어 있다.


이러한 각 인터페이스를 용도에 맞게 구현하여 아래의 클래스 형태들로 제공하고 사용자는 자신의 목적에 맞도록 선택하여 사용한다.


또한 Spring에서는 Future의 확장을 위해서 ListenableFuture를 별도로 정의하여 사용하고 있다.

이부분은 다음에 시간날때 보도록 해야겠다...



1. 조물주가 이 땅에 특별한 목적을 가지고 생명체를 창조해내었다면, 

프로그래머 역시 어떠한 목적이 있기 때문에 한 객체를 시스템내에서 창조한다.

창조된 생명체는 자신의 역할을 다할 책임이 있다.


<모델링>

Object oriented programming, 이른바 OOP라 불리우는 개념의 기본이다.

흔히 모델링을 접하게 되면 현실세계를 컴퓨터속으로 투영시키는 작업이 모델링이라는 말을 듣게 된다.

RDB모델링에서는 Entity를 도출하고 각 Entity간의 Relation을 정의하는 것이 시작이 된다.

어떠한 정보를 저장하는 가에 중점을 두고 작업을 진행하는 것이 DB모델링이라면

하나의 Object가 어떻게 동작하는가에 중점을 두고 작업을 진행하는 것이 Application모델링.

그중에서도 OOP에 해당한다.


<Responsibility>

 Object는 속성과 행위를 갖게 되며 각각 변수와 메소드라는 형태로 표현이 된다. 개발자는 이 object를 통해서 본인이 의도한 바를 구현하고자 한다. 본인이 하고 싶은 일을 대신 시킨다고 봐도 무방하다.

하나의 object로 모든 일을 처리할 것인지, 여러개의 object로 나누어서 처리할 것인지, 나눈다면 몇개로 어떻게 나눌것인지는 만드는 사람의 몫이다. 해당 시스템이 궁극적으로 이루고자 하는 목적과 범위가 무엇인지를 명확히 파악하고 그에 맞게 적절하게 구성하는 것이다.

 하나의 object로 모든 일을 처리하는 방식을 흔히 God object라고 부르며 이는 대표적인 anti-pattern의 하나이다. 모든 변경사항에 영향을 받기 때문에 항상 변경될 수밖에 없다.

이는 유지보수성을 심각히 저하시켜서 결국 재개발을 할 수 밖에 없다.

 하나의 변경사항에 대한 수정의 범위는 한곳 이 되는 것이 바람직하며(coupling), 유사한 기능에 대해서도 한곳에 모여있는 것이 좋다. (cohesion)




IT시스템의 구현은 현실세계와 밀접한 관련이 있다고 생각합니다.

짧지않은 기간동안 공부하고 경험한바를 바탕으로 마구 써내려가봅니다.


=========================================================================================

1. 조물주가 이 땅에 특별한 목적을 가지고 생명체를 창조해내었다면, 

프로그래머 역시 어떠한 목적이 있기 때문에 한 객체를 시스템내에서 창조한다.

창조된 생명체는 자신의 역할을 다할 책임이 있다.


2. 어떠한 생명체도 혼자서 모든 것을 수행하지는 못한다.

자신이 할 수 있는 것은 자신이 하고, 그 역할을 벗어나는 것은 전달하여 요청한다.

그리고 의사소통이 가능한 존재들끼리만 요청을 주고 결과를 받을 수 있다.


3. 자연세계에서 한 객체가 다른객체에게 간접적으로 영향을 받을지언정, 직접적으로 영향을 받는 경우는 거의 없다.

소프트웨어에서 역시 가장 이상적인 객체라 함은, 다른 객체에 의해서 영향을 받는 것이 최소화되며 자신의 창조목적을 다하는 것이 기본으로 본다. 가끔 특수한 경우가 있을 수는 있지만 빈번하게 발생한다면 이는 자연스럽지 못하다.


4. 생태계에서 어떤 객체가 자신의 life cycle을 최대화 시키기 위해서는 변화에 잘 적응해야만 한다.

변하는 부분과 변하지 않는 부분을 구분하고, 변하는 부분에 있어서는 최대한의 유연성을 발휘한다.

그러나 변하지 않는 부분에 대해서는 견고함을 최우선으로 삼는다.

최초에 설계된 유연성을 넘어서는 경우에는 변화를 수용하지 못하고 파괴의 순간을 맞이하는 것이 공통적인 부분이다. 이 세상에 영원한 것은 없다.


5. System을 우리는 계 라고 표현한다.

하나의 계는 여러가지 공통의 속성을 공유한다. 우리의 환경을 예로 들자면 비슷한 온도, 습도, 토양, 공기, 일조 를 공유하는 곳이다. 계 안에서는 여러 생물이 각자 평안함을 유지하면서 살게된다.

그러나 그 안의 공유하는 균형이 깨지는 순간 심각한 이상현상을 초래한다.

거꾸로 계 내에서 살던 생명체가 다른 계 로 이동하는 순간 동일한 행위를 보장하지는 못한다.

소프트웨어에서는 이러한 경계안 쪽을 시스템 안정성,표준선을 보장하는 최소의 단위로 본다.(boundary)

계는 계의 집합으로 구성된다. 각 생명체는 하나의 계를 유지하며, 여러 생명체가 모여서 생태계를 구성하며, 다양한 생태계가 모여서 지구를 구성하고 있다.


6. 어떠한 객체이던지 점진적으로 발전한다.

태어날때부터 모든 기능이 완벽한 생물은 없다. 성장하면서 주위의 변화를 습득하면서 점차 부분부분의 기능을 강화해나간다. 때로는 필요에 따라서 기능을 퇴화시키기도 하고, 특정기능을 발전시키기도 한다.

중요한 것은 이러한 점진적 발전을 위해서는 기능의 규모에는 관계없이 반드시 최소Set은 가지고 있어야 한다는 점이다. 기본적으로 머리,몸통,팔,다리는 있어야지, 팔만 있어서는 발전의 가능성조차 없다.


7. 연관성이 없는 객체는 없는 존재의 의미가 없으며, 비슷한 연관성을 가진 객체는 서로 라이벌이다.

직접적이던 간접적이던 객체들은 서로 연관성을 가지고 있다.

다른 객체와 연관성이 전혀 없이 홀로 있는 객체라면 그것은 이미 객체가 아니다. 사라진다.

이와는 반대로 서로 비슷한 연관성을 가진 객체가 있다면 이 객체들은 서로 라이벌이다.

어느 한순간이 되면 하나의 객체만 남게될 것이다.


=========================================================================================


이렇게 정리하다보면 각 객체를 특별하게 구분할 수 있는 요소는 결국 관계성으로 보입니다.

객체가 가지고 있는 하나하나의 기능에 집중해서 보다보면 큰 그림을 놓치게 되고요,

객체들이 살고있는 환경만 바라보게 되면 작은 그림을 놓치게 됩니다.


그래서 저는 시스템을 구축하거나 분석/설계 해야하는 업무를 수행할 때 아래와 같은 순서로 접근합니다.

1. 이 시스템의 목적은 무엇인가? 어디까지가 시스템의 범위인가?

2. 그 목적을 이루기 위해서 구성되고 있는, 또는 구성되어야 하는 컴포넌트는 무엇인가? 최소필요기능은 무엇인가?

3. 컴포넌트들이 보인다면 서로 관계는 어떻게 맺어야 하는가? 

4. 유사한 관계 혹은 충돌되는 관계는 없는가?

5. 컴포넌트안에는 구체적으로 어떤 객체들이 만들어져야 하는가? 얼마나 많이 만들어져야 하는가?

6. 이제는 보다 상세하게 각 객체들의 책임을 상세하게 정의해보자.


영화Matrix를 보면 아키텍트가 곧 창조주이죠.

이러한 모든 요소를 고려하여 각 객체들이 오래~ 행복하게~ 살수 있는 하나의 계를 구축해주는 것이 목표아니겠습니까. 만들어는졌으나 아무것도 하는일이 없는 객체, 혼자서 모든 일을 도맡아 하는 객체는 얼마나 힘들까요.


신처럼 처음부터 끝까지를 모두 완벽히 해낼 수 있다면 가장 이상적이겠지만 현실은 불가능입니다..



akka를 보던 중 at most once 전달이기 때문에 메시지의 유실이 발생할 수 있다는 내용이 보인다.

(http://doc.akka.io/docs/akka/snapshot/general/message-delivery-reliability.html)


그렇다면 akka를 못 쓰는 것인가? 보완하도록 메커니즘을 구성해야 되겠네....

생각난김에 메시지전송 패턴에 대해서 간략히 정리를 해본다. 


  • at-most-once delivery means that for each message handed to the mechanism, that message is delivered zero or one times; in more casual terms it means that messages may be lost.
  • at-least-once delivery means that for each message handed to the mechanism potentially multiple attempts are made at delivering it, such that at least one succeeds; again, in more casual terms this means that messages may be duplicated but not lost.
  • exactly-once delivery means that for each message handed to the mechanism exactly one delivery is made to the recipient; the message can neither be lost nor duplicated.


1. At least once

 실패가 일어나더라도 메시지의 유실이 발생해서는 안되고 복구에 너무 오랜시간이 걸려도 안된다.

메시지는 최소한 한번 이상 전달되어야 한다

<context>

메시지의 전달을 확실히 보장하는 것이 최우선이며, 중복이 발생해도 무방하다.

<solution>

각 메시지를 수신했을 때 ack응답을 되돌려주도록 한다. 만약에 ack를 정해진 시간내에 못 받을경우 다시 보낸다.


2. At most once

 메시지는 많아도 한번 전달된다.

 <context>

 중복없이 빠르게 처리하는 것이 목표이다. 유실되어도 critical하지 않은 경우

 <solution>

 전송에 관련된 상태등을 기억하지 않는다. fire-and-forget


3. Exactly one

 메시지는 정확하게 한 번만 전달되어야 한다. 금융권이나 기타 트랜잭션을 반드시 보장해야하는 경우다. 중복x!

 <context>

 분산처리 환경에서 매우 중요한 요건으로 메시지 유실이 발생해서도 안되고, 중복이 발생해도 안된다.

 <solution>

 메시지를 생성할 때 unique message identifier를 붙인다. 이 identifier를 이용해서 송신자와 수신자간에서 발생한 중복메시지를 filter처리한다.


http://www.cloudcomputingpatterns.org/

+ Recent posts