기술적 분석|Flink CDC와 결합된 Doris Connector는 MySQL 하위 데이터베이스 및 하위 테이블에 대한 정확한 액세스를 달성하기 위해 Exactly Once

1. 개요

실제 비즈니스 시스템에서는 단일 테이블에 있는 많은 양의 데이터로 인해 발생하는 다양한 문제를 해결하기 위해 일반적으로 시스템의 처리량을 향상시키기 위해 데이터베이스 테이블을 하위 데이터베이스와 하위 테이블로 분할합니다.

그러나 이는 차후의 데이터 분석에 문제를 일으키며, 이때 우리는 일반적으로 비즈니스 데이터베이스의 하위 데이터베이스와 하위 테이블을 데이터 웨어하우스에 동기화하고 이러한 하위 데이터베이스와 하위 테이블의 데이터를 병합하려고 합니다. 하나의 데이터베이스와 하나의 테이블로 추후 데이터 분석에 편리합니다.

이 문서에서는 Apache Doris Flink Connector 및 Doris Stream Load 2단계 제출과 결합된 Flink CDC를 기반으로 MySQL 데이터베이스 하위 데이터베이스 및 하위 테이블용 Apache Doris 데이터 웨어하우스에 실시간으로 효율적으로 액세스하는 방법을 보여줍니다.

1.1 CDC란?

CDC는 Change Data Capture 变更数据获取( )의 줄임말입니다.

핵심 아이디어는 데이터베이스 변경 사항(데이터 또는 데이터 테이블의 INSERT, 업데이트 업데이트, DELETE 삭제 등 포함)을 모니터링 및 캡처하고, 이러한 변경 사항을 발생한 순서대로 완전히 기록하고, 다른 서비스를 위한 메시지 미들웨어에 쓰는 것입니다. 그리고 소비.

CDC 기술의 적용 시나리오는 다음을 포함하여 매우 광범위합니다.

데이터 배포 , 데이터 소스를 여러 다운스트림에 배포하며, 종종 비즈니스 분리 및 마이크로서비스에 사용됩니다.

데이터 통합 ​​, 흩어져 있는 이기종 데이터 소스를 데이터 웨어하우스로 통합하고 데이터 섬을 제거하고 후속 분석을 용이하게 합니다.

데이터 마이그레이션 , 일반적으로 데이터베이스 백업, 재해 복구 등에 사용됩니다.

1.2 Flink CDC를 선택하는 이유

데이터베이스 로그를 기반으로 한 Flink CDC의 Change Data Caputre 기술은 전체 및 증분 통합 읽기 기능을 구현합니다.Flink의 우수한 파이프라인 기능과 풍부한 업스트림 및 다운스트림 생태계의 도움으로 다양한 데이터베이스의 변경 사항 캡처를 지원하고 이러한 변경 사항을 다운스트림 스토리지에 동기화 실시간.

현재 Flink CDC의 업스트림은 이미 MySQL, MariaDB, PG, Oracle, MongoDB, Oceanbase, TiDB, SQLServer 및 기타 데이터베이스를 지원합니다.

Flink CDC의 다운스트림은 보다 풍부하며 Kafka, Pulsar 메시지 큐, Hudi, Iceberg, Doris 등에 쓰기를 지원하고 다양한 데이터 웨어하우스 및 데이터 레이크에 쓰기를 지원합니다.

동시에 Flink SQL에서 기본적으로 지원하는 Changelog 메커니즘을 통해 CDC 데이터 처리를 매우 간단하게 만들 수 있습니다. 사용자는 SQL을 통해 전체 및 증분 데이터베이스 데이터의 정리, 확장 및 집계와 같은 작업을 수행할 수 있으므로 사용자 임계값이 크게 줄어듭니다. 또한 Flink DataStream API는 사용자가 사용자 정의 로직을 구현하는 코드를 작성할 수 있도록 지원하여 사용자에게 서비스를 심층적으로 사용자 정의할 수 있는 자유를 제공합니다.

Flink CDC 기술의 핵심은 실시간 일관성을 위해 테이블의 전체 데이터 및 증분 데이터의 동기화 및 처리를 지원하여 사용자가 각 테이블의 실시간 일관된 스냅샷을 쉽게 얻을 수 있도록 하는 것입니다. 예를 들어 테이블에 전체 과거 비즈니스 데이터가 있고 증분 비즈니스 데이터가 지속적으로 작성 및 업데이트됩니다. Flink CDC는 증분 업데이트 기록을 실시간으로 캡처하여 실시간으로 데이터베이스와 일치하는 스냅샷을 제공합니다.업데이트 기록인 경우 기존 데이터를 업데이트합니다. 레코드가 삽입되면 기존 데이터에 추가되며, 전체 프로세스 동안 Flink CDC는 일관성 보장, 즉 반복되거나 손실되지 않습니다.

FLink CDC에는 다음과 같은 장점이 있습니다.

  • Flink의 연산자와 SQL 모듈은 더 성숙하고 사용하기 쉽습니다.
  • Flink 작업은 운영자의 병렬 처리를 조정하여 처리 능력을 쉽게 확장할 수 있습니다.
  • Flink는 고급 상태 백엔드(상태 백엔드)를 지원하여 방대한 상태 데이터에 액세스할 수 있습니다.
  • Flink는 Source 및 Sink와 같은 더 많은 생태학적 지원을 제공합니다.
  • Flink는 더 큰 사용자 기반과 적극적인 지원 커뮤니티를 가지고 있어 문제를 더 쉽게 해결할 수 있습니다.

또한 Flink Table/SQL 모듈은 데이터베이스 테이블과 변경 레코드 스트림(CDC의 데이터 스트림 등)을 동일한 것의 양면으로 간주하므로 내부적으로 제공되는 Upsert 메시지 구조( +I새로운 값을 나타내는 -U, 값 을 나타내는 레코드 업데이트 전, 레코드 업데이트를 +U나타내는 마지막 값( -D삭제를 나타냄)은 Debezium et al.에 의해 생성된 변경 레코드와 일대일 대응할 수 있습니다.

1.3 아파치 도리스란?

Apache Doris는 최신 MPP 분석 데이터베이스 제품입니다. 1초 미만의 응답 시간으로 쿼리 결과를 얻을 수 있어 실시간 데이터 분석을 효과적으로 지원합니다. Apache Doris의 분산 아키텍처는 매우 간단하고 운영 및 유지 관리가 쉬우며 10PB 이상의 대용량 데이터 세트를 지원할 수 있습니다.

Apache Doris는 고정 이력 보고서, 실시간 데이터 분석, 대화형 데이터 분석 및 탐색적 데이터 분석과 같은 다양한 데이터 분석 요구 사항을 충족할 수 있습니다. 데이터 분석 작업을 더 쉽고 효율적으로 만드십시오!

1.4 2단계 커밋

1.4.1 2단계 커밋(2PC)이란?

분산 시스템에서 각 노드가 다른 노드의 트랜잭션 실행 상태를 인지할 수 있도록 중앙 노드를 도입하여 모든 노드의 실행 로직을 균일하게 처리할 필요가 있습니다. 중앙 노드 다른 비즈니스 노드를 참가자라고 합니다.

2PC는 분산 트랜잭션을 커밋 요청(투표)과 커밋(실행)의 두 단계로 나눕니다. Coordinator는 참여자의 응답에 따라 실제 거래의 실행 여부를 결정하며, 구체적인 절차는 다음과 같습니다.

요청(투표) 단계 제출

  1. 코디네이터는 트랜잭션 내용이 포함된 준비 요청을 모든 참가자에게 보내고 트랜잭션이 커밋을 위해 준비될 수 있는지 묻고 참가자의 응답을 기다립니다.
  2. 액터는 트랜잭션 및 로그 실행 취소(롤백용) 및 다시 실행(재생용)에 포함된 작업을 수행하지만 실제로 커밋하지는 않습니다.
  3. 참여자는 트랜잭션 작업의 실행 결과를 코디네이터에게 반환하고, 실행이 성공하면 yes를 반환하고, 그렇지 않으면 no를 반환합니다.

커밋(실행) 단계

성공과 실패에는 두 가지 유형이 있습니다.

  • 모든 참가자가 yes를 반환하면 트랜잭션을 커밋할 수 있습니다.
  1. 코디네이터는 모든 참가자에게 커밋 요청을 보냅니다.
  2. 참여자가 커밋 요청을 받은 후 트랜잭션이 실제로 커밋되고 점유된 트랜잭션 리소스가 해제되고 ack가 코디네이터에게 반환됩니다.
  3. 코디네이터는 모든 참가자로부터 ack 메시지를 수신하고 트랜잭션이 성공적으로 완료됩니다.
  • 참가자가 아니오를 반환하거나 시간 초과가 실패하면 트랜잭션이 중단되고 롤백해야 합니다.
  1. 코디네이터는 모든 참가자에게 롤백 요청을 보냅니다.
  2. 참가자는 롤백 요청을 받은 후 undo 로그에 따라 트랜잭션 실행 전 상태로 롤백하고 점유한 트랜잭션 리소스를 해제하고 ack를 코디네이터에게 반환합니다.
  3. 코디네이터는 모든 참가자로부터 ack 메시지를 수신하고 트랜잭션 롤백이 완료됩니다.

1.4 플링크 2PC

스트림 처리 엔진으로서 Flink는 자연스럽게 정확히 한 번 의미론을 보장합니다. 정확히 한 번 의미론은 입력, 처리 논리 및 출력의 시너지 효과의 결과입니다. Flink는 체크포인트 메커니즘과 경량 분산 스냅샷 알고리즘 ABS를 사용하여 정확히 한 번만 보장합니다. 정확히 한 번 출력 논리를 달성하려면 멱등성 쓰기, 트랜잭션 쓰기의 두 가지 제한 중 하나를 적용해야 합니다.

사전 커밋 단계의 프로세스

그림

체크포인트를 수행해야 할 때마다 JobManager는 체크포인트의 경계로 데이터 흐름의 장벽(장벽)을 입력합니다. 장벽은 오퍼레이터 체인을 따라 다운스트림으로 전달되고 오퍼레이터에 도달할 때마다 상태 백엔드에 상태 스냅샷을 작성하는 작업이 트리거됩니다. 장벽이 Kafka 싱크에 도달하면 메시지 데이터가 KafkaProducer.flush() 메서드를 통해 플러시되지만 아직 실제로 커밋되지는 않았습니다. 다음으로 체크포인트를 통해 커밋 단계를 트리거해야 합니다.

제출 단계 프로세스

그림

모든 체크포인트가 성공적으로 완료된 경우에만 쓰기가 성공합니다. 이것은 위에서 설명한 2PC 프로세스와 일치합니다. 여기서 JobManager는 조정자이고 각 운영자는 참가자입니다(단, 싱크 참가자만 제출을 수행합니다). 체크포인트가 실패하면 notifyCheckpointComplete() 메서드가 실행되지 않습니다. 재시도가 실패하면 abort() 메서드가 결국 호출되어 트랜잭션을 롤백합니다.

1.5 도리스 스트림 로드 2PC

1.5.1 스트림 로드

스트림 로드는 Apache Doris에서 제공하는 동기식 가져오기 방식으로 사용자는 HTTP 프로토콜을 전송하여 로컬 파일 또는 데이터 스트림을 Doris로 가져오도록 요청합니다. 스트림 로드는 가져오기를 동기적으로 수행하고 가져오기 결과를 반환합니다. 사용자는 요청의 반환 본문을 통해 가져오기 성공 여부를 직접 판단할 수 있습니다.

스트림 로드는 주로 로컬 파일을 가져오거나 프로그램을 통해 데이터 스트림의 데이터를 가져오는 데 적합합니다.

메서드를 사용하여 사용자는 Http Client를 통해 작업하거나 Curl 명령을 사용할 수 있습니다.

curl --location-trusted -u user:passwd [-H ""...] -T data.file -H "label:label" -XPUT http://fe_host:http_port/api/{db}/{table}/_stream_load

사용자가 동일한 데이터를 반복적으로 가져오는 것을 방지하기 위해 가져오기 작업의 레이블이 여기에 사용됩니다. 사용자는 동일한 데이터 배치에 대해 동일한 레이블을 사용하는 것이 좋습니다. 이러한 방식으로 동일한 데이터 배치에 대한 반복 요청은 한 번만 수락되어 At-Most-Once가 보장됩니다.

1.5.2 스트림 로드 2PC

Aapche Doris의 초기 Stream Load는 2단계 제출이 없으며 데이터 가져오기 시 Stream Load의 http 인터페이스를 통해 데이터 가져오기가 직접 완료되며 성공과 실패만 있습니다.

  1. 이것은 정상적인 상황에서는 문제가 되지 않습니다.분산 환경에서는 특정 가져오기 작업이 실패하여 양쪽 끝의 데이터가 일치하지 않을 수 있습니다.특히 Doris Flink Connector의 경우 Doris Flink Connector의 이전 데이터 가져오기 실패가 필요합니다. 사용자가 직접 제어하고 예외 처리하며, 예를 들어 가져오기가 실패할 경우 데이터를 지정된 위치(예: Kafka)에 저장한 다음 수동으로 처리합니다.
  2. Flink 작업이 다른 문제로 인해 갑자기 중단되면 일부 데이터는 성공하고 일부 데이터는 실패하며, 실패한 데이터에는 체크포인트가 없으므로 작업을 다시 시작해도 실패한 데이터를 다시 사용할 수 없어 양쪽 끝.

위의 문제를 해결하고 양쪽 끝에서 데이터 일관성을 보장하기 위해 Doris Stream Load 2PC를 구현했으며 원칙은 다음과 같습니다.

  1. 두 단계로 커밋
  2. 첫 번째 단계에서는 데이터 쓰기 작업이 제출되는데, 이때 데이터 쓰기 성공 후 데이터 상태는 보이지 않고 트랜잭션 상태는 PRECOMMITTED입니다.
  3. 데이터가 성공적으로 기록된 후 사용자는 Commit 작업을 트리거하여 트랜잭션 상태를 VISIBLE로 변경합니다. 이때 데이터를 쿼리할 수 있습니다.
  4. 사용자가 이 데이터 배치를 사용하려면 트랜잭션 ID를 사용하여 트랜잭션에 대한 중단 작업을 트리거하기만 하면 되며 이 데이터 배치는 자동으로 삭제됩니다.

1.5.3 스트림로드 2PC 사용 방법

  1. be.conf에서 구성 disable_stream_load_2pc=false(적용하려면 다시 시작)
  2. HEADER 에 선언되었습니다 two_phase_commit=true.

사전 커밋을 시작하려면:

curl  --location-trusted -u user:passwd -H "two_phase_commit:true" -T test.txt http://fe_host:http_port/api/{db}/{table}/_stream_load

트랜잭션 커밋 작업 트리거

curl -X PUT --location-trusted -u user:passwd  -H "txn_id:18036" -H "txn_operation:commit"  http://fe_host:http_port/api/{db}/_stream_load_2pc

사물에 대한 중단 조치 트리거

curl -X PUT --location-trusted -u user:passwd  -H "txn_id:18037" -H "txn_operation:abort"  http://fe_host:http_port/api/{db}/_stream_load_2pc

1.6 도리스 플링크 커넥터 2PC

우리는 이전에 Doris 테이블 데이터의 읽기, Upsert, 삭제(고유 키 모델)를 지원하는 Doris Flink Connector를 제공했지만 Job 실패 또는 기타 비정상적인 조건으로 인해 양쪽 끝의 데이터가 일치하지 않을 수 있는 문제가 있습니다.

이러한 문제를 해결하기 위해 FLink 2PC와 Doris Stream Load 2PC를 기반으로 Doris Connector를 수정 및 업그레이드하여 양쪽 끝이 정확히 한 번이 되도록 했습니다.

  1. 우리는 메모리에 읽기 및 쓰기 버퍼를 유지합니다. 시작 시 쓰기를 시작하고 비동기식으로 제출합니다. 이 기간 동안 http 청크를 통해 계속 BE에 데이터를 쓰고 체크포인트까지 쓰기를 중지합니다. 이것의 장점은 사용자의 잦은 http 제출로 인한 오버헤드를 방지하고 체크포인트가 완료되면 다음 단계의 쓰기가 시작됩니다.
  2. 이 Checkpoint 동안 테이블의 데이터를 동시에 쓰는 여러 작업이 있을 수 있습니다. 이 Checkpoint 동안 우리는 모두 글로벌 레이블에 해당하고, 체크포인트 동안 이 레이블에 해당하는 데이터를 쓰는 트랜잭션을 통합합니다. 데이터 상태 표시,
  3. 실패하면 Flink가 다시 시작될 때 체크포인트를 통해 데이터를 재생합니다.
  4. 이것은 Doris의 양쪽 끝에서 데이터의 일관성을 보장합니다.

2. 시스템 아키텍처

MySQL 하위 데이터베이스 및 하위 테이블의 실시간 수집 및 저장을 실현하기 위해 최신 버전의 Doris Flink Connector(2단계 제출 지원)를 통해 Flink CDC를 통합하는 방법을 완전한 예를 들어 살펴보겠습니다.

그림

  1. 여기서는 Flink CDC를 사용하여 MySQL 하위 데이터베이스 및 하위 테이블의 데이터 수집을 완료합니다.
  2. 그런 다음 Doris Flink Connector를 통해 데이터 저장을 완료하십시오.
  3. 마지막으로 Doris의 고동시성, 고성능 OLAP 분석 및 컴퓨팅 기능을 사용하여 외부 데이터 서비스 제공

3. MySQL 설치 구성

3.1 MySQL 설치

Docker를 사용하여 Mysql을 빠르게 설치 및 구성합니다. 자세한 내용은 다음 연결을 참조하십시오.

https://segmentfault.com/a/1190000021523570

3.2 MySQL binlog 열기

Docker 컨테이너를 입력하여 /etc/my.cnf 파일을 수정하고 [mysqld] 아래에 다음을 추가합니다.

log_bin=mysql_bin
binlog-format=Row
server-id=1

그런 다음 MySQL을 다시 시작하십시오.

systemctl restart mysqld

3.3 데이터 준비

여기에서 우리는 emp_1과 emp_2라는 두 개의 데이터베이스를 준비했으며 두 개의 테이블 employee_1과Employees_2가 각 데이터베이스에서 활성 및 대기 상태임을 보여줍니다. 초기화 데이터 제공

CREATE DATABASE emp_1;
 USE emp_1;
CREATE TABLE employees_1 (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
);
INSERT INTO `employees_1` VALUES (10001,'1953-09-02','Georgi','Facello','M','1986-06-26'),
(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21'),
(10003,'1959-12-03','Parto','Bamford','M','1986-08-28'),
(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01'),
(10005,'1955-01-21','Kyoichi','Maliniak','M','1989-09-12'),
(10006,'1953-04-20','Anneke','Preusig','F','1989-06-02'),
(10007,'1957-05-23','Tzvetan','Zielinski','F','1989-02-10'),
(10008,'1958-02-19','Saniya','Kalloufi','M','1994-09-15'),
(10009,'1952-04-19','Sumant','Peac','F','1985-02-18'),
(10010,'1963-06-01','Duangkaew','Piveteau','F','1989-08-24'),
(10011,'1953-11-07','Mary','Sluis','F','1990-01-22'),
(10012,'1960-10-04','Patricio','Bridgland','M','1992-12-18'),
(10013,'1963-06-07','Eberhardt','Terkki','M','1985-10-20'),
(10014,'1956-02-12','Berni','Genin','M','1987-03-11'),
(10015,'1959-08-19','Guoxiang','Nooteboom','M','1987-07-02'),
(10016,'1961-05-02','Kazuhito','Cappelletti','M','1995-01-27'),
(10017,'1958-07-06','Cristinel','Bouloucos','F','1993-08-03'),
(10018,'1954-06-19','Kazuhide','Peha','F','1987-04-03'),
(10019,'1953-01-23','Lillian','Haddadi','M','1999-04-30'),
(10020,'1952-12-24','Mayuko','Warwick','M','1991-01-26'),
(10021,'1960-02-20','Ramzi','Erde','M','1988-02-10'),
(10022,'1952-07-08','Shahaf','Famili','M','1995-08-22'),
(10023,'1953-09-29','Bojan','Montemayor','F','1989-12-17'),
(10024,'1958-09-05','Suzette','Pettey','F','1997-05-19'),
(10025,'1958-10-31','Prasadram','Heyers','M','1987-08-17'),
(10026,'1953-04-03','Yongqiao','Berztiss','M','1995-03-20'),
(10027,'1962-07-10','Divier','Reistad','F','1989-07-07'),
(10028,'1963-11-26','Domenick','Tempesti','M','1991-10-22'),
(10029,'1956-12-13','Otmar','Herbst','M','1985-11-20'),
(10030,'1958-07-14','Elvis','Demeyer','M','1994-02-17'),
(10031,'1959-01-27','Karsten','Joslin','M','1991-09-01'),
(10032,'1960-08-09','Jeong','Reistad','F','1990-06-20'),
(10033,'1956-11-14','Arif','Merlo','M','1987-03-18'),
(10034,'1962-12-29','Bader','Swan','M','1988-09-21'),
(10035,'1953-02-08','Alain','Chappelet','M','1988-09-05'),
(10036,'1959-08-10','Adamantios','Portugali','M','1992-01-03');
CREATE TABLE employees_2 (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
);
INSERT INTO `employees_2` VALUES (10037,'1963-07-22','Pradeep','Makrucki','M','1990-12-05'),
(10038,'1960-07-20','Huan','Lortz','M','1989-09-20'),
(10039,'1959-10-01','Alejandro','Brender','M','1988-01-19'),
(10040,'1959-09-13','Weiyi','Meriste','F','1993-02-14'),
(10041,'1959-08-27','Uri','Lenart','F','1989-11-12'),
(10042,'1956-02-26','Magy','Stamatiou','F','1993-03-21'),
(10043,'1960-09-19','Yishay','Tzvieli','M','1990-10-20'),
(10044,'1961-09-21','Mingsen','Casley','F','1994-05-21'),
(10045,'1957-08-14','Moss','Shanbhogue','M','1989-09-02'),
(10046,'1960-07-23','Lucien','Rosenbaum','M','1992-06-20'),
(10047,'1952-06-29','Zvonko','Nyanchama','M','1989-03-31'),
(10048,'1963-07-11','Florian','Syrotiuk','M','1985-02-24'),
(10049,'1961-04-24','Basil','Tramer','F','1992-05-04'),
(10050,'1958-05-21','Yinghua','Dredge','M','1990-12-25'),
(10051,'1953-07-28','Hidefumi','Caine','M','1992-10-15'),
(10052,'1961-02-26','Heping','Nitsch','M','1988-05-21'),
(10053,'1954-09-13','Sanjiv','Zschoche','F','1986-02-04'),
(10054,'1957-04-04','Mayumi','Schueller','M','1995-03-13');
CREATE DATABASE emp_2;
USE emp_2;
CREATE TABLE employees_1 (
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
);
INSERT INTO `employees_1` VALUES  (10055,'1956-06-06','Georgy','Dredge','M','1992-04-27'),
(10056,'1961-09-01','Brendon','Bernini','F','1990-02-01'),
(10057,'1954-05-30','Ebbe','Callaway','F','1992-01-15'),
(10058,'1954-10-01','Berhard','McFarlin','M','1987-04-13'),
(10059,'1953-09-19','Alejandro','McAlpine','F','1991-06-26'),
(10060,'1961-10-15','Breannda','Billingsley','M','1987-11-02'),
(10061,'1962-10-19','Tse','Herber','M','1985-09-17'),
(10062,'1961-11-02','Anoosh','Peyn','M','1991-08-30'),
(10063,'1952-08-06','Gino','Leonhardt','F','1989-04-08'),
(10064,'1959-04-07','Udi','Jansch','M','1985-11-20'),
(10065,'1963-04-14','Satosi','Awdeh','M','1988-05-18'),
(10066,'1952-11-13','Kwee','Schusler','M','1986-02-26'),
(10067,'1953-01-07','Claudi','Stavenow','M','1987-03-04'),
(10068,'1962-11-26','Charlene','Brattka','M','1987-08-07'),
(10069,'1960-09-06','Margareta','Bierman','F','1989-11-05'),
(10070,'1955-08-20','Reuven','Garigliano','M','1985-10-14'),
(10071,'1958-01-21','Hisao','Lipner','M','1987-10-01'),
(10072,'1952-05-15','Hironoby','Sidou','F','1988-07-21'),
(10073,'1954-02-23','Shir','McClurg','M','1991-12-01'),
(10074,'1955-08-28','Mokhtar','Bernatsky','F','1990-08-13'),
(10075,'1960-03-09','Gao','Dolinsky','F','1987-03-19'),
(10076,'1952-06-13','Erez','Ritzmann','F','1985-07-09'),
(10077,'1964-04-18','Mona','Azuma','M','1990-03-02'),
(10078,'1959-12-25','Danel','Mondadori','F','1987-05-26'),
(10079,'1961-10-05','Kshitij','Gils','F','1986-03-27'),
(10080,'1957-12-03','Premal','Baek','M','1985-11-19'),
(10081,'1960-12-17','Zhongwei','Rosen','M','1986-10-30'),
(10082,'1963-09-09','Parviz','Lortz','M','1990-01-03'),
(10083,'1959-07-23','Vishv','Zockler','M','1987-03-31'),
(10084,'1960-05-25','Tuval','Kalloufi','M','1995-12-15');
CREATE TABLE employees_2(
    emp_no      INT             NOT NULL,
    birth_date  DATE            NOT NULL,
    first_name  VARCHAR(14)     NOT NULL,
    last_name   VARCHAR(16)     NOT NULL,
    gender      ENUM ('M','F')  NOT NULL,    
    hire_date   DATE            NOT NULL,
    PRIMARY KEY (emp_no)
);
INSERT INTO `employees_2` VALUES (10085,'1962-11-07','Kenroku','Malabarba','M','1994-04-09'),
(10086,'1962-11-19','Somnath','Foote','M','1990-02-16'),
(10087,'1959-07-23','Xinglin','Eugenio','F','1986-09-08'),
(10088,'1954-02-25','Jungsoon','Syrzycki','F','1988-09-02'),
(10089,'1963-03-21','Sudharsan','Flasterstein','F','1986-08-12'),
(10090,'1961-05-30','Kendra','Hofting','M','1986-03-14'),
(10091,'1955-10-04','Amabile','Gomatam','M','1992-11-18'),
(10092,'1964-10-18','Valdiodio','Niizuma','F','1989-09-22'),
(10093,'1964-06-11','Sailaja','Desikan','M','1996-11-05'),
(10094,'1957-05-25','Arumugam','Ossenbruggen','F','1987-04-18'),
(10095,'1965-01-03','Hilari','Morton','M','1986-07-15'),
(10096,'1954-09-16','Jayson','Mandell','M','1990-01-14'),
(10097,'1952-02-27','Remzi','Waschkowski','M','1990-09-15'),
(10098,'1961-09-23','Sreekrishna','Servieres','F','1985-05-13'),
(10099,'1956-05-25','Valter','Sullins','F','1988-10-18'),
(10100,'1953-04-21','Hironobu','Haraldson','F','1987-09-21'),
(10101,'1952-04-15','Perla','Heyers','F','1992-12-28'),
(10102,'1959-11-04','Paraskevi','Luby','F','1994-01-26'),
(10103,'1953-11-26','Akemi','Birch','M','1986-12-02'),
(10104,'1961-11-19','Xinyu','Warwick','M','1987-04-16'),
(10105,'1962-02-05','Hironoby','Piveteau','M','1999-03-23'),
(10106,'1952-08-29','Eben','Aingworth','M','1990-12-19'),
(10107,'1956-06-13','Dung','Baca','F','1994-03-22'),
(10108,'1952-04-07','Lunjin','Giveon','M','1986-10-02'),
(10109,'1958-11-25','Mariusz','Prampolini','F','1993-06-16'),
(10110,'1957-03-07','Xuejia','Ullian','F','1986-08-22'),
(10111,'1963-08-29','Hugo','Rosis','F','1988-06-19'),
(10112,'1963-08-13','Yuichiro','Swick','F','1985-10-08'),
(10113,'1963-11-13','Jaewon','Syrzycki','M','1989-12-24'),
(10114,'1957-02-16','Munir','Demeyer','F','1992-07-17'),
(10115,'1964-12-25','Chikara','Rissland','M','1986-01-23'),
(10116,'1955-08-26','Dayanand','Czap','F','1985-05-28');

4. 도리스 설치 구성

여기에서는 독립 실행형 버전을 예로 들어보겠습니다.

먼저 Doris 1.1 릴리스 버전을 다운로드합니다.

https://doris.apache.org/downloads/downloads.html

지정된 디렉토리에 압축을 풉니다

tar zxvf apache-doris-1.1.0-bin.tar.gz -C doris-1.1

압축을 푼 디렉토리 구조는 다음과 같습니다.

.
├── apache_hdfs_broker
│   ├── bin
│   ├── conf
│   └── lib
├── be
│   ├── bin
│   ├── conf
│   ├── lib
│   ├── log
│   ├── minidump
│   ├── storage
│   └── www
├── derby.log
├── fe
│   ├── bin
│   ├── conf
│   ├── doris-meta
│   ├── lib
│   ├── log
│   ├── plugins
│   ├── spark-dpp
│   ├── temp_dir
│   └── webroot
└── udf
    ├── include
    └── lib

fe 및 be를 구성하십시오

cd doris-1.0
# 配置 fe.conf 和 be.conf,这两个文件分别在fe和be的conf目录下
打开这个 priority_networks
修改成自己的IP地址,注意这里是CIDR方式配置IP地址
例如我本地的IP是172.19.0.12,我的配置如下:
priority_networks = 172.19.0.0/24
######
在be.conf配置文件最后加上下面这个配置
disable_stream_load_2pc=false

  1. fe.conf기본적 be.conf으로 위와 동일한 구성만 수정하면 됩니다.
  2. 기본 fe 메타데이터 디렉토리는 fe/doris-meta디렉토리
  3. be의 데이터는 be/storage디렉토리

FE 시작

sh fe/bin/start_fe.sh --daemon

시작하다

sh be/bin/start_be.sh --daemon

MySQL 명령줄은 FE에 연결됩니다.여기에 새로 설치된 Doris 클러스터의 기본 사용자는 root와 admin이며 암호는 비어 있습니다.

mysql -uroot -P9030 -h127.0.0.1
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 41
Server version: 5.7.37 Doris version trunk-440ad03
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show frontends;
+--------------------------------+-------------+-------------+----------+-----------+---------+----------+----------+------------+------+-------+-------------------+---------------------+----------+--------+---------------+------------------+
| Name                           | IP          | EditLogPort | HttpPort | QueryPort | RpcPort | Role     | IsMaster | ClusterId  | Join | Alive | ReplayedJournalId | LastHeartbeat       | IsHelper | ErrMsg | Version       | CurrentConnected |
+--------------------------------+-------------+-------------+----------+-----------+---------+----------+----------+------------+------+-------+-------------------+---------------------+----------+--------+---------------+------------------+
| 172.19.0.12_9010_1654681464955 | 172.19.0.12 | 9010        | 8030     | 9030      | 9020    | FOLLOWER | true     | 1690644599 | true | true  | 381106            | 2022-06-22 18:13:34 | true     |        | trunk-440ad03 | Yes              |
+--------------------------------+-------------+-------------+----------+-----------+---------+----------+----------+------------+------+-------+-------------------+---------------------+----------+--------+---------------+------------------+
1 row in set (0.01 sec)

클러스터에 BE 노드 추가

mysql>alter system add backend "172.19.0.12:9050";

다음은 자신의 IP 주소입니다.

BE 보기

mysql> show backends;
+-----------+-----------------+-------------+---------------+--------+----------+----------+---------------------+---------------------+-------+----------------------+-----------------------+-----------+------------------+---------------+---------------+---------+----------------+--------------------------+--------+---------------+-------------------------------------------------------------------------------------------------------------------------------+
| BackendId | Cluster         | IP          | HeartbeatPort | BePort | HttpPort | BrpcPort | LastStartTime       | LastHeartbeat       | Alive | SystemDecommissioned | ClusterDecommissioned | TabletNum | DataUsedCapacity | AvailCapacity | TotalCapacity | UsedPct | MaxDiskUsedPct | Tag                      | ErrMsg | Version       | Status                                                                                                                        |
+-----------+-----------------+-------------+---------------+--------+----------+----------+---------------------+---------------------+-------+----------------------+-----------------------+-----------+------------------+---------------+---------------+---------+----------------+--------------------------+--------+---------------+-------------------------------------------------------------------------------------------------------------------------------+
| 10002     | default_cluster | 172.19.0.12 | 9050          | 9060   | 8040     | 8060     | 2022-06-22 12:51:58 | 2022-06-22 18:15:34 | true  | false                | false                 | 4369      | 328.686 MB       | 144.083 GB    | 196.735 GB    | 26.76 % | 26.76 %        | {"location" : "default"} |        | trunk-440ad03 | {"lastSuccessReportTabletsTime":"2022-06-22 18:15:05","lastStreamLoadTime":-1,"isQueryDisabled":false,"isLoadDisabled":false} |
+-----------+-----------------+-------------+---------------+--------+----------+----------+---------------------+---------------------+-------+----------------------+-----------------------+-----------+------------------+---------------+---------------+---------+----------------+--------------------------+--------+---------------+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

Doris 독립 실행형 설치가 완료되었습니다.

5. Flink 설치 구성

5.1 Flink1.14.4 다운로드 및 설치

wget https://dlcdn.apache.org/flink/flink-1.14.4/flink-1.14.5-bin-scala_2.12.tgz
tar zxvf flink-1.14.4-bin-scala_2.12.tgz

그런 다음 Flink 설치 디렉터리의 lib 디렉터리에 다음 종속성을 복사해야 합니다.특정 종속 lib 파일은 다음과 같습니다.

wget https://jiafeng-1308700295.cos.ap-hongkong.myqcloud.com/flink-doris-connector-1.14_2.12-1.0.0-SNAPSHOT.jar
wget https://repo1.maven.org/maven2/com/ververica/flink-sql-connector-mysql-cdc/2.2.1/flink-sql-connector-mysql-cdc-2.2.1.jar

플링크 시작

bin/start-cluster.sh

시작 후 인터페이스는 다음과 같습니다.

그림

6. Doris에 데이터 동기화 시작

6.1 Doris 데이터베이스 및 테이블 생성

create database demo;
use demo;
CREATE TABLE all_employees_info (
    emp_no       int NOT NULL,
    birth_date   date,
    first_name   varchar(20),
    last_name    varchar(20),
    gender       char(2),
    hire_date    date,
    database_name varchar(50),
    table_name    varchar(200)
)
UNIQUE KEY(`emp_no`, `birth_date`)
DISTRIBUTED BY HASH(`birth_date`) BUCKETS 1
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);

6.2 Flink SQL 클라이언트 입력

 bin/sql-client.sh embedded 

그림

체크포인트 켜고 10초마다 체크포인트 실행

체크포인트는 기본적으로 활성화되어 있지 않으며 트랜잭션을 제출하려면 체크포인트를 활성화해야 합니다.

소스는 시작 시 전체 테이블을 스캔하고 기본 키에 따라 테이블을 여러 청크로 나눕니다. 그리고 증분 스냅샷 알고리즘을 사용하여 각 청크의 데이터를 하나씩 읽습니다. 작업은 주기적으로 체크포인트를 실행하여 완료된 청크를 기록합니다. 장애 조치가 발생하면 완료되지 않은 청크를 계속 읽으십시오. 모든 청크를 읽으면 이전에 얻은 Binlog 사이트에서 증분 변경 레코드를 읽습니다. Flink 작업은 계속해서 주기적으로 Checkpoint를 실행하고 Binlog 사이트를 기록하고, 작업이 장애 조치되면 이전에 기록된 Binlog 사이트에서 계속 처리하여 Exactly Once 의미를 실현합니다.

SET execution.checkpointing.interval = 10s;

참고: 이것은 데모이며 프로덕션 환경에서는 60초의 체크포인트 간격을 권장합니다.

6.3 MySQL CDC 테이블 생성

Flink SQL Client에서 다음 SQL 실행

CREATE TABLE employees_source (
    database_name STRING METADATA VIRTUAL,
    table_name STRING METADATA VIRTUAL,
    emp_no int NOT NULL,
    birth_date date,
    first_name STRING,
    last_name STRING,
    gender STRING,
    hire_date date,
    PRIMARY KEY (`emp_no`) NOT ENFORCED
  ) WITH (
    'connector' = 'mysql-cdc',
    'hostname' = 'localhost',
    'port' = '3306',
    'username' = 'root',
    'password' = 'MyNewPass4!',
    'database-name' = 'emp_[0-9]+',
    'table-name' = 'employees_[0-9]+'
  );

  1. 'database-name' = 'emp_[0-9]+': 다음은 정규식을 사용하여 동시에 여러 라이브러리를 연결하는 방법입니다.
  2. 'table-name' = 'employees_[0-9]+': 다음은 정규식을 사용하여 여러 테이블을 동시에 연결하는 방법입니다.

CDC 테이블을 쿼리하면 모든 것이 정상임을 나타내는 다음 데이터를 볼 수 있습니다.

select * from employees_source limit 10;

그림

6.4 도리스 싱크 테이블 생성

CREATE TABLE cdc_doris_sink (
    emp_no       int ,
    birth_date   STRING,
    first_name   STRING,
    last_name    STRING,
    gender       STRING,
    hire_date    STRING,
    database_name STRING,
    table_name    STRING
) 
WITH (
  'connector' = 'doris',
  'fenodes' = '172.19.0.12:8030',
  'table.identifier' = 'demo.all_employees_info',
  'username' = 'root',
  'password' = '',
  'sink.properties.two_phase_commit'='true',
  'sink.label-prefix'='doris_demo_emp_001'
);

매개변수 설명:

  1. connector : 커넥터가 doris임을 지정합니다.
  2. fenodes: Doris FE 노드 IP 주소 및 http 포트
  3. table.identifier : Doris에 해당하는 데이터베이스 및 테이블 이름
  4. 사용자 이름: 도리스 사용자 이름
  5. 비밀번호: 도리스 사용자 비밀번호
  6. sink.properties.two_phase_commit: 2단계 커밋 사용을 지정하여 스트림이 로드될 때 http 헤더에 추가되고 two_phase_commit:true그렇지 않으면 실패합니다.
  7. sink.label-prefix : 양쪽 끝에서 데이터 일관성을 보장하기 위해 2단계 제출 중에 추가해야 하는 매개변수입니다. 그렇지 않으면 실패합니다.
  8. 다른 매개변수는 공식 문서 https://doris.apache.org/zh-CN/docs/ecosystem/flink-doris-connector.html 을 참조하십시오.

현재 Doris 싱크 테이블을 조회할 데이터가 없습니다.

select * from cdc_doris_sink;

그림

6.5 Doris 테이블에 데이터 삽입

다음 SQL을 실행합니다.

insert into cdc_doris_sink (emp_no,birth_date,first_name,last_name,gender,hire_date,database_name,table_name) 
select emp_no,cast(birth_date as string) as birth_date ,first_name,last_name,gender,cast(hire_date as string) as hire_date ,database_name,table_name from employees_source;

그러면 Flink WEB UI에서 작업 실행 정보를 볼 수 있습니다.

그림

여기서 우리는 TaskManager의 로그 정보를 볼 수 있고 여기에서 2단계 제출이 사용되며 http 청크 방식을 통해 데이터가 지속적으로 BE 측으로 전송되는 것을 알 수 있습니다. 체크포인트 완료 후, 다음 과제 제출은 계속됩니다.

2022-06-22 19:04:01,350 INFO  io.debezium.relational.history.DatabaseHistoryMetrics        [] - Started database history recovery
2022-06-22 19:04:01,350 INFO  io.debezium.relational.history.DatabaseHistoryMetrics        [] - Finished database history recovery of 0 change(s) in 0 ms
2022-06-22 19:04:01,351 INFO  io.debezium.util.Threads                                     [] - Requested thread factory for connector MySqlConnector, id = mysql_binlog_source named = binlog-client
2022-06-22 19:04:01,352 INFO  io.debezium.connector.mysql.MySqlStreamingChangeEventSource  [] - Skip 0 events on streaming start
2022-06-22 19:04:01,352 INFO  io.debezium.connector.mysql.MySqlStreamingChangeEventSource  [] - Skip 0 rows on streaming start
2022-06-22 19:04:01,352 INFO  io.debezium.util.Threads                                     [] - Creating thread debezium-mysqlconnector-mysql_binlog_source-binlog-client
2022-06-22 19:04:01,374 INFO  io.debezium.util.Threads                                     [] - Creating thread debezium-mysqlconnector-mysql_binlog_source-binlog-client
2022-06-22 19:04:01,381 INFO  io.debezium.connector.mysql.MySqlStreamingChangeEventSource  [] - Connected to MySQL binlog at localhost:3306, starting at MySqlOffsetContext [sourceInfoSchema=Schema{io.debezium.connector.mysql.Source:STRUCT}, sourceInfo=SourceInfo [currentGtid=null, currentBinlogFilename=mysql_bin.000005, currentBinlogPosition=211725, currentRowNumber=0, serverId=0, sourceTime=null, threadId=-1, currentQuery=null, tableIds=[], databaseName=null], partition={server=mysql_binlog_source}, snapshotCompleted=false, transactionContext=TransactionContext [currentTransactionId=null, perTableEventCount={}, totalEventCount=0], restartGtidSet=null, currentGtidSet=null, restartBinlogFilename=mysql_bin.000005, restartBinlogPosition=211725, restartRowsToSkip=0, restartEventsToSkip=0, currentEventLengthInBytes=0, inTransaction=false, transactionId=null]
2022-06-22 19:04:01,381 INFO  io.debezium.util.Threads                                     [] - Creating thread debezium-mysqlconnector-mysql_binlog_source-binlog-client
2022-06-22 19:04:01,381 INFO  io.debezium.connector.mysql.MySqlStreamingChangeEventSource  [] - Waiting for keepalive thread to start
2022-06-22 19:04:01,497 INFO  io.debezium.connector.mysql.MySqlStreamingChangeEventSource  [] - Keepalive thread is running
2022-06-22 19:04:08,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:08,321 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6963,
    "Label": "doris_demo_001_0_1",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 634,
    "NumberLoadedRows": 634,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 35721,
    "LoadTimeMs": 9046,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9041,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:08,321 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:08,321 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_2
2022-06-22 19:04:08,321 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:08,325 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 1
2022-06-22 19:04:08,329 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6963] commit successfully."
}
2022-06-22 19:04:18,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:18,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6964,
    "Label": "doris_demo_001_0_2",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9988,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9983,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:18,310 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:18,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_3
2022-06-22 19:04:18,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:18,312 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 2
2022-06-22 19:04:18,317 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6964] commit successfully."
}
2022-06-22 19:04:28,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:28,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6965,
    "Label": "doris_demo_001_0_3",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9998,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9993,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:28,308 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:28,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_4
2022-06-22 19:04:28,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:28,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 3
2022-06-22 19:04:28,316 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6965] commit successfully."
}
2022-06-22 19:04:38,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6966,
    "Label": "doris_demo_001_0_4",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9999,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9994,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:38,308 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_5
2022-06-22 19:04:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:38,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 4
2022-06-22 19:04:38,317 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6966] commit successfully."
}
2022-06-22 19:04:48,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:48,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6967,
    "Label": "doris_demo_001_0_5",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 10000,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9996,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:48,310 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:48,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_6
2022-06-22 19:04:48,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:48,312 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 5
2022-06-22 19:04:48,317 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6967] commit successfully."
}
2022-06-22 19:04:58,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:04:58,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6968,
    "Label": "doris_demo_001_0_6",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9998,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9993,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:04:58,308 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:04:58,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_7
2022-06-22 19:04:58,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:04:58,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 6
2022-06-22 19:04:58,316 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6968] commit successfully."
}
2022-06-22 19:05:08,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:05:08,309 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6969,
    "Label": "doris_demo_001_0_7",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9999,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9995,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:05:08,309 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:05:08,309 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_8
2022-06-22 19:05:08,309 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:05:08,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 7
2022-06-22 19:05:08,316 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6969] commit successfully."
}
2022-06-22 19:05:18,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:05:18,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6970,
    "Label": "doris_demo_001_0_8",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9999,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9993,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:05:18,308 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:05:18,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_9
2022-06-22 19:05:18,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:05:18,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 8
2022-06-22 19:05:18,317 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6970] commit successfully."
}
2022-06-22 19:05:28,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:05:28,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6971,
    "Label": "doris_demo_001_0_9",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 10000,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9996,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:05:28,310 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:05:28,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_10
2022-06-22 19:05:28,310 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:05:28,315 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 9
2022-06-22 19:05:28,320 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6971] commit successfully."
}
2022-06-22 19:05:38,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:05:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6972,
    "Label": "doris_demo_001_0_10",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 0,
    "NumberLoadedRows": 0,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 0,
    "LoadTimeMs": 9998,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 9992,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:05:38,308 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:05:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_11
2022-06-22 19:05:38,308 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:05:38,311 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 10
2022-06-22 19:05:38,316 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6972] commit successfully."
}
2022-06-22 19:05:48,303 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load stopped.
2022-06-22 19:05:48,315 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - load Result {
    "TxnId": 6973,
    "Label": "doris_demo_001_0_11",
    "TwoPhaseCommit": "true",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 520,
    "NumberLoadedRows": 520,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 29293,
    "LoadTimeMs": 10005,
    "BeginTxnTimeMs": 0,
    "StreamLoadPutTimeMs": 0,
    "ReadDataTimeMs": 0,
    "WriteDataTimeMs": 10001,
    "CommitAndPublishTimeMs": 0
}
2022-06-22 19:05:48,315 INFO  org.apache.doris.flink.sink.writer.RecordBuffer              [] - start buffer data, read queue size 0, write queue size 3
2022-06-22 19:05:48,315 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - stream load started for doris_demo_001_0_12
2022-06-22 19:05:48,315 INFO  org.apache.doris.flink.sink.writer.DorisStreamLoad           [] - start execute load
2022-06-22 19:05:48,322 INFO  org.apache.flink.streaming.runtime.operators.sink.AbstractStreamingCommitterHandler [] - Committing the state for checkpoint 11
2022-06-22 19:05:48,327 INFO  org.apache.doris.flink.sink.committer.DorisCommitter         [] - load result {
    "status": "Success",
    "msg": "transaction [6973] commit successfully."
}

6.6 Doris 데이터 쿼리

여기에 636개의 데이터를 삽입했습니다.

mysql> select count(1) from  all_employees_info ;
+----------+
| count(1) |
+----------+
|      634 |
+----------+
1 row in set (0.01 sec)
mysql> select * from  all_employees_info limit 20;
+--------+------------+------------+-------------+--------+------------+---------------+-------------+
| emp_no | birth_date | first_name | last_name   | gender | hire_date  | database_name | table_name  |
+--------+------------+------------+-------------+--------+------------+---------------+-------------+
|  10001 | 1953-09-02 | Georgi     | Facello     | M      | 1986-06-26 | emp_1         | employees_1 |
|  10002 | 1964-06-02 | Bezalel    | Simmel      | F      | 1985-11-21 | emp_1         | employees_1 |
|  10003 | 1959-12-03 | Parto      | Bamford     | M      | 1986-08-28 | emp_1         | employees_1 |
|  10004 | 1954-05-01 | Chirstian  | Koblick     | M      | 1986-12-01 | emp_1         | employees_1 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak    | M      | 1989-09-12 | emp_1         | employees_1 |
|  10006 | 1953-04-20 | Anneke     | Preusig     | F      | 1989-06-02 | emp_1         | employees_1 |
|  10007 | 1957-05-23 | Tzvetan    | Zielinski   | F      | 1989-02-10 | emp_1         | employees_1 |
|  10008 | 1958-02-19 | Saniya     | Kalloufi    | M      | 1994-09-15 | emp_1         | employees_1 |
|  10009 | 1952-04-19 | Sumant     | Peac        | F      | 1985-02-18 | emp_1         | employees_1 |
|  10010 | 1963-06-01 | Duangkaew  | Piveteau    | F      | 1989-08-24 | emp_1         | employees_1 |
|  10011 | 1953-11-07 | Mary       | Sluis       | F      | 1990-01-22 | emp_1         | employees_1 |
|  10012 | 1960-10-04 | Patricio   | Bridgland   | M      | 1992-12-18 | emp_1         | employees_1 |
|  10013 | 1963-06-07 | Eberhardt  | Terkki      | M      | 1985-10-20 | emp_1         | employees_1 |
|  10014 | 1956-02-12 | Berni      | Genin       | M      | 1987-03-11 | emp_1         | employees_1 |
|  10015 | 1959-08-19 | Guoxiang   | Nooteboom   | M      | 1987-07-02 | emp_1         | employees_1 |
|  10016 | 1961-05-02 | Kazuhito   | Cappelletti | M      | 1995-01-27 | emp_1         | employees_1 |
|  10017 | 1958-07-06 | Cristinel  | Bouloucos   | F      | 1993-08-03 | emp_1         | employees_1 |
|  10018 | 1954-06-19 | Kazuhide   | Peha        | F      | 1987-04-03 | emp_1         | employees_1 |
|  10019 | 1953-01-23 | Lillian    | Haddadi     | M      | 1999-04-30 | emp_1         | employees_1 |
|  10020 | 1952-12-24 | Mayuko     | Warwick     | M      | 1991-01-26 | emp_1         | employees_1 |
+--------+------------+------------+-------------+--------+------------+---------------+-------------+
20 rows in set (0.00 sec)

6.7 테스트 삭제

mysql> use emp_2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_emp_2 |
+-----------------+
| employees_1     |
| employees_2     |
+-----------------+
2 rows in set (0.00 sec)
mysql> delete from employees_2 where emp_no in (12013,12014,12015);
Query OK, 3 rows affected (0.01 sec)

Doris 데이터 삭제 확인

mysql> select count(1) from  all_employees_info ;
+----------+
| count(1) |
+----------+
|      631 |
+----------+
1 row in set (0.01 sec)

7. 요약

이 질문은 주로 FLink CDC 하위 데이터베이스와 하위 테이블을 실시간으로 동기화하는 방법을 소개하고 최신 버전의 Apache Doris Flink Connector와 통합된 Flink 2PC 및 Doris Stream Load 2PC의 메커니즘, 통합 원리 및 사용 방법을 결합합니다.

도움이 되기를 바랍니다.

8. 관련 링크:

SelectDB 공식 웹사이트:

https://selectdb.com

아파치 도리스 공식 웹사이트:

http://doris.apache.org

아파치 도리스 Github:

https://github.com/apache/doris

Apache Doris 개발자 메일링 그룹:

[email protected]

이미지.png

{{o.name}}
{{m.name}}

рекомендация

отmy.oschina.net/u/5735652/blog/5555473