새소식

반응형
GCP/BigQuery

BigQuery - 운영 1탄 / 불필요한 dataset 삭제

  • -
반응형

운영은 필수다.

 

안녕하세요. 

제가 아무래도 DBA로 시작해서 그런지 자연스럽게 성향이 운영을 당연시합니다. 

모니터링을 데이터를 기반으로 비용 절감과 고효율을 만들기 위해서 여러 가지 방법으로 고민을 합니다.

 

최근 트랜드에서 아쉬운 부분이 있다면, 많은 회사들은 개발을 빠르게 하기에 초점을 맞추다 보니 운영을 뒷전인 경우가 굉장히 많은 것 같습니다. 운영을 신경 쓰지 않으면 결국 시스템은 터지기 마련입니다. 그렇기에 이번에는 BigQuery에서 몇 가지 운영 관련한 내용을 정리하여 글을 쓰고자 합니다.

 

1. Dataset 왜 지우려고 하는가?

 

BigQuery는 Dataset의 저장 비용이 매우 저렴합니다.

제가 생각하기에 BigQuery의 비용은 저장비용보다는 검색(SELECT)비용이 대부분이라고 봅니다.

 

다음의 내용을 보면 가격이 매우 저렴한 것을 알 수 있습니다.

 

BigQuery 저장 비용

 

아래의 내용을 보면 예시를 통해서 용량 크기에 따라서 얼마나 비용이 발생하는지 알 수 있습니다.

 

가격 책정 예시

 

자세한 내용은 아래의 링크를 보면 더욱 자세히 알 수 있습니다.

https://cloud.google.com/bigquery/pricing#storage

 

가격 책정  |  BigQuery: 클라우드 데이터 웨어하우스  |  Google Cloud

BigQuery 가격 책정 검토

cloud.google.com

 

위에서도 언급했듯이 BigQuery의 저장 가격은 매우 저렴하고, 검색비용이 대부분을 차지합니다.

하지만 저장 비용이 저렴한 것은 맞지만 공짜는 아닙니다.

 

그렇기에 영구적으로 데이터를  보관해야 하는 경우가 아니라면 데이터를 지워서 비용을 절감해야 한다고 봅니다.

그리고  위에서 예시를 통해서  대충 계산해도 10TB만 있어도 한 달에 산술적으로 200$입니다.

BigQuery에 저장하는 만큼 TB 단위는 당연히 넘어서  PB까지도 저장을 할 것인데, 당연히 무시할 수 없습니다.

 

 

2. 어떤 기준으로 선정할까?

 

데이터를 지우는 부분은 민감한 부분입니다.

있던 데이터가 없어지면 큰일 나는 경우가 많습니다. (이 부분은 뒤에서 다루겠습니다.)

 

우선 데이터가 얼마나 쌓여있는지 보고 판단하기 위해서 Table의 크기와  row를 추출하여  따로 Database에 저장하였습니다. (현재 저는 모니터링 Database를 중앙 화하여 관리하고 있습니다.)

 

아래의 Query를 통해서 Table의 정보를 일자별로 저장하였습니다.

SELECT project_id,dataset_id,table_id,row_count,(size_bytes/1024)/1024 as size 
FROM <dataset_name>.__TABLES__ 
cs

 

위의 내용을 저장하여 Dataset 별로 크기를 정리하여  엑셀로  만듭니다.

 

엑셀을 이용해서 정리

 

엑셀을 이용해서 내용을 정리하고 전사적으로 공유해서 담당자를 기입하고 확인하도록 하여 이 데이터를 삭제할지 아니면 영구 보존할지 정할 수 있습니다. 사실 이 부분에서는 막일(?) 작업이 필요할 수밖에 없습니다.

 

BigQuery에는 tag와 같이 설명이라는 항목을 제공하며, 여기에 담당자와 여러 가지 내용을 작성할 수 있지만 철저하게 관리되지 않는 경우 특히 Dataset을 만드는 권한이 관리자에게 집중되지 않는 경우는 Dataset에 이러한 규칙이 정상적으로 작성되고 관리되지 못하는 경우가 많습니다.

 

BigQuery 설명

 

그렇기에 어쩔 수 없이 담당자를 알아내야 하는 노가다 작업이 필요합니다.

조금은 번거로울 수 있지만 이 부분은 어쩔수 없다고 봅니다. 그렇다고 권한을 모두 제한하고 갑자기 권한을 제거한다면, 많은 부서에서 좋아하지 않을 것 같습니다. 

 

 

🤷‍♂️ Why?

Q. Dataset을 지우지 않고 Table별로 관리는 안될까?

Table을 지우는 부분을 아마도 Table을 한달,일년 이런식으로 "데이터를 최신으로 얼마나 가지고 있을 것인가?" 라는 부분 때문에 고민한다고 봅니다. 이 경우에는 BigQuery 자체에서 Table 수명이라는 기능을 제공하고 있어서, Table의 수명이 지나면 자동으로 지워지게 할 수 있습니다. 

단, 하나의 Table에서 Life cycle을 지정 하는 경우는 당연히 Query를 통해서 배치처리를 만들어야 할 것 같습니다. 

 

 

3.  담당자가 지정되지 않은 경우 바로 Dataset을 지워야 할까?

 

결론부터 말하면 아닙니다.

운영을 해본 입장에서 말하면 우리의 고객(?)인 사용자들은 업무가 매우 바쁩니다.

그래서 아무리 여러 번 말해도 놓칠 수 있다고 봅니다.

 

Dataset을 지웠는데, 갑자기 이런 말을 들을 수 있습니다.

 

"그 데이터 필요한데 왜 지웠나요? 다시 복구해주세요."

 

아... 정말 난감합니다.

내가 그렇게 많이 이야기했는데...

 

좌절...

 

하지만 어쩔 수 없죠.

우리는 복구를 해줘야 합니다. 

어찌 보면 운영을 하는 엔지니어의 숙명과도 같은 업무죠... 복구 

그래서 Dataset을 다른 project에 복사를 해둡니다. 

 

저 같은 경우 다음과 같이 여기저기에서 옵션을 보고 다음의 bq 명령어를 만들었습니다.

일단 작업은 2단계로 나뉩니다. 

 

첫 번째, Dataset을 만듭니다.

제가 Dataset을 그대로 복사하려고 했는데, Dataset이 없다고 하면서 복사가 되질 않았습니다.

확인해보면 Dataset을 복사하는 명령어 자체는 만들면서 들어가는 게 아닌 것 같습니다. (옵션이 있겠지만 찾지 못하였습니다.)

bq mk --dataset \
<생성 할 프로젝트>:<생성 할 Dataset명> 
cs

위와 같이 <> 부분에 만들고자 하는 project와 Dataset을 넣고 우선 Dataset을 만들어 줍니다. 

 

두 번째, Dataset을 복사합니다.

Dataset을 만들었다면 이제 복사를 시작할 수 있습니다.

bq mk --transfer_config --data_source=cross_region_copy --project_id=<현재 프로젝트명> \
   --params='{"source_dataset_id": "<복사할 Dataset명>", "source_project_id": "<복사할 프로젝트명>"}' \
   --target_dataset=tables --display_name=<작업에 보여줄 이름> \
   --schedule_end_time="$(date -v +1H -u +%Y-%m-%dT%H:%M:%SZ)"
cs

위에서 조금 조심해야 할 것은 복사할 project명과 목적지 project명을 잘 봐야 한다는 것입니다. 

(잘못하면 반대 상황이 발생할 수 있습니다.)

 

그리고 여기서 주의해야 할 점이 있습니다.

만약에 테이블이 있으면 해당 테이블이 복사가 되지 않습니다.

Dataset 복사지만, 결론적으로는 Table 복사가 맞는 말입니다.

예를 들어서 예전에 한번 복사를 시행했고, 이후에 다시 한번 복사를 해야 하는 상황이 발생했다면, 테이블을 지우고 또는 Dataset를 깔끔하게 지우고 다시 수행해 주셔야 합니다. 그렇지 않을 경우 이미 테이블이 있다고 메시지가 나오면서 테이블을 복사하지 않습니다.

 

테이블이 있어서 복사가 안됌

 

bq 명령어를 통해서 작업을 만들면 아래의 스크린숏과 같이 "데이터 전송" 부분에서 결과 및 상황을 확인할 수 있습니다.

 

데이터 전송

 

작업을 만들면 즉시 데이터를 전송하기 시작합니다.

단, 데이터 전송을 할 테이블이 많을 경우 시간이 약간 걸립니다. (2000개 정도에 15분 정도 소요됐음)

 

👍 Tip

가끔 데이터 전송이 오류가 납니다. 하지만 정상적으로 실행됩니다.

사이즈 큰 테이블이나 개수가 많을 경우 가끔 오류가 나는데요. 
이상하게 테이블이 계속 생성됩니다. 그러니 당황하지 마시고, 테이블이 생기는지 새로고침 해보세요.
아마도 불친절한 구글에서...

 

그런데 말입니다.

 

그런데, 생각해보면 Dataset을 한두 개만 지우진 않을 것 같습니다.

운영을 한다고 하면 수십수백 개의 Dataset을 관리할 것이라고 봅니다.

그래서 이걸 전부 하나씩 지우는 건 조금 아닌 것 같고... 

 

그래서 Python으로 대충(?) 만들어 봤습니다.

import os
import time
 
= open("복사할 dataset 리스트 txt파일""r")
 
source_project = ""
destination_project = ""
 
while True:
    line = f.readline()
    line = line.replace("\n""")
 
    if not line:
        break
 
    print(f"여기 시작중 ... {line}")
    create_dataset = (f"""bq mk --dataset {destination_project}:{line}_remove""")
    copy_dataset=f'bq mk --transfer_config --data_source=cross_region_copy --project_id={source_project} --params=\'{{"source_dataset_id":"{line}", "source_project_id": "{destination_project}"}}\' --target_dataset={line} --display_name={line} --schedule_end_time="$(date -v +1H -u +%Y-%m-%dT%H:%M:%SZ)"'
    print("_________________________________________________________________________")
    print(create_dataset)
    print(copy_dataset)
    print("_________________________________________________________________________")
 
    os.system(create_dataset)
    os.system(copy_dataset)
 
    time.sleep(5)
 
f.close()
 
cs

 

txt 파일의 경우 다음과 같이 리스트를 /n 구분자로 입력해주시면 됩니다.

 

dataset 리스트

 

이렇게 하면 순차적으로 Dataset을 생성하고 복사하는 작업을 만듭니다.

제가 혼자 쓰려고 만든 코드라서 조금 부족하지만 쓰는 데는 전혀 문제가 없습니다.

(파라미터 명도 조금...)

 

4. 이제 정말로 Dataset을 지웁니다.

 

이제 Dataset을 정말로 지워야 합니다.

생각보다 이 명령어는 더 간단합니다. 

 

이 부분은 아예 Python 코드로 있는 부분을 제가 수정해서 만들었습니다.

from google.cloud import bigquery
import time
 
client = bigquery.Client(project='삭제할 dataset의 project위치')
 
= open("복사할 dataset 리스트 txt파일""r")
 
while True:
    line = f.readline()
    line = line.replace("\n""")
 
    if not line:
        break
        
    client.delete_dataset(line, delete_contents=True, not_found_ok=True
 
    print("_________________________________________________________________________")
    print("Deleted dataset '{}'.".format(line))
    print("_________________________________________________________________________")
 
    time.sleep(5)
 
f.close()
 
cs

 

위의 복사와 같은 방법으로 리스트에 삭제할 Dataset을 넣고 실행하면 쭈욱 지워집니다.

아래의 링크에서 다른 언어를 통해서 하는 방법도 다루고 있으니 편하신 방법으로 사용하는 것도 좋을 듯합니다.

https://cloud.google.com/bigquery/docs/samples/bigquery-delete-dataset

 

데이터 세트 삭제  |  BigQuery  |  Google Cloud

의견 보내기 데이터 세트 삭제 프로젝트에서 데이터 세트를 삭제합니다. 이 코드 샘플이 포함된 문서 페이지 컨텍스트에서 사용된 코드 샘플을 보려면 다음 문서를 참조하세요. 코드 샘플 C# 이

cloud.google.com

 

마치며...

가장 처음에도 언급했지만 많은 회사들이 개발에만 집중하는 것이 너무 안타깝습니다.

운영을 하지 않으면 갑자기 문제가 여기저기서 문제가 터지면서 해결이 불가능 한 지경에 이르게 됩니다.

최근에는 클라우드가 많이 발달되고 도입되면서 관리자가 아닌 다양한 사용자와 직군에서 사용하면서 누구나 쉽게 서버를 만들거나 위와 같이 BigQuery에서 Dataset이나 Table을 만드는 등의 여러 가지 권한을 가지고 있는 경우가 많습니다.

 

그렇기 때문에 운영을 하지 않을 경우 비용면에서 감당이 안 되는 상황이 발생할 수 있습니다.

또한 퇴사를 하거나 임시로 만든 Dataset과 같은 경우 사용하던 사람이 잊어버리고 그냥 내버려두는 경우가 많습니다.

운영은 선택이 아닌 필수인 것을 언제나 기억했으면 좋겠습니다.

 

감사합니다.

 

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.