Computer >> 컴퓨터 >  >> 프로그래밍 >> 데이터베이스

Apache Cassandra 데이터베이스 백업 및 복구 완벽 가이드

데이터베이스 백업과 복구는 데이터베이스 관리자(DBA)가 수행하는 가장 중요한 일상 업무 중 하나입니다. 데이터베이스 백업은 데이터 손실 상황이 발생했을 때 이를 복구하는 데 사용할 수 있는 데이터 사본입니다.

이 글에서는 Apache® Cassandra® 데이터베이스를 백업하고, 장애 발생 후 이를 복원하는 방법을 단계별로 소개합니다.

개요

Apache Cassandra는 분산형 구조를 가지고 있어, 클러스터 내 최소 한 개의 노드에만 데이터가 존재한다면 단일 노드 장애는 물론 다중 노드 장애가 발생하더라도 비즈니스 데이터를 잃지 않고 견딜 수 있습니다. 하지만 모범 사례 관점에서 보면 반드시 데이터베이스 백업을 구성해 두는 것이 좋습니다.

클러스터 전체 재구축, 데이터 손상, 실수로 인한 데이터 삭제 등 어떤 장애가 발생하더라도 백업본에서 데이터를 복원하여 비즈니스 운영을 최소한의 영향 또는 무영향으로 지속할 수 있습니다.

최근에는 빅데이터라고 불리는 대용량 비즈니스 데이터를 효과적으로 관리하기 위해 Cassandra와 같은 NoSQL 데이터베이스를 도입하는 기업이 점점 늘어나고 있습니다. Cassandra는 많은 주요 조직에서 널리 사용되며, 확장성, 내결함성, 일관성을 보장하여 빅데이터 환경을 지원합니다.

Cassandra 데이터베이스 백업 및 복원

Cassandra 데이터베이스의 스냅샷을 생성하고 필요할 때 복원하려면 다음 유틸리티를 활용할 수 있습니다:

  • nodetool — 스냅샷 생성용
  • sstableloader — 스냅샷 백업 복원용

다음 이미지는 sstableloader를 사용해 클라우드 클러스터에서 Cassandra 클러스터로 데이터를 이전하는 과정을 보여줍니다.

Apache Cassandra 데이터베이스 백업 및 복구 완벽 가이드

이미지 출처: https://dzone.com/articles/using-casandras-sstable-bulk

백업(Backup)

다음 예제에서는 nodetool을 사용하여 employee 테이블이 있는 Cassandra 데이터베이스 키스페이스(users)의 스냅샷을 생성합니다.

소스 Cassandra 클러스터 정보:

$ nodetool -u cassandra -pw ******** -h localhost status

Datacenter: us-central1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns (effective)  Host ID                               Rack
UN  10.128.0.2  121.52 KiB  256         63.3%             5957997f-7471-4c21-bead-37a6604812e2  f
UN  10.128.0.3  92.22 KiB  256          68.0%             87c2a663-a965-4675-b5ed-c4a46d77c796  f
UN  10.128.0.4  225.3 KiB  256          68.8%             8e12557f-be00-4387-bff3-ef51f431b9a0  f

다음 명령으로 키스페이스를 백업합니다:

$ nodetool -h localhost -u cassandra -pw ****** snapshot users -t "users-201904201800"

Requested creating snapshot(s) for [users] with snapshot name [users-201904201800] and options {skipFlush=false}
Snapshot directory: users-201904201800

위 명령을 실행하면 아래 예제와 같이 백업 스냅샷이 생성됩니다:

/bitnami/cassandra/data/data/users/employee-c1319df0636211e9a0e3570eb7f8fd5f/snapshots/users-201904201800
$ ls -ltr
total 44
-rw-r--r-- 2 cassandra cassandra   16 Apr 20 12:05 md-1-big-Filter.db
-rw-r--r-- 2 cassandra cassandra   56 Apr 20 12:05 md-1-big-Summary.db
-rw-r--r-- 2 cassandra cassandra   32 Apr 20 12:05 md-1-big-Index.db
-rw-r--r-- 2 cassandra cassandra  134 Apr 20 12:05 md-1-big-Data.db
-rw-r--r-- 2 cassandra cassandra   10 Apr 20 12:05 md-1-big-Digest.crc32
-rw-r--r-- 2 cassandra cassandra   43 Apr 20 12:05 md-1-big-CompressionInfo.db
-rw-r--r-- 2 cassandra cassandra 4683 Apr 20 12:05 md-1-big-Statistics.db
-rw-r--r-- 2 cassandra cassandra   92 Apr 20 12:05 md-1-big-TOC.txt
-rw-r--r-- 1 cassandra cassandra   31 Apr 20 12:05 manifest.json
-rw-r--r-- 1 cassandra cassandra  865 Apr 20 12:05 schema.cql

$ date
Sat Apr 20 12:08:21 UTC 2019

이제 /snapshot 백업 디렉터리의 파일들을 tar 파일로 압축한 뒤, 해당 tar 파일을 /bitnami/Cassandra/data/data/backup 디렉터리로 옮깁니다.

$ tar -cvf users-201904201800.tar *.*
manifest.json
md-1-big-CompressionInfo.db
md-1-big-Data.db
md-1-big-Digest.crc32
md-1-big-Filter.db
md-1-big-Index.db
md-1-big-Statistics.db
md-1-big-Summary.db
md-1-big-TOC.txt
schema.cql

$ ls -ltr
total 64
-rw-r--r-- 2 cassandra cassandra    16 Apr 20 12:05 md-1-big-Filter.db
-rw-r--r-- 2 cassandra cassandra    56 Apr 20 12:05 md-1-big-Summary.db
-rw-r--r-- 2 cassandra cassandra    32 Apr 20 12:05 md-1-big-Index.db
-rw-r--r-- 2 cassandra cassandra   134 Apr 20 12:05 md-1-big-Data.db
-rw-r--r-- 2 cassandra cassandra    10 Apr 20 12:05 md-1-big-Digest.crc32
-rw-r--r-- 2 cassandra cassandra    43 Apr 20 12:05 md-1-big-CompressionInfo.db
-rw-r--r-- 2 cassandra cassandra  4683 Apr 20 12:05 md-1-big-Statistics.db
-rw-r--r-- 2 cassandra cassandra    92 Apr 20 12:05 md-1-big-TOC.txt
-rw-r--r-- 1 cassandra cassandra    31 Apr 20 12:05 manifest.json
-rw-r--r-- 1 cassandra cassandra   865 Apr 20 12:05 schema.cql
-rw-r--r-- 1 cassandra cassandra 20480 Apr 20 12:22 users-201904201800.tar

cp *.tar /bitnami/cassandra/data/data/backup.
/bitnami/cassandra/data/data/backup

$ ls -ltr
-rw-r--r--  1 cassandra cassandra 20480 Apr 20 12:23 users-201904201800.tar

백업 tar 파일을 기본 위치가 아닌 곳으로 복사한 후, employee 테이블을 삭제(drop)합니다.

참고: Cassandra는 정의된 파티션 키와 복제 계수(replication factor)를 기준으로 클러스터 전반에 데이터를 분산 저장합니다. 따라서 이 백업 명령은 모든 노드에서 실행해야 합니다. 이 예제에서는 Linux® 셸 스크립트를 crontab에 등록하여 모든 노드를 한 번에 백업하는 방식을 사용합니다.

$ cqlsh -u cassandra -p *******

Connected to Test_Cassandra at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.

cassandra@cqlsh> use users;
cassandra@cqlsh:users> select * from employee;

 emp_id | employee_address | employee_name
--------+------------------+---------------
   8796 |        Singapore |           Joy
   5647 |           London |          Mike
   3452 |           Canada |         Nancy
   6453 |            China |          John

(4 rows)

cassandra@cqlsh:users> drop table employee;
cassandra@cqlsh:users> select * from employee;
InvalidRequest: Error from server: code=2200 [Invalid query] message="unconfigured table employee"

복원(Restore)

키스페이스(users)의 스냅샷 백업에서 employee 테이블을 복원하려면 sstableloader 유틸리티를 사용해야 합니다. sstableloader는 각 노드에 sstable 세트를 복사할 뿐만 아니라, 클러스터에 정의된 복제 전략(replication strategy)에 따라 적절한 데이터 부분을 모든 노드에 전송합니다. 참고로 데이터를 복원하기 위해 테이블이 반드시 비어 있어야 하는 것은 아닙니다.

다음 단계에 따라 tar 파일을 backup/users 경로에 복원합니다:

$ pwd
/bitnami/cassandra/data/data/backup/users
$ ls -ltr
total 20
-rw-r--r-- 1 cassandra cassandra 20480 Apr 20 12:23 users-201904201800.tar
$ tar -xvf *.tar
manifest.json
md-1-big-CompressionInfo.db
md-1-big-Data.db
md-1-big-Digest.crc32
md-1-big-Filter.db
md-1-big-Index.db
md-1-big-Statistics.db
md-1-big-Summary.db
md-1-big-TOC.txt
schema.cql

복원하려는 테이블 이름과 동일한 이름으로 user 디렉터리에 대한 심볼릭 링크(soft link)를 생성합니다.

$ ln -s /bitnami/cassandra/data/data/backup/users employee
$ ls -ltr
total 64
-rw-r--r-- 1 cassandra cassandra   865 Apr 20 12:05 schema.cql
-rw-r--r-- 1 cassandra cassandra    92 Apr 20 12:05 md-1-big-TOC.txt
-rw-r--r-- 1 cassandra cassandra    56 Apr 20 12:05 md-1-big-Summary.db
-rw-r--r-- 1 cassandra cassandra  4683 Apr 20 12:05 md-1-big-Statistics.db
-rw-r--r-- 1 cassandra cassandra    32 Apr 20 12:05 md-1-big-Index.db
-rw-r--r-- 1 cassandra cassandra    16 Apr 20 12:05 md-1-big-Filter.db
-rw-r--r-- 1 cassandra cassandra    10 Apr 20 12:05 md-1-big-Digest.crc32
-rw-r--r-- 1 cassandra cassandra   134 Apr 20 12:05 md-1-big-Data.db
-rw-r--r-- 1 cassandra cassandra    43 Apr 20 12:05 md-1-big-CompressionInfo.db
-rw-r--r-- 1 cassandra cassandra    31 Apr 20 12:05 manifest.json
-rw-r--r-- 1 cassandra cassandra 20480 Apr 20 12:23 users-201904201800.tar
lrwxrwxrwx 1 cassandra cassandra    41 Apr 20 15:56 employee -> /bitnami/cassandra/data/data/backup/users

스냅샷 백업 시 생성된 .cql 파일을 사용해 테이블 구조를 다시 만듭니다.

키스페이스 백업을 실행하면 해당 키스페이스에 포함된 객체들의 DDL(데이터 정의 언어)이 담긴 schema.cql 파일이 자동으로 생성됩니다.

실수로 삭제된 employee 객체는 이 schema.cql 파일을 통해 재생성할 수 있습니다.

$ cqlsh -u cassandra -p ******** -f schema.cql

Warnings:
dclocal_read_repair_chance table option has been deprecated and will be removed in version 4.0

dclocal_read_repair_chance table option has been deprecated and will be removed in version 4.0
$ cqlsh -u cassandra -p ******* -f schema.cql

이제 sstableloader를 사용해 스냅샷에서 데이터를 복원합니다. 이 도구는 백업에 포함된 모든 sstables를 읽어 클러스터로 데이터를 스트리밍하며, 클러스터에 정의된 복제 전략에 따라 각 노드에 해당하는 데이터 부분을 전송합니다.

Syntax: sstableloader -u <username> -pw passwrod -d <hostname> <employee table softlink name with location>

다음 명령으로 데이터를 복원합니다:

$  sstableloader -u cassandra -pw  ******** -d cassandra-cluster-1-node-0 /bitnami/cassandra/data/data/backup/users/employee
Established connection to initial hosts
Opening sstables and calculating sections to stream
Streaming relevant part of /bitnami/cassandra/data/data/backup/users/md-1-big-Data.db  to [/10.128.0.2, /10.128.0.3, /10.128.0.4]
progress: [/10.128.0.2]0:0/1 0  % [/10.128.0.3]0:0/1 0  % [/10.128.0.4]0:1/1 100% total: 33% 0.032KiB/s (avg: 0.032KiB/s)
progress: [/10.128.0.2]0:0/1 0  % [/10.128.0.3]0:0/1 0  % [/10.128.0.4]0:1/1 100% total: 33% 0.000KiB/s (avg: 0.031KiB/s)
progress: [/10.128.0.2]0:0/1 0  % [/10.128.0.3]0:1/1 100% [/10.128.0.4]0:1/1 100% total: 66% 0.113KiB/s (avg: 0.050KiB/s)
progress: [/10.128.0.2]0:1/1 100% [/10.128.0.3]0:1/1 100% [/10.128.0.4]0:1/1 100% total: 100% 85.129KiB/s (avg: 0.074KiB/s)
progress: [/10.128.0.2]0:1/1 100% [/10.128.0.3]0:1/1 100% [/10.128.0.4]0:1/1 100% total: 100% 0.000KiB/s (avg: 0.073KiB/s)
progress: [/10.128.0.2]0:1/1 100% [/10.128.0.3]0:1/1 100% [/10.128.0.4]0:1/1 100% total: 100% 0.000KiB/s (avg: 0.073KiB/s)

Summary statistics:
   Connections per host    : 1
   Total files transferred : 3
   Total bytes transferred : 0.393KiB
   Total duration          : 5346 ms
   Average transfer rate   : 0.073KiB/s
   Peak transfer rate      : 0.074KiB/s

각 노드가 자신의 sstables에서 데이터를 가져올 수 있도록 위 과정을 모든 노드마다 반복 수행합니다.

그다음 nodetool repair로 데이터를 정합화합니다. 이 명령은 실행 중인 노드에 저장된 데이터의 모든 복제본을 서로 비교하여, 각 복제본을 최신 버전으로 갱신합니다.

$ nodetool repair -u Cassandra -pw ********

[2019-04-21 07:59:14,701] Starting repair command #1 (5b123ad0-640b-11e9-a0e3-570eb7f8fd5f), repairing keyspace users with repair options (parallelism: parallel, primary range: false, incremental: true, job threads: 1, ColumnFamilies: [], dataCenters: [], hosts: [], # of ranges: 768, pull repair: false)
[2019-04-21 07:59:16,450] Repair completed successfully
[2019-04-21 07:59:16,451] Repair command #1 finished in 1 second
[2019-04-21 07:59:16,460] Replication factor is 1. No repair is needed for keyspace 'system_auth'
[2019-04-21 07:59:16,474] Starting repair command #2 (5c22e780-640b-11e9-a0e3-570eb7f8fd5f), repairing keyspace system_traces with repair options (parallelism: parallel, primary range: false, incremental: true, job threads: 1, ColumnFamilies: [], dataCenters: [], hosts: [], # of ranges: 513, pull repair: false)
finished (progress: 1%)
[2019-04-21 07:59:17,653] Repair completed successfully
[2019-04-21 07:59:17,653] Repair command #2 finished in 1 second

마지막으로 삭제했던 employee 테이블의 데이터를 검증합니다. 앞선 명령들이 이전에 생성한 백업에서 데이터를 복원했으므로, 이제 데이터가 올바르게 복원되었는지 확인해야 합니다.

$ cqlsh -u cassandra -p ********

Connected to Test_Cassandra at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.11.4 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.

cassandra@cqlsh> use users;

cassandra@cqlsh:users> select * from employee;

 emp_id | employee_address | employee_name
--------+------------------+---------------
   8796 |        Singapore |           Joy
   5647 |           London |          Mike
   3452 |           Canada |         Nancy
   6453 |            China |          John

(4 rows)

마무리

이번 글에서는 Cassandra 데이터베이스에서 특정 테이블을 백업하고 복원하는 방법을 배웠습니다. 만약 테이블 단위가 아니라 키스페이스/데이터베이스 전체를 복원해야 한다면, 테이블 복원 부분을 제외한 위 단계들을 그대로 적용하면 됩니다. 이 경우 키스페이스를 먼저 재생성한 뒤, sstableloader로 데이터를 로드하면 됩니다.

sstableloader는 백업에 포함된 각 sstables를 직접 읽어 클러스터로 스트리밍하면서, 클러스터에 정의된 복제 전략에 맞게 데이터를 배치하기 때문에 소스 클러스터와 타겟 클러스터의 노드 수가 달라도 문제없이 작동합니다.

전문적인 관리 서비스로 환경 최적화하기

Rackspace의 Application services (RAS) 전문가들은 광범위한 애플리케이션 포트폴리오에 걸쳐 다음과 같은 전문 및 관리형 서비스를 제공합니다:

  • e커머스 및 디지털 경험 플랫폼
  • ERP(Enterprise Resource Planning, 전사적 자원 관리)
  • BI(Business Intelligence, 비즈니스 인텔리전스)
  • Salesforce CRM(Customer Relationship Management)
  • 데이터베이스
  • 이메일 호스팅 및 생산성 도구

저희가 제공하는 것들:

  • 중립적인 전문성: 즉각적인 가치를 창출하는 역량에 집중하여 현대화 여정을 간소화하고 안내합니다.
  • Fanatical Experience™: '프로세스 우선, 기술은 그다음(Process first. Technology second.)'이라는 철학과 전담 기술 지원을 결합해 종합적인 솔루션을 제공합니다.
  • 타의 추종을 불허하는 포트폴리오: 폭넓은 클라우드 경험을 바탕으로 올바른 클라우드에 적합한 기술을 선택하고 배포할 수 있도록 돕습니다.
  • 애자일한 제공 방식: 고객의 여정 어느 시점에서든 함께하며, 저희의 성공을 고객의 성공과 맞춥니다.

지금 바로 문의하여 시작하세요.