Kudu 에는 HBase 의 스냅샷 익스포트 같은 기본 백업 도구가 오래 없었다. 실무에서는 Impala 나 Spark 로 읽어 옮기는 방식을 쓴다. Kudu 1.12 이후에는 Spark 기반 백업·복원 잡(kudu-backup)이 제공되므로 버전이 맞으면 그쪽을 먼저 검토한다.
원본 테이블의 DDL 을 그대로 받아 대상 클러스터에서 만든다. 기본키와 파티션 구성을 손으로 옮기다 틀리는 사고를 막는다.
SHOW CREATE TABLE mydb.my_kudu_table;
impala-shell -i src-impalad:21050 -q "SHOW TABLES IN mydb" -B --quiet \
| while read -r t; do
impala-shell -i src-impalad:21050 -q "SHOW CREATE TABLE mydb.$t" -B --quiet
done > /tmp/kudu_ddl.sql
대상 클러스터에서 실행하기 전에 kudu.master_addresses 를 대상 주소로 바꾼다.
Parquet 을 거치는 방법. 원본에서 Parquet 으로 떨어뜨리고 distcp 로 옮긴 뒤 대상에서 적재한다. 대용량에 가장 무난하다.
CREATE TABLE stage_parquet STORED AS PARQUET
LOCATION '/staging/export/my_kudu_table'
AS SELECT * FROM mydb.my_kudu_table;
hadoop distcp -m 20 \
hdfs://src-nn:8020/staging/export/my_kudu_table \
hdfs://dst-nn:8020/staging/import/my_kudu_table
CREATE EXTERNAL TABLE stage_parquet_in (...)
STORED AS PARQUET
LOCATION '/staging/import/my_kudu_table';
UPSERT INTO mydb.my_kudu_table SELECT * FROM stage_parquet_in;
CSV 로 뽑는 방법. 소량이거나 다른 시스템으로 보낼 때만 쓴다. 타입 정보가 사라지고 NULL 과 빈 문자열이 구분되지 않는다.
impala-shell -i src-impalad:21050 \
-q "SELECT * FROM mydb.my_kudu_table" \
-B --output_delimiter=',' --print_header \
-o /tmp/my_kudu_table.csv
Spark 로 직접 옮기는 방법. 두 클러스터에 동시에 접근할 수 있으면 중간 저장 없이 옮긴다.
src = (spark.read.format("kudu")
.option("kudu.master", "src-master01:7051")
.option("kudu.table", "impala::mydb.my_kudu_table").load())
(src.write.format("kudu")
.option("kudu.master", "dst-master01:7051")
.option("kudu.table", "impala::mydb.my_kudu_table")
.mode("append").save())
impala-shell -i src-impalad:21050 -B --quiet \
-q "SHOW TABLES IN mydb" > /tmp/tables.txt
while read -r t; do
echo "[INFO] exporting $t"
impala-shell -i src-impalad:21050 -q \
"CREATE TABLE stg_${t} STORED AS PARQUET LOCATION '/staging/export/${t}' AS SELECT * FROM mydb.${t}"
done < /tmp/tables.txt
목록을 뽑을 때 grep kudu 같은 필터로 테이블을 고르는 방식은 이름에 의존해 부정확하다. Kudu 테이블만 골라내려면 각 테이블의 저장 형식을 확인한다.
impala-shell -i src-impalad:21050 -B --quiet \
-q "DESCRIBE FORMATTED mydb.${t}" | grep -i kudu
옮긴 뒤 건수와 표본을 대조한다. 기본키 기준 정렬로 비교하면 차이를 찾기 쉽다.
SELECT COUNT(*) FROM mydb.my_kudu_table;
SELECT MIN(id), MAX(id), COUNT(DISTINCT id) FROM mydb.my_kudu_table;
Impala 는 CSV 를 Kudu 테이블에 직접 넣지 못한다. 반드시 스테이징 테이블을 거쳐야 한다. 적재는 UPSERT 로 하면 재실행이 안전하다.