[발 번역]아마존 EBS 위의 MongoDB 백업하기

해당 문서는 http://blog.fiesta.cc/post/13127613694/backing-up-mongodb-instances-on-ebs 의 Backing up MongoDB instances on EBS 라는 글을 발 번역한 글입니다. 오역에 주의하세요.

 

아마존 EBS 위의 MongoDB 백업하기

Replica Set과 Journaling 을 사용함에도 불구하고, 정기적으로 데이터를 백업하는 것은 여전히 좋은 생각입니다.( 역자 주: MongoDB에서는 데이터의 안전성을 위해서 REplica Set과 Journaling을 함께 사용하는 것을 권장합니다. 개발 노드에서도 Journaling을 안 쓸 이유가 없다라고 하더군요.)  MongoDB 유저나, 다른 사람들로 부터,  꽤 복잡한 시스템에 정기적인 백업을 하지 않는다는 얘기를 자주 듣고 놀랍니다. 정기 백업은 Fiesta 의 백업 인프라스트럭처를 빠르게 대충 살펴보는데 많은 도움을 준다고 생각합니다.  누구든지 어떻게 이런 작업들을 다루는지 얘기해 준다면 경청하도록 하겠습니다.

 

Architecture

아마존 EC2 위에서 Single Replica Set으로 동작하고 있습니다. Secondary 장비를 백업을 위해서 사용하고 있습니다. 그리고 EBS위에서 동작하고 있습니다. 실제 백업을 위해서 아마존 Snapshot을 이용하며,  S3에 저장해둡니다. 모든 데이터는 MongoDB와 S3에 나뉘어져 있습니다. MongoDB 데이터를 어떻게 백업할 것인지에 초점을 맞추고 있습니다.

 

Journaling

MongoDB 1.8.x 부터 Journaling 이 들어갔습니다. Journaling 을 켜두면, MongoDB 데이터 디렉토리의 hot snapshot 을 만들 수 있습니다. 우리는 현재 Journaling 을 사용하고 있지는 않고 있습니다. 좀 더 조심스럽게 접근하기 위해서입니다. 현재는 백업노드에서 snapshot을 만들기 위해서 fsync 와 lock을 사용하고 있습니다.  해당 작업을 하는 코드는 다음과 같습니다.

 

The Code

다음 코드는 실제로 백업을 수행하는 코드입니다. lock_and_backup 함수는 매일 밤마다 cron 으로 동작합니다.


import subprocess

from pymongo import Connection
import settings
def do_ebs_backup():
 env = {"EC2_HOME": settings.ec2_home,
 "JAVA_HOME": settings.java_home}
 keyfile = EC2_KEY
 certfile = EC2_CERT
 args = ["-K", keyfile, "-C", certfile]

# We use the 'backup' tag to find the volumes to back up
 out = subprocess.Popen([settings.ec2_tools + "bin/ec2-describe-volumes",
 "-F", "tag:env=backup"] + args,
 stdout=subprocess.PIPE,
 env=env).communicate()[0]
 volumes = set([v for v in out.split() if v.startswith("vol-")])
 if not volumes:
 raise Exception("No volumes to backup?")

# Create a snapshot for each volume we found above
 snaps = []
 for volume in volumes:
 snap = subprocess.Popen([settings.ec2_tools + "bin/ec2-create-snapshot"] + \
 args + [volume],
 stdout=subprocess.PIPE,
 env=env).communicate()[0]
 snaps.append(snap)
 return snaps
def lock_and_backup():
 conn = Connection(slave_okay=True)
 try:
 conn.admin.command("fsync", lock=True)
 do_ebs_backup()
 finally:
 conn.admin["$cmd.sys.unlock"].find_one()
<pre>

 

Snapshot을 위해서 EC2 command-line 툴을 이용하고 있으며, Python의 Subproecess 모듈을 해당 툴과의 연동을 위해서 사용하고 있습니다.  가장 중요한 작업은 lock_and_backup() 함수이며, fsync 커맨드의 실행과, snapshot 전에 쓰기 Lock을 설정합니다.

(역자 주: 코멘트 중에 왜 boto를 안쓰냐는 얘기가 있습니다.  boto는 아마존 Ec2를 위한 오픈소스 Python 툴입니다. 현재 boto 말고도, python 쪽에 libcloud 라는 좋은 툴이 있는데, boto는 정말 아마존 특화된 기능들이 많습니다.)