PyMongo 를 이용하여 마이그레이션 스크립트 작성하기 (1)

·2020년 8월 29일
0

Database

목록 보기
1/2

최근 회사에 데이터 분석 툴을 도입하게 되면서 각 서버마다 데이터 수집을 위한 세팅을 진행하였다. 나는 그 중 작은 서버를 담당하게 되어 며칠 안에 금방 처리할 수 있을 줄 알았는데 … 데이터 분석을 위해 필요한 요건을 살펴보다 지금 스키마로는 데이터 수집이 어렵다는 것을 알게되었다. 더 정확하게는, 매번 데이터를 전송할 때 마다 DB 에 부담이 갈 수 밖에 없는 구조였다.

고민 끝에 통계성 메타 데이터를 관리하는 별도의 컬렉션을 만들고, 기존 데이터들은 스크립트로 연산하여 해당 컬렉션에 반영하기로 하였다!

마이그레이션이란?

데이터 마이그레이션이란 시스템의 변경에 의해 데이터를 새로운 시스템으로 이관하는 행위를 의미한다. 내가 이번에 진행하는 테이블(컬렉션) 생성 혹은 변경과 같은 작은 범위도 마이그레이션에 속한다.

Python, PyMongo

해당 DB 에 접근하는 서버가 노드이긴 하지만, 전체 유저를 데이터를 대상으로 하는 작업이다보니 유저 목록과 정보를 CSV 파일로 스크립트에 넘기는 것이 좋겠다고 생각되어 CSV 파일을 쉽게 읽고 쓸 수 있는 파이썬을 선택했다. (‘데이터 처리에는 파이썬이 많이 쓰인다’ 는 말을 자주 들어서 이번 기회에 체감해보고 싶은 마음도 있었는데 파이썬이 데이터와 궁합이 좋은 이유를 아직은 잘 모르겠다 🙃) 몽고 DB 를 사용하고 있어 파이썬 몽고 DB 드라이버인 PyMongo - 파이 몽고를 이용했다.

PyMongo 시작하기

정말 간단하다!
pip 을 이용하여 pymong 를 설치해준 다음,

$ python -m pip install pymongo

스크립트에서 pymongo 를 import 한 후 DB 와 연결해주면 끝! 바로 원하는 쿼리를 작성해주면 된다.

import pymongo
def pymongo_script():
    uri = "mongodb://ganadaramabasa..."
    client = pymongo.MongoClient(uri)
    db = client.get_database('target-database-name')
    ...
    
if __name__ == "__main__":
   pymongo_script()
  • URI 가 아닌 host, port 를 지정하는 방법으로도 접속할 수 있다.
  • URI 로 접속할 경우, 스크립트를 실행시킬 때 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate 라는 에러가 발생할 수 있는데 URI 끝에 ?ssl=true&ssl_cert_reqs=CERT_NONE 을 붙이면 해결할 수 있다.

🔗 Certificate verification policy : https://api.mongodb.com/python/current/examples/tls.html?highlight=ssl_cert_reqs

고민되었던 것들

특별히 더 걱정되고 주의했던 부분들은, (사실 아직 라이브에서는 돌려보지 않아서 여전히 걱정 중 😂)

  • DB 부하
    유저 한 명에 대한 새로운 도큐먼트를 생성할 때 마다 로그성으로 남아있는 이전 도큐먼트를 다 찾아내서 연산해야 하기 때문에 DB 에 무리가 가지는 않을까 걱정이 되었다.

    예전에 전체 유저 중 절반에 해당하는 유저의 특정 정보를 일괄 수정하는 스크립트를 돌린 적이 있는데 그 때 몽고가 거의 터지기 직전까지 갔던 오싹한 기억이 있다. 나중에 알게된 것인데 index 가 걸리지 않은 query 를 날려서 생긴 문제였어서 이번에는 스크립트 조회 정책에 맞춰 index 를 생성하였다.

    조회만 하는 기존 컬렉션은 read preference 를 secondary preferred 로 설정하여 접근하였고 생성하는 컬렉션은 default 값인 primary 로 설정하였다.

import pymongo
from pymongo import ReadPreference
def pymongo_script():
    uri = "mongodb://ganadaramabasa..."
    client = pymongo.MongoClient(uri)
    db = client.get_database('target-database-name')
    read_collection = 
        db.get_collection('collection-a')
    write_collection = 
        db.get_collection(
            'collection-b',
            read_preference=ReadPreference.SECONDARY_PREFERRED
        )
if __name__ == "__main__":
   pymongo_script()

시점

라이브에서 계속 실시간으로 업데이트되는 데이터이기 때문에 기존 데이터를 ‘언제’ 이전으로 조회해야 누락되거나 중복되는 데이터가 없을지 고민이 되었다. 이 부분은 신규 컬렉션의 도큐먼트별 타임스탬프의 생성 시간을 기준으로 조회하였다.

에러처리

처리 실패한 유저를 파악하기 위해 스크립트를 돌며 성공, 실패 여부와 실제 도큐먼트를 생성할 때 (혹은 생성하고자 했을 때) 반영하고자 했던 연산 값들을 기록하는 로그 CSV 를 생성하도록 처리하였다.

0개의 댓글