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

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

데이터 설계

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

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코드로 제공하면 개발뿐 아니라 성능테스트에도 많은 도움이 된다.

 

Enterprise Batch

 과거에 배치는 단순히 main()함수에 의해서 순차적으로 실행되도록 작성되는 프로그램이었고 그 수도 많지 않았으며 요건도 단순했다.

 하지만 대용량의 데이터, 매일 수백,수천만 건의 데이터 처리작업이 매일 끊임없이 발생하는 엔터프라이즈 환경에서 필수적인 배치작업을 개발/실행/운영하기 위한 아키텍처의 필요성이 대두되고 있다.

 현장에서 업무를 수행하면서 느꼈던 특히 대용량 배치시스템을 구성하기 위해서 어떠한 요소를 살펴야할지 정리해본다.

배치는 꼭 필요한 것인가

 은행업무를 예로 들어본다면 다음과 같다.

 고객이 창구에 방문하여 돈을 입금하면 직원은 돈을 받아서 금고에 넣고 원장에 금액을 기록한다. 이러한 업무는 최대한 빨리 처리해서 고객에게 결과를 주어야 한다. 빠른응답이 생명인 온라인 업무이다.

 영업시간이 종료되면 그날 있었던 거래들을 집계하고, 타 은행과 정산이 필요할 경우 돈을 주고 받기도 한다. 즉시 처리할 필요는 없지만 비지니스를 위해서는 반드시 해야하는 업무이다. 이러한 것이 배치 업무이다.

 가장 이상적인 시스템은 배치가 없이 모두 실시간으로 처리하는 것이다.

 하지만 자원은 한정되어 있으며 해야할 일은 많다. 일의 우선순위를 나눌수 밖에 없다.

배치 어플리케이션 특징

  1. 수행방식

    • 온라인 : 사용자의 요청을 항상 대기하고 있다가 요청이 들어오면 실시간으로 처리하여 결과를 돌려준다 일반적으로 다양한 채널(대외계, UI등)을 통해서 데이터를 입력받고, 해당내용이 Request로 Server에 전달되어 비지니스 처리 후 다시 Response를 통해서 응답하게 된다.
    • 배치 : 사전에 약속된 Resource로부터 데이터를 입력받고, 데이터를 처리하여 결과를 다시 Resource에 반영한다. 대부분이 정해진 일정에 따라서 자동으로 수행한다.
    • 최근에는 수천건 이내의 데이터의 경우 온라인 호출(sync or Async)을 통하여 배치를 구동하는 경우도 있다. 편의상 온라인 배치라고 부른다.
  2. 수행시간 및 자원소모

    • 온라인 : 대부분 1건단위 요청으로 비지니스처리가 이루어지며 요청에서 응답까지 3초이내로 끝나는 것이 일반적이다.
    • 배치 : 수백~수천만건단위 비지니스 처리이며 짧게는 수 분, 길게는 수 시간이 소요된다. 정해진 시간내에 수행이 완료되어야 한다.(후행작업을 위해서)
    • 따라서 배치는 한정된 자원(CPU, Memory등)을 효율적으로 사용해야 하며, 과도한 자원사용으로 시스템이 down되는 것을 방지해야 한다. 그 예로 온라인의 경우 하나의 서비스 메소드 호출시 Connection,Statement등의 자원을 사용하고 즉시 반환하여 다른 호출에 자원을 양보하지만 배치의 경우 최초 점유한 자원을 끝까지 사용하는 것이 효율적이다.
  3. 처리 패턴의 다양성

    • 배치업무의 처리패턴은 다양하다. 또한 많은 기술적요소와 업무적요소가 혼재되어 이를 구분하기 쉽지 않다. 파일전송, EAI연계, DB Load/Unload등 연계요소는 분리하여 공통화하도록 하고 업무적요소는 처리하는 Resource의 유형에 따라 분류하는 등 다양한 처리패턴에 대해서 정리하고 공통화할 필요가 있다.
  4. 논리적 계층

    • Batch Program : 일반적으로 개발자가 작업하는 하나의 단위이다. 모듈이라고 부르기도 한다. 일반적으로 데이터를 읽고 처리하여 다시 저장하는 형태이며 일부 처리결과를 타 시스템에 전달하는 경우도 있다.
    • Batch Job : 비지니스 관점에서 하나의 목표를 달성하기 위해서 구성되는 단위이다. 1개 이상의 Program을 순차적으로, 혹은 조건적으로 실행한다.
    • Batch Job Group : 각 Batch Job들의 실행조건, 선/후행관계, 실행시간 및 연관성 있는 Batch Job의 그룹이다.
    • Batch System : Batch Job Group이 모여서 기업을 서포트하기 위한 하나의 시스템이 구현된다.

 아직까지는 단일 프로그램으로 배치작업을 구성하고, 스케쥴링 대신에 Jenkins나 crontab을 활용하는 곳도 많이 있다. 또한 Stored Procedure를 활용하여 대부분의 로직을 DB에 구성하고 DB Server내에서 모든 작업을 끝내는 경우도 있다. 배치작업의 개수가 수십개정도인 소규모시스템에서는 그러한 방향이 효율적일 수 있다.

 하지만 일정규모이상의 데이터와 프로세스를 다루는 시스템을 구축하기 위해서는 배치 어플리케이션의 특징을 이해하고 이를 위한 아키텍처 구축에 많은 고민이 필요함을 알 수 있다.

 

+ Recent posts