Cloudera Manager · Hive Metastore · Ranger · Hue 의 백엔드로 MariaDB 를 쓴다. 단일 인스턴스가 단일 장애점이니 Galera 로 다중 마스터를 구성하고 싶은데, 권장되지 않는다는 말을 듣는다. 이유가 "복잡해서" 정도로만 설명되면 판단하기 어렵다.
복잡도 문제가 아니라 Galera 의 동작 방식에서 오는 제약이다. 네 가지가 직접적이다.
모든 테이블에 기본키가 있어야 한다. Galera 는 행 기반 복제와 인증(certification)으로 노드 사이의 충돌을 판정하는데, 기본키 없는 테이블에서는 행을 특정할 수 없다. 기본키 없는 테이블에 대한 DELETE 는 지원되지 않고, 결과가 노드마다 달라질 수 있다. 하둡 생태계의 서비스 스키마에는 기본키 없는 테이블이 섞여 있다.
InnoDB 만 복제된다. MyISAM 테이블은 복제되지 않는다. 마이그레이션 과정에서 남은 MyISAM 테이블이 있으면 노드마다 내용이 달라진다.
SELECT table_schema, table_name, engine
FROM information_schema.tables
WHERE table_schema IN ('metastore','scm','ranger','hue')
AND engine <> 'InnoDB';
SELECT t.table_schema, t.table_name
FROM information_schema.tables t
LEFT JOIN information_schema.table_constraints c
ON c.table_schema = t.table_schema
AND c.table_name = t.table_name
AND c.constraint_type = 'PRIMARY KEY'
WHERE t.table_schema IN ('metastore','scm','ranger','hue')
AND c.constraint_name IS NULL;
커밋 시점 충돌이 애플리케이션 오류로 튄다. Galera 는 낙관적 잠금을 쓴다. 서로 다른 노드에서 같은 행을 건드리면 커밋 단계에서 한쪽이 거부되고, 클라이언트는 교착 상태 오류(SQLSTATE 40001)를 받는다. 이것을 정상 동작으로 보고 재시도하는 것이 Galera 사용법인데, Hive Metastore 같은 클라이언트는 그런 재시도를 전제로 만들어져 있지 않다. 여러 Metastore 인스턴스가 서로 다른 Galera 노드에 붙어 동시에 파티션을 추가하면 이 오류가 난다.
큰 트랜잭션이 막힌다. Galera 는 한 트랜잭션의 쓰기 집합 크기를 제한한다. 파티션을 수만 개 추가하는 작업처럼 큰 트랜잭션은 한계에 걸려 실패할 수 있다.
Cloudera 가 문서에 적어 둔 지원 데이터베이스 목록은 단일 인스턴스 MariaDB · MySQL · PostgreSQL · Oracle 이다. Galera 나 MySQL NDB Cluster 같은 다중 마스터 구성은 그 목록에 없다. 즉 문제가 났을 때 지원을 받기 어렵다. 이것은 기술적 제약과 별개로 운영상 무게가 있다.
목적이 "메타데이터 DB 가 죽어도 서비스가 멈추지 않게" 라면 다중 마스터가 아닌 방법을 쓴다.
비동기 또는 준동기 복제로 대기 노드를 두고, 장애 시 승격한다. 쓰기는 언제나 한 노드로만 간다.
[mariadb]
server_id = 1
log_bin = /var/lib/mysql/binlog
binlog_format = ROW
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
Galera 를 굳이 쓰겠다면 쓰기를 한 노드로 고정한다. 로드밸런서에서 한 노드만 활성으로 두고 나머지는 대기로 둔다. 이렇게 하면 인증 충돌이 나지 않아 위의 세 번째 문제가 사라진다. 실제 운영 사례에서 쓰이는 절충안이다. 다만 기본키와 스토리지 엔진 제약은 그대로 남는다.
PostgreSQL 로 가는 선택지도 있다. Patroni 기반 HA 구성이 성숙해 있고, 하둡 생태계의 서비스들도 PostgreSQL 을 정식 지원한다.
Galera 위에서 메타스토어를 돌릴 때 나타나는 전형적인 증상은 다음과 같다.
파티션 추가나 통계 갱신에서 간헐적으로 Deadlock found when trying to get lock 이 난다. 재실행하면 되는 경우가 많아 원인이 묻힌다.
노드 사이에 행 수가 어긋난다. 기본키 없는 테이블에서 생긴다.
한 노드가 재합류할 때 전체 상태 전송(SST)이 걸려 그동안 쓰기가 멈춘다.
이미 Galera 위에 올려 둔 상태라면, 먼저 위의 두 조회로 기본키 없는 테이블과 비 InnoDB 테이블을 찾아 놓는다. 이전 계획을 세울 때 그 목록이 출발점이 된다.
메타데이터 DB 의 백업은 이중화와 별개다. 어떤 구성이든 정기 논리 백업을 함께 둔다.