백업
백업 (Backups)
Apache Cassandra는 불변 SSTable 파일에 데이터를 저장해요. Apache Cassandra 데이터베이스의 백업은 SSTable 파일로 저장된 데이터베이스 데이터의 백업 복사본입니다. 백업은 다음을 포함한 여러 목적으로 사용됩니다:
- 지속성(durability)을 위해 데이터 사본을 저장
- 노드/파티션/네트워크 장애로 테이블 데이터가 손실된 경우 테이블을 복원
- SSTable 파일을 다른 머신으로 이전(이식성, portability)
출처: 문서
본문
백업 유형
Apache Cassandra는 두 가지 백업 전략을 지원합니다.
- 스냅샷 (Snapshots)
- 증분 백업 (Incremental Backups)
스냅샷은 하드 링크를 통해 생성된, 특정 시점의 테이블 SSTable 파일 사본입니다. 테이블을 만드는 DDL도 함께 저장됩니다. 스냅샷은 사용자가 만들거나 자동으로 만들어질 수 있어요. cassandra.yaml 파일의 snapshot_before_compaction 설정은 각 컴팩션 전에 스냅샷을 만들지 여부를 결정합니다. 기본적으로 snapshot_before_compaction은 false로 설정됩니다. cassandra.yaml에서 auto_snapshot을 true(기본값)로 설정하면 키스페이스 잘라내기(truncation)나 테이블 삭제 전에 자동으로 스냅샷이 생성될 수 있어요. 자동 스냅샷 때문에 잘라내기가 지연될 수 있으며, 조정자가 잘라내기가 완료되기를 얼마나 기다릴지 결정하는 또 다른 설정이 cassandra.yaml에 있어요. 기본적으로 Cassandra는 자동 스냅샷 완료를 위해 60초를 기다립니다.
증분 백업은 멤테이블이 SSTable로 디스크에 플러시될 때 하드 링크로 생성된 테이블의 SSTable 파일 사본입니다. 보통 증분 백업은 백업 시간을 줄이고 디스크 공간을 줄이기 위해 스냅샷과 짝을 이룹니다. 증분 백업은 기본적으로 활성화되어 있지 않으며, cassandra.yaml에서(incremental_backups 설정으로) 또는 nodetool로 명시적으로 활성화해야 해요. 활성화되면 Cassandra는 로컬로 플러시되거나 스트리밍된 각 SSTable에 키스페이스 데이터의 backups/ 서브디렉터리에 하드 링크를 만듭니다. 시스템 테이블의 증분 백업도 만들어집니다.
데이터 디렉터리 구조
Cassandra 데이터의 디렉터리 구조는 키스페이스별로 다른 디렉터리로 구성되고, 테이블 데이터 파일이 있는 테이블 디렉터리도 있습니다. 특정 테이블에 대한 백업과 스냅샷을 각각 저장하는 backups와 snapshots 디렉터리도 테이블 디렉터리 안에 저장됩니다. Cassandra의 디렉터리 구조는 그림 1에 나와 있어요.
그림 1. Cassandra 데이터용 디렉터리 구조
백업과 스냅샷을 위한 예제 테이블 설정
이 섹션에서는 증분 백업과 스냅샷을 시연하는 데 사용할 수 있는 예제 데이터를 만들게요. 세 노드 Cassandra 클러스터를 사용했습니다. 먼저 키스페이스를 만들고, 키스페이스 안에 테이블을 만들고 테이블 데이터를 추가했습니다. cqlkeyspace와 catalogkeyspace 두 키스페이스를 사용했고 각각 두 테이블이 있습니다.
키스페이스 cqlkeyspace 만들기:
CREATE KEYSPACE cqlkeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
cqlkeyspace 키스페이스에 테이블 t와 t2 만들기:
USE cqlkeyspace;
CREATE TABLE t (
id int,
k int,
v text,
PRIMARY KEY (id)
);
CREATE TABLE t2 (
id int,
k int,
v text,
PRIMARY KEY (id)
);
테이블에 데이터 추가:
INSERT INTO t (id, k, v) VALUES (0, 0, 'val0');
INSERT INTO t (id, k, v) VALUES (1, 1, 'val1');
INSERT INTO t2 (id, k, v) VALUES (0, 0, 'val0');
INSERT INTO t2 (id, k, v) VALUES (1, 1, 'val1');
INSERT INTO t2 (id, k, v) VALUES (2, 2, 'val2');
데이터를 나열하는 테이블 쿼리:
SELECT * FROM t;
SELECT * FROM t2;
결과:
id | k | v
----+---+------
1 | 1 | val1
0 | 0 | val0
(2 rows)
id | k | v
----+---+------
1 | 1 | val1
0 | 0 | val0
2 | 2 | val2
(3 rows)
두 번째 키스페이스 catalogkeyspace 만들기:
CREATE KEYSPACE catalogkeyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};
catalogkeyspace에 테이블 journal과 magazine 만들기:
USE catalogkeyspace;
CREATE TABLE journal (
id int,
name text,
publisher text,
PRIMARY KEY (id)
);
CREATE TABLE magazine (
id int,
name text,
publisher text,
PRIMARY KEY (id)
);
테이블에 데이터 추가:
INSERT INTO journal (id, name, publisher) VALUES (0, 'Apache Cassandra Magazine', 'Apache Cassandra');
INSERT INTO journal (id, name, publisher) VALUES (1, 'Couchbase Magazine', 'Couchbase');
INSERT INTO magazine (id, name, publisher) VALUES (0, 'Apache Cassandra Magazine', 'Apache Cassandra');
INSERT INTO magazine (id, name, publisher) VALUES (1, 'Couchbase Magazine', 'Couchbase');
데이터를 나열하는 테이블 쿼리:
SELECT * FROM catalogkeyspace.journal;
SELECT * FROM catalogkeyspace.magazine;
결과:
id | name | publisher
----+---------------------------+------------------
1 | Couchbase Magazine | Couchbase
0 | Apache Cassandra Magazine | Apache Cassandra
(2 rows)
id | name | publisher
----+---------------------------+------------------
1 | Couchbase Magazine | Couchbase
0 | Apache Cassandra Magazine | Apache Cassandra
(2 rows)
스냅샷 (Snapshots)
이 섹션에서 스냅샷을 만드는 것을 시연할게요. 스냅샷을 만드는 데 사용하는 명령은 nodetool snapshot이며 사용법은 다음과 같습니다:
$ nodetool help snapshot
결과:
NAME
nodetool snapshot - Take a snapshot of specified keyspaces or a snapshot
of the specified table
SYNOPSIS
nodetool [(-h <host> | --host <host>)] [(-p <port> | --port <port>)]
[(-pp | --print-port)] [(-pw <password> | --password <password>)]
[(-pwf <passwordFilePath> | --password-file <passwordFilePath>)]
[(-u <username> | --username <username>)] snapshot
[(-cf <table> | --column-family <table> | --table <table>)]
[(-kt <ktlist> | --kt-list <ktlist> | -kc <ktlist> | --kc.list <ktlist>)]
[(-sf | --skip-flush)] [(-t <tag> | --tag <tag>)] [--] [<keyspaces...>]
OPTIONS
-cf <table>, --column-family <table>, --table <table>
The table name (you must specify one and only one keyspace for using
this option)
-h <host>, --host <host>
Node hostname or ip address
-kt <ktlist>, --kt-list <ktlist>, -kc <ktlist>, --kc.list <ktlist>
The list of Keyspace.table to take snapshot.(you must not specify
only keyspace)
-p <port>, --port <port>
Remote jmx agent port number
-pp, --print-port
Operate in 4.0 mode with hosts disambiguated by port number
-pw <password>, --password <password>
Remote jmx agent password
-pwf <passwordFilePath>, --password-file <passwordFilePath>
Path to the JMX password file
-sf, --skip-flush
Do not flush memtables before snapshotting (snapshot will not
contain unflushed data)
-t <tag>, --tag <tag>
The name of the snapshot
-u <username>, --username <username>
Remote jmx agent username
--
This option can be used to separate command-line options from the
list of argument, (useful when arguments might be mistaken for
command-line options
[<keyspaces...>]
List of keyspaces. By default, all keyspaces
스냅샷 구성
명령줄에서 Nodetool로 스냅샷 생성하는 것을 시연하기 위해 cassandra.yaml 파일에 auto_snapshots 설정을 false로 설정했습니다:
auto_snapshot: false
또한 컴팩션 전에 스냅샷을 자동으로 만드는 것을 비활성화하려면 snapshot_before_compaction을 false로 설정하세요:
snapshot_before_compaction: false
스냅샷 만들기
스냅샷을 만들기 전에 스냅샷을 검색하면 아무것도 나열되지 않을 것입니다:
$ find -name snapshots
예제 키스페이스와 테이블을 사용해 스냅샷을 만들 거예요.
키스페이스의 모든 테이블 스냅샷
위 문법을 사용해 catalogkeyspace 키스페이스의 모든 테이블에 대해 catalog-ks라는 스냅샷을 만듭니다:
$ nodetool snapshot --tag catalog-ks catalogkeyspace
결과:
Requested creating snapshot(s) for [catalogkeyspace] with snapshot name [catalog-ks] and
options {skipFlush=false}
Snapshot directory: catalog-ks
위 find 명령으로 이제 snapshots 및 snapshots 디렉터리가 다음과 유사한 파일과 함께 발견됩니다:
./cassandra/data/data/catalogkeyspace/journal-296a2d30c22a11e9b1350d927649052c/snapshots
./cassandra/data/data/catalogkeyspace/magazine-446eae30c22a11e9b1350d927649052c/snapshots
여러 키스페이스의 모든 테이블 스냅샷도 유사하게 만들 수 있습니다:
$ nodetool snapshot --tag catalog-cql-ks catalogkeyspace, cqlkeyspace
키스페이스의 단일 테이블 스냅샷
단일 테이블의 스냅샷을 만들려면 nodetool snapshot 명령 문법이 다음과 같습니다:
$ nodetool snapshot --tag <tag> --table <table> --<keyspace>
위 문법을 사용해 catalogkeyspace 키스페이스의 magazine 테이블에 대한 스냅샷을 만듭니다:
$ nodetool snapshot --tag magazine --table magazine catalogkeyspace
결과:
Requested creating snapshot(s) for [catalogkeyspace] with snapshot name [magazine] and
options {skipFlush=false}
Snapshot directory: magazine
같은 키스페이스의 여러 테이블 스냅샷
키스페이스의 여러 테이블 스냅샷을 만들려면 --kt-list 옵션으로 Keyspace.table 목록을 지정해야 해요. 예를 들어 cqlkeyspace 키스페이스의 테이블 t와 t2에 대한 스냅샷을 만듭니다:
$ nodetool snapshot --kt-list cqlkeyspace.t,cqlkeyspace.t2 --tag multi-table
결과:
Requested creating snapshot(s) for ["CQLKeyspace".t,"CQLKeyspace".t2] with snapshot name [multi-
table] and options {skipFlush=false}
Snapshot directory: multi-table
같은 테이블 집합의 여러 스냅샷을 만들고 다른 이름으로 태그할 수 있어요. 예를 들어 cqlkeyspace 키스페이스의 테이블 t와 t2에 대해 또 다른 스냅샷을 만들고 다르게 태그합니다:
$ nodetool snapshot --kt-list cqlkeyspace.t, cqlkeyspace.t2 --tag multi-table-2
결과:
Requested creating snapshot(s) for ["CQLKeyspace".t,"CQLKeyspace".t2] with snapshot name [multi-
table-2] and options {skipFlush=false}
Snapshot directory: multi-table-2
다른 키스페이스의 여러 테이블 스냅샷
다른 키스페이스에 있는 여러 테이블의 스냅샷을 만들려면 명령 문법은 여러 테이블이 같은 키스페이스에 있을 때와 동일합니다. 각 <keyspace>.<table>을 --kt-list 옵션에 별도로 지정해야 해요.
예를 들어 cqlkeyspace의 테이블 t와 catalogkeyspace의 테이블 journal에 대한 스냅샷을 만들고 스냅샷을 multi-ks로 태그합니다.
$ nodetool snapshot --kt-list catalogkeyspace.journal,cqlkeyspace.t --tag multi-ks
결과:
Requested creating snapshot(s) for [catalogkeyspace.journal,cqlkeyspace.t] with snapshot
name [multi-ks] and options {skipFlush=false}
Snapshot directory: multi-ks
스냅샷 나열
스냅샷을 나열하려면 nodetool listsnapshots 명령을 사용하세요. 앞선 예제에서 만든 모든 스냅샷이 나열됩니다:
$ nodetool listsnapshots
결과:
Snapshot Details:
Snapshot name Keyspace name Column family name True size Size on disk
multi-table cqlkeyspace t2 4.86 KiB 5.67 KiB
multi-table cqlkeyspace t 4.89 KiB 5.7 KiB
multi-ks cqlkeyspace t 4.89 KiB 5.7 KiB
multi-ks catalogkeyspace journal 4.9 KiB 5.73 KiB
magazine catalogkeyspace magazine 4.9 KiB 5.73 KiB
multi-table-2 cqlkeyspace t2 4.86 KiB 5.67 KiB
multi-table-2 cqlkeyspace t 4.89 KiB 5.7 KiB
catalog-ks catalogkeyspace journal 4.9 KiB 5.73 KiB
catalog-ks catalogkeyspace magazine 4.9 KiB 5.73 KiB
Total TrueDiskSpaceUsed: 44.02 KiB
스냅샷 디렉터리 찾기
스냅샷 디렉터리는 find -name snapshots 명령으로 나열될 수 있습니다:
$ find -name snapshots
결과:
./cassandra/data/data/cqlkeyspace/t-d132e240c21711e9bbee19821dcea330/snapshots
./cassandra/data/data/cqlkeyspace/t2-d993a390c22911e9b1350d927649052c/snapshots
./cassandra/data/data/catalogkeyspace/journal-296a2d30c22a11e9b1350d927649052c/snapshots
./cassandra/data/data/catalogkeyspace/magazine-446eae30c22a11e9b1350d927649052c/snapshots
특정 테이블의 스냅샷을 나열하려면 먼저 해당 테이블의 스냅샷 디렉터리로 변경하세요. 예를 들어 catalogkeyspace/journal 테이블의 스냅샷을 나열합니다:
$ cd ./cassandra/data/data/catalogkeyspace/journal-296a2d30c22a11e9b1350d927649052c/snapshots && ls -l
결과:
total 0
drwxrwxr-x. 2 ec2-user ec2-user 265 Aug 19 02:44 catalog-ks
drwxrwxr-x. 2 ec2-user ec2-user 265 Aug 19 02:52 multi-ks
snapshots 디렉터리는 스냅샷의 SSTable 파일을 나열합니다. 또한 각 스냅샷에는 스냅샷에서 복원할 때 테이블을 CQL로 재생성할 수 있는 스키마를 정의하는 schema.cql 파일이 생성됩니다:
$ cd catalog-ks && ls -l
결과:
total 44
-rw-rw-r--. 1 ec2-user ec2-user 31 Aug 19 02:44 manifest.jsonZ
-rw-rw-r--. 4 ec2-user ec2-user 47 Aug 19 02:38 na-1-big-CompressionInfo.db
-rw-rw-r--. 4 ec2-user ec2-user 97 Aug 19 02:38 na-1-big-Data.db
-rw-rw-r--. 4 ec2-user ec2-user 10 Aug 19 02:38 na-1-big-Digest.crc32
-rw-rw-r--. 4 ec2-user ec2-user 16 Aug 19 02:38 na-1-big-Filter.db
-rw-rw-r--. 4 ec2-user ec2-user 16 Aug 19 02:38 na-1-big-Index.db
-rw-rw-r--. 4 ec2-user ec2-user 4687 Aug 19 02:38 na-1-big-Statistics.db
-rw-rw-r--. 4 ec2-user ec2-user 56 Aug 19 02:38 na-1-big-Summary.db
-rw-rw-r--. 4 ec2-user ec2-user 92 Aug 19 02:38 na-1-big-TOC.txt
-rw-rw-r--. 1 ec2-user ec2-user 814 Aug 19 02:44 schema.cql
스냅샷 지우기
스냅샷은 nodetool clearsnapshot 명령으로 지우거나 삭제할 수 있어요. 특정 스냅샷 이름을 지정하거나 -all 옵션을 지정해야 합니다.
예를 들어 cqlkeyspace 키스페이스에서 magazine이라는 스냅샷을 삭제합니다:
$ nodetool clearsnapshot -t magazine cqlkeyspace
또는 -all 옵션으로 cqlkeyspace의 모든 스냅샷을 삭제합니다:
$ nodetool clearsnapshot -all cqlkeyspace
증분 백업 (Incremental Backups)
이어지는 섹션에서 증분 백업을 구성하고 만드는 것을 논의할게요.
증분 백업 구성
증분 백업을 만들려면 cassandra.yaml에서 incremental_backups를 true로 설정하세요.
incremental_backups: true
이것이 증분 백업을 만드는 데 필요한 유일한 설정이에요. 기본적으로 incremental_backups는 false로 설정되는데, 각 데이터 플러시마다 새 SSTable 파일 집합이 생성되고 여러 CQL 문을 실행하면 backups 디렉터리가 빠르게 채워져 테이블 데이터 저장에 필요한 저장 공간을 사용할 수 있기 때문입니다. 증분 백업은 명령줄에서 nodetool enablebackup 명령으로도 활성화할 수 있어요. 증분 백업은 nodetool disablebackup 명령으로 비활성화할 수 있고, 활성화 여부는 nodetool statusbackup으로 확인할 수 있습니다.
증분 백업 만들기
각 테이블을 만든 뒤 nodetool flush 명령으로 테이블 데이터를 플러시합니다. 증분 백업이 생성됩니다.
$ nodetool flush cqlkeyspace t
$ nodetool flush cqlkeyspace t2
$ nodetool flush catalogkeyspace journal magazine
증분 백업 찾기
증분 백업은 Cassandra의 데이터 디렉터리 안의 테이블 디렉터리 내에 생성됩니다. 백업은 다음 명령으로 찾을 수 있어요.
$ find -name backups
결과:
./cassandra/data/data/cqlkeyspace/t-d132e240c21711e9bbee19821dcea330/backups
./cassandra/data/data/cqlkeyspace/t2-d993a390c22911e9b1350d927649052c/backups
./cassandra/data/data/catalogkeyspace/journal-296a2d30c22a11e9b1350d927649052c/backups
./cassandra/data/data/catalogkeyspace/magazine-446eae30c22a11e9b1350d927649052c/backups
증분 백업 만들기(상세)
이 섹션에서는 이전에 만든 키스페이스와 테이블을 사용해 증분 백업이 어떻게 생성되는지 더 자세히 논의합니다.
키스페이스와 테이블을 플러시합니다:
$ nodetool flush cqlkeyspace t
아직 테이블 데이터를 추가하지 않았더라도 backups 검색과 backups 디렉터리가 백업 디렉터리를 나열할 것입니다.
$ find -name backups
결과:
./cassandra/data/data/cqlkeyspace/t-d132e240c21711e9bbee19821dcea330/backups
backups 디렉터리를 확인하면 백업 파일도 없다는 것을 보여줍니다:
$ cd ./cassandra/data/data/cqlkeyspace/t-d132e240c21711e9bbee19821dcea330/backups && ls -l
결과:
total 0
데이터에 행을 추가하면 nodetool flush 명령을 실행해 테이블 데이터를 플러시하고 증분 백업이 생성됩니다:
$ nodetool flush cqlkeyspace t
$ cd ./cassandra/data/data/cqlkeyspace/t-d132e240c21711e9bbee19821dcea330/backups && ls -l
결과:
total 36
-rw-rw-r--. 2 ec2-user ec2-user 47 Aug 19 00:32 na-1-big-CompressionInfo.db
-rw-rw-r--. 2 ec2-user ec2-user 43 Aug 19 00:32 na-1-big-Data.db
-rw-rw-r--. 2 ec2-user ec2-user 10 Aug 19 00:32 na-1-big-Digest.crc32
-rw-rw-r--. 2 ec2-user ec2-user 16 Aug 19 00:32 na-1-big-Filter.db
-rw-rw-r--. 2 ec2-user ec2-user 8 Aug 19 00:32 na-1-big-Index.db
-rw-rw-r--. 2 ec2-user ec2-user 4673 Aug 19 00:32 na-1-big-Statistics.db
-rw-rw-r--. 2 ec2-user ec2-user 56 Aug 19 00:32 na-1-big-Summary.db
-rw-rw-r--. 2 ec2-user ec2-user 92 Aug 19 00:32 na-1-big-TOC.txt
예를 들어
cqlkeyspace/t같은 어떤 테이블의 backups 디렉터리도 그 테이블의 데이터 디렉터리에 생성됩니다.
또 다른 데이터 행을 추가하고 플러시하면 또 다른 증분 백업 파일 집합이 생깁니다. SSTable 파일에는 타임스탬프가 찍혀 있어 첫 번째 증분 백업과 두 번째 백업을 구분합니다:
total 72
-rw-rw-r--. 2 ec2-user ec2-user 47 Aug 19 00:32 na-1-big-CompressionInfo.db
-rw-rw-r--. 2 ec2-user ec2-user 43 Aug 19 00:32 na-1-big-Data.db
-rw-rw-r--. 2 ec2-user ec2-user 10 Aug 19 00:32 na-1-big-Digest.crc32
-rw-rw-r--. 2 ec2-user ec2-user 16 Aug 19 00:32 na-1-big-Filter.db
-rw-rw-r--. 2 ec2-user ec2-user 8 Aug 19 00:32 na-1-big-Index.db
-rw-rw-r--. 2 ec2-user ec2-user 4673 Aug 19 00:32 na-1-big-Statistics.db
-rw-rw-r--. 2 ec2-user ec2-user 56 Aug 19 00:32 na-1-big-Summary.db
-rw-rw-r--. 2 ec2-user ec2-user 92 Aug 19 00:32 na-1-big-TOC.txt
-rw-rw-r--. 2 ec2-user ec2-user 47 Aug 19 00:35 na-2-big-CompressionInfo.db
-rw-rw-r--. 2 ec2-user ec2-user 41 Aug 19 00:35 na-2-big-Data.db
-rw-rw-r--. 2 ec2-user ec2-user 10 Aug 19 00:35 na-2-big-Digest.crc32
-rw-rw-r--. 2 ec2-user ec2-user 16 Aug 19 00:35 na-2-big-Filter.db
-rw-rw-r--. 2 ec2-user ec2-user 8 Aug 19 00:35 na-2-big-Index.db
-rw-rw-r--. 2 ec2-user ec2-user 4673 Aug 19 00:35 na-2-big-Statistics.db
-rw-rw-r--. 2 ec2-user ec2-user 56 Aug 19 00:35 na-2-big-Summary.db
-rw-rw-r--. 2 ec2-user ec2-user 92 Aug 19 00:35 na-2-big-TOC.txt
증분 백업과 스냅샷으로부터 복원
테이블이 삭제된 후 복원하는 두 가지 주요 도구/명령은:
- sstableloader
- nodetool refresh
스냅샷은 증분 백업과 본질적으로 같은 SSTable 파일 집합을 포함하며 몇 개의 추가 파일이 더 있습니다. 스냅샷은 CQL로 테이블을 만드는 스키마 DDL을 위한 schema.cql 파일을 포함합니다. 테이블 백업은 DDL을 포함하지 않으며, 증분 백업에서 복원할 때는 스냅샷에서 얻어야 합니다.
더 알아보기 (Learn more)
- nodetool snapshot
- sstableloader — SSTable 로딩으로 복원
- cassandra.yaml 설정 — auto_snapshot, incremental_backups 등