Remote·RemoteSecure 데이터베이스 엔진
Remote·RemoteSecure 데이터베이스 엔진
Remote와 RemoteSecure 데이터베이스 엔진은 네이티브 TCP 프로토콜로 원격 ClickHouse 서버의 데이터베이스 테이블에 실시간 접근을 제공해요. ClickHouse에서 ClickHouse로의 MySQL과 PostgreSQL 데이터베이스 엔진 대응물이에요.
출처: 문서
본문
Remote와 RemoteSecure 데이터베이스 엔진은 네이티브 TCP 프로토콜로 원격 ClickHouse 서버의 데이터베이스 테이블에 실시간 접근을 제공해요. 그것들은 MySQL과 PostgreSQL 데이터베이스 엔진의 ClickHouse-대-ClickHouse 대응물이에요. 테이블 목록과 구조는 필요할 때 원격 서버에서 가져오므로(내부적으로 SHOW TABLES와 DESCRIBE TABLE 사용), 데이터베이스는 항상 원격 서버의 현재 상태를 반영해요. 각 테이블은 제공된 주소들로 만들어진 ad-hoc 클러스터 위의 Distributed 스토리지로 노출되며, SELECT와 INSERT 쿼리를 원격 서버로 전달해요. 이것은 여러 ClickHouse 클러스터를 연합(federate)하거나 더 큰 ClickHouse 클러스터를 clickhouse-local이나 더 작은 클러스터에 연결할 때 유용해요.
데이터베이스 만들기 (Creating a database)
- Remote
- RemoteSecure
Remote는 포트가 생략되면 일반 TCP 포트(tcp_port, 기본 9000)로 연결해요.
CREATE DATABASE remote_db
ENGINE = Remote('addresses_expr', 'database'[, 'user'[, 'password']]);
RemoteSecure는 포트가 생략되면 보안 TCP 포트(tcp_port_secure, 기본 9440)를 사용하는 보안 TLS 연결로 연결해요.
CREATE DATABASE remote_db
ENGINE = RemoteSecure('addresses_expr', 'database'[, 'user'[, 'password']]);
엔진 매개변수 (Engine Parameters)
addresses_expr— 원격 서버 주소 또는host·host:port형태의 여러 주소를 생성하는 표현식. 주소 표현식은 remote 테이블 함수와 같은 glob 패턴을 지원해요(예:{a,b,c},{N..M},{a|b}로 여러 샤드·복제본으로 확장). 포트가 생략되면Remote는 일반 TCP 포트(tcp_port, 기본 9000)를,RemoteSecure는 보안 TCP 포트(tcp_port_secure, 기본 9440)를 사용해요.database— 원격 서버의 데이터베이스 이름.user— 원격 사용자 이름. 선택 사항, 기본값:default.password— 원격 사용자 비밀번호. 선택 사항, 기본값: 빈 값.
주소와 자격 증명은 데이터베이스 정의에 저장되므로 비밀번호는 SHOW CREATE DATABASE에서 숨겨져요. remote 테이블 함수처럼 현재 서버를 가리키는 주소는 로컬 샤드로 취급돼요. SELECT와 INSERT는 현재 사용자로 직접 실행되므로(따라서 그 사용자는 하부 데이터베이스와 그 테이블에 대한 해당 권한이 필요해요), 저장된 자격 증명은 진짜 원격 서버에만 사용돼요. 샤드의 로컬 복제본에 데이터베이스나 테이블이 없으면 Distributed 테이블처럼 샤드의 원격 복제본으로 조회가 폴백해요. 그 경우 SHOW CREATE TABLE은 구성된 주소 대신 실질적인 폴백 주소(해당 샤드에서 제거된 로컬 복제본)를 출력하므로, 방출된 Remote(...) 테이블 정의는 실제로 쿼리를 서비스하는 객체를 재구성해요.
주소 표현식이 여러 샤드를 설명하면 각 프록시 테이블은 그들 모두에서 읽지만, 메타데이터(테이블 목록과 구조)는 임의의 샤드(로컬이 선호됨)에서 가져와요. remote 테이블 함수처럼 목록화가 샤드당 하나 대신 단일 쿼리로 끝나게 하려는 것이에요. 따라서 클러스터의 샤드들은 같은 테이블 집합을 서비스할 것으로 기대돼요. 일부만 가진 테이블은, 그 테이블이 없는 샤드에서 쿼리가 실패하는 프록시로 서비스돼요. 다중 샤드 데이터베이스의 테이블에 대한 INSERT는 각 행을 임의의 샤드로 보내요(프록시 Distributed 테이블은 암시적 rand() 샤딩 키를 담아요). 쿼리의 샤드를 고정하려면 insert_shard_id를 설정해요. 암시적 키는 삽입된 행만 분산해요. 읽기에서는 테이블은 샤딩 키가 없는 Distributed 테이블처럼 동작해요(특히 optimize_skip_unused_shards와 force_optimize_skip_unused_shards는 그것을 샤드 가지치기 키로 취급하지 않아요). SHOW CREATE TABLE은 방출된 Remote(...) 테이블 정의에 키를 포함하므로, 그로부터 다시 만든 테이블도 다중 샤드 INSERT 쿼리를 받아들여요.
명명된 컬렉션도 지원돼요.
CREATE DATABASE remote_db
ENGINE = Remote(my_named_collection, database = 'default');
참고 (Notes)
- 이 엔진은 원격 서버의 읽기 통과(read-through) 뷰예요.
Remote데이터베이스에 대한CREATE TABLE,DROP TABLE,ALTER및 유사한 DDL 문은 지원되지 않아요. 원격 서버에서 스키마를 직접 관리해요. - 접근 권한은 구성된 원격 사용자에 대해 원격 서버에서, 로컬에서는 데이터베이스와 그 테이블에 대한 일반 권한으로 강제돼요.
- 사용자가 볼 권한이 없는 로컬 샤드의 테이블은 금지된 것보다 누락된 것으로 보고되므로,
Remote데이터베이스로 사용자가 권한이 없는 로컬 데이터베이스의 테이블 이름을 조사할 수 없어요. 이것은 목록화(SHOW TABLES,EXISTS TABLE)뿐 아니라 해석(DESCRIBE TABLE,SHOW CREATE TABLE,SELECT)에도 적용되고, 그런 테이블은 샤드의 원격 복제본을 통해서도 서비스되지 않아요. 위에서 설명한 폴백은 로컬 복제본이 정말 그 테이블이 없을 때만 작동해요. - 샤드의 로컬 복제본에 존재하는 데이터베이스의 테이블 목록화는 그 샤드의 원격 복제본만 가진 테이블도 포함하므로,
SHOW TABLES와system.tables가 그 복제본으로 폴백하는EXISTS TABLE,DESCRIBE TABLE,SELECT와 일치해요. 원격 복제본 어느 것도 응답하지 않으면 사용 가능한 복제본의 응답이 이미 있으므로 로컬 복제본의 목록이 그대로 반환돼요. - 원격 서버가 사용 불가하면 그 테이블 목록(
SHOW TABLES,system.tables)은 같은 데이터베이스의EXISTS TABLE과SELECT가 하는 것처럼 빈 목록 대신 연결 오류를 보고해요. 그런 데이터베이스에 도달할 수 없는 동안 모든 데이터베이스를 다루는system.tables의SELECT도 실패한다는 점을 유의하세요. Remote데이터베이스는 같은 서버의 다른Remote데이터베이스를 가리킬 수 있어요. 그런 체인의 테이블 목록화·설명에는 중간 데이터베이스의 권한이 필요 없어요. 그것은 자체 데이터나 메타데이터를 가지지 않고, 각 홉이 호출자의 권한을 차례로 프록시하는 객체들에 대해 이미 검사하니까요. 반대로 데이터 읽기·쓰기는 체인의 각 홉에서SELECT/INSERT가 필요해요. 쿼리가 정말 중간 데이터베이스의 테이블에 대해 실행되기 때문이에요(다른Distributed테이블 위의Distributed테이블과 정확히 같아요). 위에서 설명한 가시성 규칙은 체인을 넘어서 유지돼요. 중간 데이터베이스가 호출자에게 숨기는 테이블은 바깥 데이터베이스의 원격 복제본을 통해서도 서비스되지 않아요. 로컬 복제본의 중간 데이터베이스가 자신의 대상에 도달할 수 없으면 바깥 샤드의 로컬 복제본은 복제본 자체가 다운된 것처럼 전혀 응답할 수 없고, 바깥 데이터베이스는 샤드의 원격 복제본으로 폴백해요.
예시 (Example)
원격 서버의 system 데이터베이스를 가리키는 Remote 데이터베이스를 만들고 그것에서 읽어요.
CREATE DATABASE remote_system
ENGINE = Remote('127.0.0.1:9000', 'system', 'default', '');
SHOW TABLES FROM remote_system LIKE 'one';
┌─name─┐
│ one │
└──────┘
SELECT * FROM remote_system.one;
┌─dummy─┐
│ 0 │
└───────┘