big query(빅쿼리)에서 멱등성을 위한 전략
멱등성이란 DW에서 데이터를 적재 할때 자주 사용 합니다.
DW에서 이따금씩 재처리를 하는 경우 기존의 잘못된 데이터를 지우고 재적재 해야 합니다. 그렇지 않으면 데이터의 중복이 발생하여 데이터가 이상하게 증가하거나 결과값이 이상하게 나올 수 있습니다.
그런데 big query에서 제가 겪은 상황에서 멱등성을 고려 하여 프로세스를 구성하였다가 큰 낭패를 본적이 있습니다. 상황은 다음과 같습니다.
bucket에 JSON 형태로 쌓이는 데이터가 있습니다. 데이터는 YYYY/MM/DD 형태로 쌓이고 있습니다. 그런데 데이터를 적재할때 2020/02/26 폴더의 데이터에 서버에서 조금씩 지연되서 들어오는 경우 2020-02-27의 데이터가 들어오는 경우가 있습니다. (한개의 파일에 다른 날짜의 데이터가 들어옴) |
위와 같은 상황일 경우 멱등성을 고려하였을때 일반적인 로그가 찍힌 시간으로 멱등성을 고려하여, DELETE하고 INSERT 할 경우 일부 데이터가 지워지지 않습니다. 2020-02-26일의 날짜로 DELETE를 하였기 때문에 INSERT 할때 쌓였던 2020-02-27일의 지연되어 들어온 데이터는 지워지지 않고 그대로 남아 있습니다. 이 경우 재처리를 여러번 할 경우 계속해서 데이터가 중복 됩니다.
위와 같이 데이터가 손실되는 구간이 발생 합니다. 이를 방지하기 위해서는 새로운 날짜 컬럼이 필요합니다. 새로운 날짜 컬럼을 통해서 위의 나온 파일의 적재 시간을 기준으로 데이터를 만들어서 다음과 같이 로그를 적재합니다.
timeMs의 경우 로그적재 시간입니다. 이 시간으로 할 경우 우와 같이 데이터의 손실이 발생 합니다. 그래서 TDDate라는 날짜 컬럼을 프로세스에서 처리 할때 적재된 시간을 기준으로 적재하여 DELETE 할때 TDDate를 기준으로 지우면 깔끔하게 지워집니다.
하지만 여기서도 한가지 문제가 있습니다. 바로 파티션입니다. 보통 데이터를 사용하는 사용자의 경우 제가 만든 TDDate를 사용하지 않고 timeMs(로그 적재시간)을 사용합니다. 그럴 경우 당연히 파티션은 timeMs에 걸어야 합니다. 그런데 TDDate를 기준으로 DELETE를 할 경우 big query에서 용량이 너무 많이 증가됩니다. (사용량)
이를 방지 하기 위해서 다음과 같이 Query를 만들어서 사용하여 사용량을 크게 줄일 수 있습니다.
위와 아래의 쿼리의 사용량을 확실하게 보실 수 있습니다. 위와 같이 timeMs로 범위를 조금 넓게 가져온 뒤에 TDDate로 검색해서 DELETE를 할 경우 휠씬 작은 사용으로 멱등성을 보장 할 수 있습니다.
감사합니다.