비투엔 기술기고

대량 데이터 동기화 방법 _ 신동민 책임

알 수 없는 사용자 2016. 3. 7. 15:02




대부분의 시스템은 다양한 목적으로 데이터 동기화를 필요로 합니다. 데이터 이행, DB서버간 테이블을 복제 하거나, 외부 시스템의 데이터 연계 목적 등이 대표적인 경우라고 할 수 있습니다. 데이터 동기화는 그 목적과 시스템 구성, 요구 사항에 따라 다양한 방식을 이용할 수 있으며, 이를 위한 전문 솔루션(CDC, EAI )을 이용하기도 합니다.


이번 글에서는 비교적 간단한 방법 중 하나로 솔루션을 이용하지 않고 Source 시스템의 테이블 Full 데이터를 수신하여, Target 시스템의 테이블에 효과적으로 반영하는 방안을 소개합니다.



 

Full 데이터 동기화 필요한가?

이해를 돕기 위해 도로명주소 시스템(http://www.juso.go.kr)’에서 제공하는 건물정보 DB를 구축하는 예를 들어보겠습니다 ‘도로명주소 시스템은 타 시스템의 주소DB 구축을 지원하기 위해 아래와 같이 ①전체주소(매월말일기준)와 ②일변동자료를 제공하고 있습니다





도로명 주소 DB를 구축하고자 하는 시스템은 (실시간 동기화 요건이 아니라면) 특정 기준일자의 ①전체주소를 다운받아 DB를 구축하고, 이후부터는 매일 일변동자료만 다운받아 반영하도록 하는 것이 일반적입니다.


위 사례는 아주 심플한 경우이며 비슷한 방식으로 서버간 데이터를 연동하는 사례는 주변에서 어렵지 않게 찾을 수 있습니다. 그러나, 변경 자료를 수신해 처리하는 이 방식은 아래사항을 고려하지 않는다면 곧 Source 시스템과 데이터가 불일치하는 경험을 하게 될 것입니다

    1. 원본 테이블에 물리적인 삭제(Delete)가 발생하고, 변동 자료에 삭제(Delete)된 데이터를 표시하여 제공하지 않는 경우

    2. 소스 시스템ㅁ에서 변동자료 추출 시 변동 레코드가 누락된 경우

    3. 타겟 시스템에서 변동자료 중 일부 처리를 누락한 경우

    4. 데이터 변동 순서와 처리순서가 바뀐 경우

    5. 기타...

이를 해결하기 위한 차선책으로 간편하게 사용하는 방법 중 하나는 정기적으로 Full 데이터를 수신하여 반영하는 것입니다. 예를 들어, 평소에는 도로명 주소 일변동자료를 매일 반영하고, 매월 말일에는 전체주소 데이터를 반영하도록 하는 것입니다. 근본적인 해결책은 아니지만 허용 가능한 오차범위 내에서 정기적으로라도 불일치를 보정하는 방법입니다.


데이터 중요도에 따라 항상 전체 데이터를 수신하여 처리하기도 합니다. 소스 시스템의 부하, 네트워크 부하가 크지 않고 제공되는 변동 데이터만 추출하기 어려운 환경이라면 적용해 볼 수 있을 것입니다. 그 밖에도 기타 여러 이유로 재작업이 필요한 경우가 드물지 않게 발생하곤 합니다.



 

Full 데이터 동기화 방법

어떤 이유에서건 테이블 Full 데이터를 수신하여 주기적으로 동기화해야 한다면, 처리 방법과 성능을 고민해봐야 합니다. 소량의 데이터라면 크게 고민하지 않아도 무방하겠지만, 전체 데이터가 수백~수천만 건 이상의 대량 데이터라면 반드시 고려해봐야 할 문제입니다.


, 대량 데이터 처리를 위한 작업시간 확보가 가능한 여건인가도 고려해야 합니다. 업무 요건이 온라인 처리가 반드시 필요한 환경이라면 Truncate & Insert 방식이나 CTAS(Create Table As Select) & Rename과 같은 방법은 적절하지 않을 것입니다.

 

방법 1

온라인 처리가 필요하고, 소스 테이블에 삭제(Delete) 레코드도 있다면 간편하게 아래 <쿼리1>처럼 사용하기 쉽습니다. <쿼리1>은 데이터 처리에는 문제가 없으나, 대량 데이터 처리 성능은 기대하기 어렵습니다. 참고로, [건물_수신] 테이블은 전체 데이터 파일을 다운받아 그대로 업로드 해놓은 임시 테이블이고, [건물] 테이블이 반영하고자 하는 Target 테이블입니다.



SQL> DELETE FROM 건물;


10641493행이 삭제되었습니다.


경 과: 00:06:34.47


SQL> INSERT INTO 건물 SELCET * FROM 건물_수신;


10647977개의 행이 만들어졌습니다.


경 과: 00:07:15.67


<쿼리1>



방법 2

트랜잭션이 없는 작업시간을 확보할 수 있다면, 미리 만들어 놓은 테이블과 이름을 교체하는 <쿼리2> 방식도 많이 사용됩니다. 하지만, DDL 작업은 관리목적의 DBA 작업 방식으로는 적합하지만 정기적으로 수행하는 배치(Batch) 프로그램에는 적합하지 않은 방법입니다.



CREATE TABLE 건물_NEW AS SELECT * FROM 건물_수신;


ALTER TABLE 건물     RENAME TO 건물_OLD;
ALTER TABLE 건물_NEW RENAME TO 건물;


<쿼리2>



방법 3

다음에 소개할 방식은 온라인 처리가 필요하고, 전체 데이터 건수는 많지만 변경 데이터 건수는 소량인 경우에 적용해볼 수 있는 방법입니다.


앞서 얘기한 도로명 주소 시스템을 다시 예로 들어보겠습니다. <1>은 최근 6개월간 매월말일 기준으로 제공되는 전체주소(건물정보) 건수 입니다. 최초 DB구축을 제외하면 운영 중 전체주소 파일을 다운받아 처리하는 작업이 필요할 때, 실제 변동이 발생한 데이터는 얼마나 될까요? 아마 실제 변경이 필요한 데이터는 아주 소량에 불과할 것입니다


기준일자

 데이터건수

2015.12.31

10,655,346

2015.11.30

10,647,977

2015.10.31

10,641,493

2015.09.30

10,636,992

2015.08.31

10,631,562

2015.07.31

10,626,228

<표1>



아래 <쿼리3>는 이점에 착안하여 전체주소 데이터를 보다 효율적으로 반영하는 SQL입니다.


<쿼리3>


<쿼리3>MERGE문의 USING절 내에서 큰 테이블 2(건물, 건물_수신)를 읽고 조인해야 하는 부담이 있지만, <쿼리1>의 전체 데이터를 지우고 다시 입력하는 DML (Delete, Insert) 부하보다는 훨씬 부담이 적습니다. , CPUMemory가 충분하다면 Direct Path Read, 병렬처리, 해시조인 기법을 활용하여 USING 절의 부하는 크게 감소시킬 수 있습니다.


이 방식은 USING절의 Full Outer Join을 통해 실제 데이터 변경이 필요한 레코드만 추출하여 DML 작업을 실행하는 것이 핵심입니다. 다시 말해, 변경되지도 않는 99% 데이터를 지우고 다시 입력하는 무겁고 불필요한 작업을 없애는 것입니다.

 



마무리

이상으로 몇 가지 데이터 처리 방법을 살펴 보았습니다. 글의 시작에서 언급한 바와 같이 데이터 동기화는 여러 목적과 다양한 방법으로 사용되고 있습니다. 그 만큼 복잡한 요건과 다양한 해법이 존재하고, 성능 및 결과물의 품질도 차이가 나기 마련입니다. 글을 읽는 분들의 상황과 여건에 따라 효과적인 방법을 적용하는데 조금이나마 도움이 되기를 바랍니다.