데이터의 유형

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

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

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/

 최근 몇 년전만 해도 응답시간 수초, 수십개의 서버, 기가단위의 데이터로 시스템이 구성되었지만 오늘날에는 모바일, 수천대의 클라우드 기반환경으로 변화하면 millisecond단위의 응답시간, 페타바이트 데이터 등의 요건으로 인해서 과거의 소프트웨어 아키텍처로는 이를 수용하기가 어려운 상태이다.

 결국 우리는 Responsive, Resilient, Elastic and Message Driven 한 시스템을 원하고 이것을  Reactive Systems이라고 부른다. ( 보다 유연하고 scalabe하면서 장애도 방지하는 그런 시스템)

Reactive Systems are:

Responsive: The system responds in a timely manner if at all possible. Responsiveness is the cornerstone of usability and utility, but more than that, responsiveness means that problems may be detected quickly and dealt with effectively. Responsive systems focus on providing rapid and consistent response times, establishing reliable upper bounds so they deliver a consistent quality of service. This consistent behaviour in turn simplifies error handling, builds end user confidence, and encourages further interaction.

Resilient: The system stays responsive in the face of failure. This applies not only to highly-available, mission critical systems — any system that is not resilient will be unresponsive after a failure. Resilience is achieved by replication, containment, isolation and delegation. Failures are contained within each component, isolating components from each other and thereby ensuring that parts of the system can fail and recover without compromising the system as a whole. Recovery of each component is delegated to another (external) component and high-availability is ensured by replication where necessary. The client of a component is not burdened with handling its failures.

Elastic: The system stays responsive under varying workload. Reactive Systems can react to changes in the input rate by increasing or decreasing the resources allocated to service these inputs. This implies designs that have no contention points or central bottlenecks, resulting in the ability to shard or replicate components and distribute inputs among them. Reactive Systems support predictive, as well as Reactive, scaling algorithms by providing relevant live performance measures. They achieve elasticity in a cost-effective way on commodity hardware and software platforms.

Message Driven: Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation, location transparency, and provides the means to delegate errors as messages. Employing explicit message-passing enables load management, elasticity, and flow control by shaping and monitoring the message queues in the system and applying back-pressure when necessary. Location transparent messaging as a means of communication makes it possible for the management of failure to work with the same constructs and semantics across a cluster or within a single host. Non-blocking communication allows recipients to only consume resources while active, leading to less system overhead.

Large systems are composed of smaller ones and therefore depend on the Reactive properties of their constituents. This means that Reactive Systems apply design principles so these properties apply at all levels of scale, making them composable. The largest systems in the world rely upon architectures based on these properties and serve the needs of billions of people daily. It is time to apply these design principles consciously from the start instead of rediscovering them each time.

참고)http://www.reactivemanifesto.org/

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

슬라이드쉐어에서도 공유가 되고 있으니 참고할 수 있다.

http://www.slideshare.net/mircodotta/go-reactive-eventdriven-scalable-resilient-responsive-systems?qid=bc7cfcab-8c5b-4d37-a122-11590578803f&v=qf1&b=&from_search=11

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

 디스크, 메모리, 서버등의 자원은 갈수록 저렴해지고 일반적이 되어가고 있으며 동시사용자는 기하급수적으로 늘어났다.

과거 중요한 서비스는 반드시 죽지 않아야 하고 고정되어 requset/response를 보장한다는 개념에서,

이제는 수백,수천개를 띄워놓고 사용자 수에 따라서 서비스량을 조정하면서도 약간의 문제는 상관하지 않고 돌아간다는 개념으로 변화하고 있다.

 

 

패러다임 변화에 따라서 어플리케이션도 변경이 되어야 한다는 내용.

이러한 내용을 반영하여 나온 것이 reactive programming으로 현재 typesafe에서 주도하고 있다.

akka,scala를 통해서 이를 구현하고 있으며 많은 IT서비스기업에서 사용하고 있다.

과거에는 WAS기반으로 앞단에 load balancer를 두는 아키텍처가 일반적이었다. 현재도 일반적이다.

이러한 구조는 일단 확장이 어렵다. WAS를 추가하거나 서버를 추가할때 들어가야 할 설정들도 많고, 배포정책도 정해져야 한다. 기동/재기동에 따라서 묶이는 서비스의 단위(도메인)가 커서 영향범위도 넓다고 생각한다.

이를 보완하기 위해서 따라서 scale out이 쉽게 가능한 micro service 아키텍처가 많이 거론되고 있다.

뒷받침되어야 할 것들에 대해서 생각해보았다.

 

1. 외부로부터 데이터 입력/출력을 담당하는 부분

 데이터 사용량에 따라서 쉽게 scale out이 가능해야 한다. 이는 별도의 설정없이 slave node의 추가만으로 사용이 가능해야 한다. zookeeper나 hadoop의 구조를 생각하면 될 것 같다.

=> 4번과도 연관성이 있으며 다양한 형태의 서비스(ex, spring/storm/spark)와 효과적으로 연결되기 위한 grid bus형태가 필요하지 않을까 고민된다.

 

2. 실제 비니지스를 담당하는 어플리케이션의 모듈화

 각 어플리케이션을 설계할때 참조관계를 깊이 고려해야 한다. 이는 배포의 단위와 직결되며, 커지면 커질수록 단위 서비스를 위해 필요한 작업들이 증가하게 된다. application design에서는 cohension과 coupling으로 예전부터 강조되어왔던 개념이며 refactoring, restructuring을 통해서 초기단계뿐만 아니라 개발/운영단계가 진행될 때에도 계속 병행되어야 한다.

=> 이 부분은 framework개발을 할때부터 고민해왔던 부분인데(온라인/배치/센터컷을 어떻게 자연스럽게 연결할 것인지.. @.@), 앞으로도 계속 봐야할 것 같다.

 변하는 부분과 변하지 않는 부분에 대한 식별이 잘 이루어져야 한다. 무한하게 유연한 설계는 있을 수가 없다. 있다한들 엄청 복잡해지면서 아무도 사용하지 않게된다.. ㅜㅜ

 

3. immutable state

2번과 연관되는 내용이다. 어플리케이션 인스턴스가 일을 할때에는 순수히 메시지에 의존해서 일을 하도록 해야한다. state를 가지게 되는 순간 다양한 메시지에 대해서 어떻게 반응해야 하는지 고려가 되어야 하며(과거 java멤버변수들..), 설계복잡도가 급격히 증가하게 된다.

=> reactive programming를 보다가 과거에 나왔던 actor model에 대해서도 자연스럽게 접하게 되었고 akka도 보고 있다..  scala를 공부하면서 느끼는 내용은 함수형+객체형 언어스타일대로 구현하다보니 이게 자연스럽게 이루어진다. scala에서는 val을 최대한 사용할 것을 권장하고 있다. ^^;

 

4. 실시간 대용량 데이터 처리

 이미 hadoop기반의 배치성 빅데이터 분석은 어느정도 정착이 된 상태이고, storm이나 spark streaming을 통한 실시간 데이터분석도 많이 활용되고 있다. scale out과 연관되어서 약간은 다른 부분을 생각해보고 싶은 것은 분석대상이 될 데이터에 수집/처리에 대한 부분이다. 역시 1번과 연관성이 있지만 5번과 연관성이 더 깊다고 본다. 저장소에 대한 고민도 필요한 것 같다. 쉽게 쌓고, 쉽게 접근할 수 있어야 한다.

=>수집/처리/분석에 대한 Storage를 하나의 아키텍처로 가는것은 부담이 있기 때문에 NoSQL, HDFS, RDB의 적절한 조합이 필요하다고 생각한다. 수집부분에서는 NoSQL로 무조건 쌓아두고, ACID가 보장되어야 하는 데이터들에서는 RDB처리한다. 수집과 처리가 끝난부분에 대해서 선택적으로 HDFS로 옮겨서 분석을 수행한다.(사실 Spark가 너무 좋아져서 이부분이 점점 의미가 없어지기는 한다..;)

 

5. 클라우드 기반

 하나의 서버를 추가하는 것이 손쉽게 이루어져야 한다. 서버자원이 많이 남아돌아서 이를 충분히 활용하기 위해서 가상화기술이 발달해왔다면 앞으로는 어플리케이션 레벨에서의 가상화를 위해서 발전될 것으로 예상한다.

=> docker 기술이 또 주목받고 있다. 하나의 서비스를 이미지화하여 서비스사용량이 증가하면 쉽게 대응할 수도 있고, 어플리케이션 변경이나 버전업이 생길경우에도 이미지를 새로 생성하여 배포하도록 한다. OS가 포함되지 않아서 이미지크기도 부담이 없다.

 

 그 외에도 데이터가 올라와야 하는 Device나 Web, Open API들의 표준화, 다양한 서비스를 효과적으로 연계하기 위한 메시지 포멧/프로토콜 등 고민해야 할 부분이 많다. 하지만 시도해볼 가치는 있다고 생각한다.

 이와 같은 아키텍처를 통하면??

메뉴에서 각 버튼이 하는 액션을 하나의 서비스로 정의하여 구현 => 사용자가 많이 클릭하는 서비스는 인스턴스를 많이 띄우면 된다!

 

앞으로의 목표는 다양한 사업에서 적용될 수 있는 클라우드 기반 아키텍처가 포함된 플랫폼을 만들어서 사용자(비니지스 개발자)에게 쉽게 제공하는 것!

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

 소프트웨어는 역시 코드로 말해야 한다. 워낙 다양한 오픈소스가 있어서 받아보고, 돌려보고, 읽어보고 해야하는 내용도 많고 이들을 엮어서 사용하는 것도 쉽지 않다. 또한 중요한 것은 해당 프로젝트의 개념과 목적을 명확히 이해해야 한다.

1)용도에 맞지 않게 사용하거나,

2)비슷한 개념을 가진 오픈소스를 섞어쓰거나

3)비슷한 목적이지만 구현방법이 다른 오픈소스를 같이 쓰게 되면 두고두고 고생한다.

 

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

Communication_Offerings  (0) 2015.03.25
Go Reactive Systems  (0) 2015.03.25
빅데이터 분석에서 배치활용  (0) 2014.10.21
배치 어플리케이션 개발시 고려사항  (0) 2014.04.20
Batch Architecture 고려사항  (0) 2014.03.31

빅데이터 분석에서 배치활용

최근 다양한 분야에서 빅데이터 분석이 활용되고 있다. 일반적으로 빅데이터 플랫폼을 구현하기 위해서는 수집->정제->분석->결과전이->Visualization등의 단계가 필요하다고 볼 수 있다.

이 중 수집단계에서는 수집주기에 따라서 RealTime/배치성/NearRealTime으로 나누며, 유형에 따라서는 정형/비정형으로 나눌 수 있다. 

기존 배치작업의 경우 정기적 정형데이터 (ex, RDBMS or File등)의 수집에서 활용될 수 있다.

다만 몇가지 차이점을 고려해야 한다.


배치작업으로 빅데이터 수집 시 고려해야 할 점

범용성

여러 노드에 위치한 다양한 Legacy DB로부터 데이터를 수집해야 하기 때문에 범용성이 있어야 한다. SQL은 되도록 ANSI SQL을 준수하고 DBMS자체의 함수사용을 자제한다. 처리속도의 향상을 위해서 프로시저는 제한적으로 사용이 가능하지만 추후 유지보수나 비지니스 변경을 적시에 반영하기 위해서는 신중한 검토가 필요하다.

원격서버에 대한 실행제어

데이터 수집의 속도향상을 위해서는 분산환경을 이용해야 하며, 데이터 유형에 따라서 이미지수집,로그수집 등 다양한 프로세스가 존재할 수 있다. 이를 한곳에서 모니터링하고 제어할 수 있는 환경이 필요하다.

사용성

분석자는 개발을 모른다는 전제하에 수집기능이 제공되어야 한다. 분석작업을 위해서 데이터를 수집할 때 단순한 쿼리수행과 옵션만으로 기능을 사용할 수 있어야 한다. UI기반으로 수집모델을 만들어 낼 수 있다면 더욱 좋다.

경량성

일반적으로 빅데이터 분석시 사용하는 Hadoop은 여러노드에서 분산처리된다. 수집작업을 같은 노드에서 수행할 경우 서버자원에 경합이 발생하여 성능저하를 야기할 수 있다. HDFS적재의 편리성 때문에 Hadoop 노드에서도 수집작업이 이루어짐을 감안한다면 최소한의 패키징과 라이브러리로 자원소모량을 줄일 필요가 있다.

데이터 매핑

빅데이터 분석을 위해서 수집되는 데이터는 과거 업무프로세스에 의해서 정의된 배치작업과는 다르게 수시로 Input/Output Layout이나 쿼리문이 변경되어야 한다. 이를 위해서 쉽게 데이터 매핑을 지원해야 한다.


ps)파일을 읽어야 하는 수집작업이지만 배치성이 아니라 Near-Real Time의 수집처리가 있을 수 있다. (ex, System Log, Daemon Process)

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

Go Reactive Systems  (0) 2015.03.25
scale out 이 가능한 architecture? micro service?  (0) 2015.03.25
배치 어플리케이션 개발시 고려사항  (0) 2014.04.20
Batch Architecture 고려사항  (0) 2014.03.31
Enterprise Batch  (0) 2014.03.31

배치 어플리케이션 개발시 고려사항

배치 아키텍처가 준비되었다면 실제 배치 어플리케이션을 설계/개발해야 한다. 이를 위해서 고려해야될 사항을 살펴본다.

데이터 설계

배치에서는 대용량의 데이터를 다루기 때문에 이부분에 대한 고민이 많이 필요하다.

Resource유형

File

기본적으로 배치는 데이터를 순차적으로 처리하기 때문에 File처리가 DB처리보다 속도에 장점이 있다. 또한 다른 시스템으로 처리결과를 전달하기 위해서는 일반적으로 파일전송을 많이 사용한다. File을 생성하거나 참조할때에는 Charset에 주의해야 한다. 또한 File Input/Output 레이아웃 정의시 한글이 포함된 컬럼의 경우 byte length가 달라지는 것을 감안해야 하며 숫자컬럼을 표현할 때에는 부호,소수점에 따라서 교정이 필요할 수 있다.

  • Fixed Length : 레코드의 각 컬럼이 고정길이로 구성되어 있다. length로 각 컬럼을 구분한다. (ex, SAM파일)
  • Variable Length : 레코드의 각 컬럼이 가변길이로 구성되어 있다. Column Separator로 각 컬럼을 구분한다. (ex, CSV파일)

DB

DB의 경우 Connection을 얻고 PreparedStatement를 생성하여 쿼리를 날리는 작업이 필요하기 때문에 상대적으로 느릴 수 있으나 배치작업을 통해서 생성된 데이터가 다른 곳에서 많이 참조가 될 경우에는 데이터 Access에 이점이 있다. 또한 File 처리에 비해서 개발방법이 쉽고, 변경이 발생해도 빠르게 반영할 수 있다.

CHAR vs VARCHAR

과거 COBOL을 사용했던 시스템에서는 가변형이라는 데이터 타입이 존재하지 않았기 때문에 CHAR타입이 아직도 많이 남아있다. 고정길이 데이터에는 CHAR타입을 사용하는 것이 원칙이지만 데이터 타입은 언제 어떻게 변경될지 모르기 때문에 차세대 이후부터는 CHAR타입보다는 VARCHAR타입을 사용하는 것을 권장한다. 예로 CHAR형으로 데이터가 선언되어 있을 경우 남는 공간에 공백문자가 들어가게 되는데 이는 저장공간에 낭비가 발생할 뿐만 아니라 값비교를 위해서 trim등의 스트링 연산이 추가되어야 한다. 대용량 데이터를 처리해야하는 경우 이에 대한 비용도 무시할 수 없다. 운영시 용이성과 개발시 용이성을 볼 때 VARCHAR로 통일하는 것을 추천한다.

INDEX 재설계

INDEX는 데이터 Access를 빠르게 할 수 있으나, 데이터 추가/삭제/수정이 빈번하게 발생할 경우 속도저하를 발생시킨다. 온라인에서 사용하는 테이블과 최대한 겹치지 않도록 배치 테이블을 설계하는 것이 바람직하며 부득이하게 같은 테이블을 사용할 경우 적절하게 INDEX를 제어하도록 한다. (테이블당 3~4개 권고) 또한 SELECT를 사용할때 테이블 대부분의 자료를 읽어야 하는 경우에는 Full Scan하는 것이 더 빠를 수 있다. 그리고 배치작업에서 대용량 데이터를 적재할 경우에는 DROP INDEX를 하고 데이터 적재를 마친 뒤 INDEX재생성을 하는 것이 일반적으로 속도에 이점이 있다.

파티션 테이블 활용

데이터 저장공간에 파티션 개념을 도입하여, 테이블의 특정컬럼을 기준으로 하여 분리된 파티션에 데이터를 저장할 수 있도록 하는것이다. 데이터 로드, INDEX생성, 백업 및 복구등을 파티션 레벨에서 수행할 수 있으며 수행시간을 단축시킬 수 있다.특히 주기단위로 대용량 데이터를 관리하는데 매우 유용하며 쿼리를 파티션 테이블에서 수행할 경우 분할된 파티션들 중 일부에만 접근하기 때문에 성능이 향상된다. 병렬 프로그래밍과 같이 사용할 경우 효과를 극대화할 수 있다.

비지니스 로직 구성

비지니스 로직구성이 배치 어플리케이션의 핵심이다. 전체적으로 업무 프로세스를 재설계하는지가 관건이다.

업무 프로세스 재설계

기존 업무의 분석과 재설계를 통해 비지니스 로직자체를 단순화 한다. 유사한 업무를 통합하고, 불필요한 반복작업을 제거해야 한다. DBMS의 신규기능(ex, sum, over)을 활용할 수 있으며, 어플리케이션을 효율적으로 작성해야 한다. 반복문내의 불필요한 연산을 제거하고 I/O를 최소화해야 한다.

Application 효율화

loop 문내 불필요 로직 최소화

  • Loop내에서 DB건당 Read는 최소화 하는 것이 좋다. JOIN쿼리를 활용하여 처음에 다수의 필요한 테이블 자료를 조회하면 DB Read횟수를 줄일 수 있다. 
  • 변경 전
    • while(DB.ReadA()){ 비지니스로직처리 DB.ReadB(); } 
    • DB.READ.A=> SELECT * FROM A
    • DB.READ.B=> SELECT * FROM B WHERE NAME=?
  • 변경 후
    • while(DB.ReadC()){ 비지니스로직처리 } 
    • DB.READ.C=> SELECT * FROM A,B WHERE A.NAME=B.NAME
  • Loop내에서 DB건당 Write는 최소화 하는 것이 좋다. 로직처리 후 데이터를 모아서 처리하는 것을 권장한다. 또한 Java의 경우 JDBC addBatch기능을 활용하면 2~10배정도 속도향상이 있다. 
  • 변경 전
    • void a(){ 비지니스 로직 } void b(){ DBWrite();} 
    • while(DBRead()){ a(); b(); } 
  • 변경 후
    • while(DBRead()){ a(); }
    • while(DBRead(a의결과){ b(); }
  • 불필요한 객체생성이나 연산을 제거한다. 대표적으로 String연산을 loop내에서 반복할 경우 메모리 사용량 및 처리속도에 악영향을 줄 수 있다. MultiThread일 경우 StringBuffer를, SingleThread일 경우 StringBuilder를 사용하는 것이 일반적이다. 그 외에도 loop내에서 객체하나로 값만 바꿔서 사용할 수 있는 경우는 new를 loop문 밖으로 빼는 것이 필수이다.

단순 코드성 정보 Memory 활용

자주 참조되는 데이터(ex, 코드성 데이터, 영업일등)는 Memory이 Loading후 로직에서 활용하면 매번 DB Read를 하는 것보다 속도향상의 효과가 있다. 단, Loading되는 데이터의 사이즈를 감안해야 한다.

병렬처리를 감안한 파라미터 설계

  • Multi Process
  • Multi Thread

 

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

Go Reactive Systems  (0) 2015.03.25
scale out 이 가능한 architecture? micro service?  (0) 2015.03.25
빅데이터 분석에서 배치활용  (0) 2014.10.21
Batch Architecture 고려사항  (0) 2014.03.31
Enterprise Batch  (0) 2014.03.31

Batch Architecture 고려사항

아래 언급되는 내용들은 배치뿐 아니라 일반적인 Enterprise Application Architecture에서 공통적으로 해당되는 내용이다.

Language

 최근 금융권 시스템에도 Java가 많이 도입되면서 배치에서도 Java를 사용하는 경우가 늘어나고 있다. 하지만 Java의 경우 가상머신(VM)을 통해서 수행되기 때문에 C나 COBOL에 비해서 속도에 약점을 보일 수 있어서 배치에는 적합하지 않다는 인식도 많이 있다.

 실제로 프로젝트에서 가장 많이 나오는 불만이 "로직 변경없이 똑같이 작성하면 기존보다 느리다"는 것이다. 하지만 장점도 있다. 일반적으로 온라인과 동일한 Language를 사용하기 때문에 아키텍처 통일성이 확보되고 프로그램 재사용이 가능하다. 또한 다양한 Opensource의 활용이 용이하고 멀티쓰레드 처리에 쉽게 접근할 수 있다.

따라서 다양한 관점의 분석과 이해당사자들의 협의를 통하여 Language선택이 이루어져야 한다. 실제로 프로젝트를 수행할 때 성능 최적화에 가장 큰 요소는 Language가 아니라 업무에 관련된 부분이다.

불필요한 작업단계를 제거하거나 통합하고, CriticalPath작업의 위치를 조정하고 작업간 선/후행관계를 재조정하는 등 업무의 최적화에서 더 큰 효과를 볼 수 있다.

Resource Management

현재 시스템에서 수행되어야 할 작업의 상세한 내용을 5w1h원칙으로 정확하게 파악해야 한다.

  • who : 작업명은 무엇인가? 작업의 주체는 누구인가?
  • when : 언제 수행되는가? 일단위인가? 월단위인가?
  • what : 무엇을 수행하는 작업인가? File처리인가? 그렇다면 어느파일에 접근하는가? DB처리인가? 그렇다면 어느 테이블에 접근하는가?
  • why : 작업의 목적은 무엇인가? 어떤한 작업의 선행인가? 후행인가?
  • where : 어느서버에서 수행되는가? 어느계정으로 수행되는가?
  • how : 스케쥴링에 의해서 수행되는가? 원격호출로 수행되는가?

    또한 배치 시스템의 특성상 많은 데이터가 생성되고 참조되는데 이에 대한 관리도 필요하다. 예를 들면 다음과 같다.

  • 파일명명규칙 : 생성되는 파일에 대해서 명명규칙이 필요하다. 업무구분/보관주기/생성모듈등 정보관리가 필요하다. 특히 장기간 불필요파일들이 남아있을 경우 저장공간 부족을 야기시킬수 있기때문에 보관주기에 따라 주기적으로 정리하는 것이 좋다.
  • 테이블레이아웃 : 배치에서 LOAD/UNLOAD작업을 하기 위한 테이블 정보도 관리 되어야 한다.
  • FTP목록 : 작업결과를 FTP로 전송할 경우가 있다. 이 때 사용되는 서버/계정정보/권한 등도 관리 되어야 한다.

    이외에도 실제로 현장에서는 정보 관리주체가 각각 다르다 보니 한눈에 영향도를 파악하기 어려운 경우가 많이 있다.

Capacity

 총 작업의 개수, 각 작업이 소모하는 자원, 작업의 처리대상/주기, Peak Time등을 알고 있어야 한다. 예를 들어서 평상시에는 정상적으로 동작하던 작업이 특정요일만 되면 지연현상이 발생하는 경우가 있다. 상황을 분석해보니 특정요일 같은시간대에 수행되는 다른작업이 같은 처리대상에 접근하고 있어서 Table Lock발생하는 경우였다. 또 월초/월말에 처리해야하는 데이터의 양이 큰 폭으로 증가하여 작업시간이 지연되거나 시스템에 부하를 발생하는 경우도 있을 수 있다. RuleEngine을 사용하는 배치작업의 경우 메모리를 많이 소모하여 동시에 다수의 작업이 수행될 경우 자원부족현상이 발생할 수도 있다.

 이러한 상황을 예방하기 위해서 작업Dependency Diagram작성, 배치작업관리 메타시스템 구축등을 통해서 작업 패턴을 사전에 분석하는 등의 노력이 필요하다.

Deployment & FailOver

 시스템 장애가 발생하여 부득이하게 다른 서버를 사용할 경우를 대비하여 사전에 준비가 되어 있어야 한다. 예를 들어서 배치프로그램은 물론이고 배치프로그램들이 생성하는 File들도 동일한 버전으로 배포가 되어 있어야 하며 스케쥴러와 같은 기타 솔루션들도 유지가 되어야 한다. 또한 설정정보들 역시 신속하게 변경/적용할 수 있어야 한다. 최근에는 파일공유 솔루션이나 NAS를 통해서 어플리케이션 및 파일을 공유하여 사용하고 있다.

개발표준

 전체 개발표준 뿐만 아니라 대표적인 케이스를 선정하여 유형별 Sample코드를 제공하는 것도 하나의 방법이 될 수 있다. 배치의 경우 예를 들면 입력되는 데이터에 따라서 후행배치를 분기시키는 데몬배치도 있고 Resource를 읽어서 처리하는 비지니스 배치도 있다. 비지니스 배치도 처리하는 Resource유형에 따라서 File to File, DB to File등이 존재할텐데 이에 따른 처리패턴을 확보하여 Sample코드로 제공하면 개발뿐 아니라 성능테스트에도 많은 도움이 된다.

 

+ Recent posts