꾸준함이 중요한 Lion2me의 기술블로그

신뢰 할 수 있는 데이터 시스템을 구축하는 방법

23 Feb 2024
DE

Data Reliability

IBM에서는 데이터 신뢰성을 “데이터 신뢰성은 데이터가 시간이 흘러도 여러 소스에 걸쳐 일관성을 유지하고 오류가 없는지 여부에 관한 신뢰도를 측정하는 척도로서 데이터의 완전성과 정확성을 의미합니다.” 라고 말했습니다. 다른 신뢰성을 나타내는 문장보다 IBM의 문장이 가장 잘 정의되었다고 생각하기에 이 문장을 기반으로 신뢰성을 설명하겠습니다.

Why we ensure Data Reliability?

데이터를 활용하는 서비스는 “의사결정”과 “서비스 제공”이 있습니다. 주로 서비스 제공에는 AI 서비스가 포함됩니다.

이러한 서비스를 제공 할 때 데이터 신뢰성은 비즈니스에 직접적인 영향을 줄 수 있습니다. 예를들면 마케팅을 수행 할 때 특정 광고 캠페인의 ROAS를 얼마나 빠르고 정확하게 예측 할 수 있는가는 광고 전략에 관련한 의사결정을 도와 줄 수 있고, ROAS가 낮은 광고는 빠르게 종료 함으로써 불필요한 지출을 줄일 수 있습니다.

실제로 대규모로 광고 플랫폼을 사용하는 서비스의 경우 이러한 지출을 줄이는 것으로 수 십억 단위의 지출을 줄일 수 있습니다.

그런데 만약 이 광고 캠페인의 ROAS를 잘못 예측하면 어떻게 될까요?

특정 광고 캠페인으로 하루에 100만원의 광고 비용을 지출할 때 실제 ROAS가 0.6으로 저조한 성적을 내고 있음에도 데이터의 오류로 인해 10일 후 ROAS를 예측하였을 때 1.2의 준수한 성적을 내고 있다면, 데이터에 이상이 있음을 알아채기까지 60일이 걸렸을 때 이미 사용 된 1000만원 이후에도 광고 캠페인을 60일간 지속하여 6000만원의 지출이 추가 지불됩니다.

이 경우 해당 캠페인 말고도 다른 캠페인도 ROAS가 제대로 예측되지 않았기 때문에 큰 지출이 발생 할 수 있습니다. 정확한 의사결정은 회사의 매출에 큰 영향을 끼치고, 그렇기에 데이터 신뢰성은 매우 높은 우선순위를 얻습니다.

How to ensure Data Reliability?

데이터 신뢰성은 “데이터의 완전성과 정확성”을 말하고 전제 조건은 “시간이 흘러도 여러 소스에 걸친 일관성 유지”, “오류의 여부” 입니다.

이 전제 조건들을 기반으로 알아보겠습니다.

“시간이 흘러도 여러 소스에 걸친 일관성을 유지”하는 데이터

시간이 흘러도 여러 소스에 걸쳐 일관성을 유지하는 것의 의미에 대한 저의 생각은 “명확한 목적을 가진 데이터를 참조하는 경우”와 “지나치게 국소적인 혹은 필요 이상의 광범위한 처리를 하는가” 라고 생각합니다.

명확한 목적을 가진 데이터를 참조하는 경우

“명확한 목적을 가진 데이터 처리”는 현재 데이터 거버넌스를 유지하는 업무를 진행하면서 주의하는 부분 중 하나입니다. 하지만 이 경우 참조하는 것을 경계해야 합니다.

ETL을 하는 과정에서 우리는 리포트를 위한 Adhoc 업무를 수행하는 등 특정 목적을 위한 테이블을 만드는 과정에서 참조 할 수 있는 테이블을 raw 데이터에서 일부 추출하여 만들고 있습니다. 하지만 이 과정에서 “목적”이 명확한 테이블이 만들어지게 되는데, 문제는 이 테이블이 원하는 목적과 다른 테이블에 참조되는 경우입니다.

이 경우 다른 목적을 위한 테이블이기에, 기존의 목적을 위한 테이블의 기준에 따라 다른 조건이 추가 될 수 있습니다. 그러면 당장에는 추가되는 테이블의 조건에 부합하더라도 변환이 발생 했을 때도 부합 할 지 알 수 없습니다.

이러한 문제가 명확한 목적을 가진 데이터를 참조하여 시간이 흐르면서 일관성이 깨지는 경우가 아닐까 생각합니다.

그러면 우리의 액션 아이템으로는 “명확한 목적을 가진 데이터를 참조하지 않는 것”으로 이 문제를 해결 할 수 있습니다.

지나치게 국소적인 처리를 한 데이터

여기서 국소적인 처리가 의미하는 것은 하드코딩에 관련한 내용입니다.

우리는 쿼리를 짤 때 조건을 거는 경우 대체로 하드코딩을 사용합니다. 이 부분은 데이터베이스 특징에 따라 빠른 쿼리를 보장하고 검색을 용이하게 하지만, 문제는 변환이 자주 발생하는 정보에 대한 하드코딩은 조심 할 필요가 있습니다.

예를 들면, 결제 데이터를 저장하고 결제에 사용 된 카드에 따라 서비스를 제공하고 싶을 경우 대부분의 경우 “extra_service”라는 컬럼에 “10295”와 같은 ID 값을 저장하고 card 테이블에 “kb_card_XX”의 ID를 가진 “extra_service” 컬럼에 “10295”값을 가진 레코드를 생성합니다.

하지만 이렇게 만들어진 데이터는 어떨까요?

“extra_service” 테이블에 card 컬럼이 추가되고 “kb_card_XX”라는 특정 카드 1개가 포함되고 “10295”라는 추가 서비스 데이터의 ID를 사용하지 않는다면, 우리는 **매 추가 서비스를 제공하는 카드를 추가/삭제/변환 할 때마다 조건을 수정해야 합니다”

SELECT cb.userid, cb.id, es.id
FROM card_table cb
LEFT JOIN extra_service es
ON cb.userid = es.userid
WHERE es.id = '10295'

위 쿼리는 10295라는 서비스를 제공 할 카드와 유저 정보를 얻어 올 수 있습니다. 10295라는 서비스를 받을 유저라면 모두 얻어 낼 수 있죠. 하지만

SELECT userid, card
FROM extra_service
WHERE card = 'kb_card_XX' or card = 'kb_card_XY' or card = 'kb_card_XZ';

위 쿼리는 3개의 카드가 모두 같은 서비스를 제공받는다고 생각하면, 새로운 카드가 생길때마다 계속해서 조건을 추가해야 합니다. 이러한 처리를 한 경우가 지나치게 국소적인 처리로 인해 시간에 따라 여러 소스에 걸쳐 일관성이 유지되지 않는 경우가 아닐까 생각합니다.

그러면 우리는 “조건의 카디널리티를 좁혀서 문제를 해결 할 수 있습니다.”

지나치게 광범위한 처리

명확한 목적을 가진 테이블을 파생시킬 때 일관성이 깨지는 경우를 봤습니다만, 반대로 너무 광범위한 처리를 할 경우에도 신뢰도가 쌓이지 않을 수 있습니다. 이 경우에는 사용 목적의 증가로 인해 발생합니다. 예를들면 다음의 쿼리로 데이터를 수집 할 수 있습니다.

SELECT userid, sum(pay_amount)
FROM payment
GROUP BY userid

대부분의 경우 이 테이블이 원하는 목적인 유저의 결제 금액의 합계를 구하는 쿼리가 정답이 될 수 있습니다. 하지만 “환불”데이터가 추가적으로 포함되면 이 테이블은 정답이 될 수 있을까요?

물론 “실제 결제 금액”이라는 정보를 얻는 것은 정답이 될 수 있습니다. 하지만 결제와 환불에 대해서 별도로 데이터를 얻어야 하는 경우라면 말이 달라집니다. 이 경우에는 payment_type이 필요합니다.

SELECT userid, sum(pay_amount)
FROM payment
WHERE payment_type = 'pay'
GROUP BY userid

이러한 경우가 “지나치게 광범위한 처리로 인해 시간에 따라 여러 소스에 걸쳐 일관성이 유지되지 않는 경우”라고 생각합니다.

이 문제는 “명확한 목적을 가진 처리를 통해 문제를 해결 할 수 있습니다.”

“오류의 여부를 판단하여 일관성을 유지”하는 데이터

여기서 “오류”라는 단어를 조금 더 광범위하게 말해서 “원하는 결과를 얻는지의 여부”로 확장하겠습니다. 오류라는 단어는 휴먼 에러보다 시스템 상의 오류에 가까운 단어로 생각되고, 가용성에 가까운 의미를 가지고 있기 때문입니다.

이 부분은 Data Observability에 큰 관련성이 있다고 생각합니다. 데이터 파이프라인을 작성하는 단계에서 우리는 “데이터가 잘 입력 되었는지”를 아는 것이 상당히 어렵다는 점을 알고 있습니다. 이전 회사에서는 데이터가 잘 입력되었다는 것을 단순한 Count로 검증하기도 했었고, 사실 가장 구현 및 비교 효율이 좋은 방법이기도 했습니다. 하지만 raw 데이터를 다루는 것 외에 여러 파이프라인을 거치면서 더 세부적인 관찰이 필요합니다.

OLAP 방식으로 동작하는 데이터 플랫폼을 사용하면 자주 겪는 “컬럼 순서”에 따른 문제는 이러한 오류를 자주 일으키기도 합니다. 실제로 Redshift의 Copy는 S3의 Parquet 파일을 읽을 때 파일에 포함 된 컬럼의 정보를 무시하고 순서를 맞춰서 입력해야 합니다. 이 경우에 만약 A, B 컬럼이 서로 입력 될 수 있는 타입을 가진채로 입력이 진행되고, 그 도메인의 범위가 어느정도 일치한다면 실제 서비스에 사용 될 때까지 인지하기 어려운 문제도 발생 할 수 있습니다.

이러한 경우가 “오류 또는 원하는 결과가 나오지 않아서 발생하는 일관성 불일치”라고 생각합니다.

그러면 우리는 “오류 혹은 원하는 결과가 나오도록 관측”해야 합니다.

가공의 단계를 나누어 가공의 정도를 줄이는 방안

이 글을 적으면서 참조한 페이지에서 좋은 방안이 나와서 추가적으로 적는 내용입니다.

데이터는 더 많이 가공 될 수록 신뢰성을 잃을 가능성이 높다는 문장입니다. 그래서 각 가공 단계를 나누어서 신뢰성을 확보하는 방안도 좋은 것 같습니다.

Summary

  1. 명확한 목적을 가지고 있는 테이블의 파생을 주의한다.
  2. 조건의 카디널리티를 줄이는 방향으로 설계한다.
  3. 명확한 목적을 가진 처리를 한다.
  4. 오류 혹은 원하는 결과가 나오는 것을 확인하는 시스템을 구축한다.
  5. 가공의 정도를 줄인다.

참고

  • https://www.ibm.com/kr-ko/topics/data-reliability
  • https://brunch.co.kr/@8d1b089f514b4d5/39