기사를 통해 Canal 데이터 동기화 기술을 시작할 수 있습니다~

비디오 튜토리얼 포털:

운하 미니멀리스트 소개: 운하 데이터 동기화 기술을 빠르게 시작할 수 있는 1시간~_哔哩哔哩_bilibili 운하 미니멀리스트 소개: 운하 데이터 동기화 기술을 빠르게 시작할 수 있는 1시간 ~ 포함 총 13개의 비디오 : 01. 수업 전 튜토리얼 및 사전 지식 포인트, 02. 운하 구성 요소 이해, 03. MySQL 마스터-슬레이브 복제 원리 등 더 재미있는 UP 마스터의 영상은 UP 계정을 주목해주세요. https://www.bilibili.com/video/BV1Uc411P7XN/?spm_id_from=333.337.search-card.all.click

1. 사전 지식 포인트

1.1 운하 발음

인기 도서: 운하

1.2 전제 지식 포인트

  • MySQL의 기본 동작

  • 자바 기초

  • 스프링부트

2. 운하 소개

2.1 역사적 배경

초기 알리바바는 항저우와 미국에 전산실을 배치했고, 전산실 간 동기화에 대한 업무상 요구사항이 있었다.초기 구현은 비즈니스 트리거를 기반으로 하여 그다지 편리하지 않았다.2010년에 점진적으로 대체되었다. 많은 수의 데이터베이스 증분 구독 및 소비 작업을 파생시킨 데이터베이스 로그 분석을 통해. 이런 맥락에서 카날이 나왔다.

2014년경 Tmall Double Eleven은 대규모 프로모션 활동을 위해 MySQL 데이터베이스의 높은 동시 읽기 및 쓰기 문제를 해결하기 위해 처음 도입되었습니다. 이후 알리 내에서 널리 사용되고 홍보됐으며 2017년 공식적으로 오픈소스화됐다.

Github: https://github.com/alibaba/canal

 

2.2 정의

Canal 구성 요소는 MySQL 데이터베이스 증분 로그 구문 분석을 기반으로 하는 구성 요소로 증분 데이터 구독 및 소비를 제공하고 다운스트림 소비자(예: Kafka, RocketMQ 등) 또는 스토리지(예: Elasticsearch, HBase, 등.).

일반 언어: Canal은 MySQL 데이터의 변경 사항을 감지한 다음 변경된 데이터를 구문 분석하고 변경된 데이터를 MQ로 보내거나 다른 데이터베이스와 동기화하고 추가 비즈니스 로직 처리를 기다립니다.

3. 운하의 작동 원리

3.1 MySQL 마스터-슬레이브 복제 원칙

 

  • MySQL 마스터는 데이터 변경 사항을 바이너리 로그 또는 줄여서 Binlog에 기록합니다.

  • MySQL 슬레이브는 마스터의 바이너리 로그를 자신의 릴레이 로그(릴레이 로그)에 복사

  • MySQL 슬레이브는 변경된 데이터를 최신으로 동기화하기 위해 릴레이 로그 작업을 재생합니다.

3.2 MySQL Binlog 로그

3.2.1 소개

MySQL의 Binlog는 MySQL의 가장 중요한 로그라고 할 수 있으며 모든 DDL 및 DML 문을 이벤트 형태로 기록합니다.

기본적으로 MySQL은 Binlog 로그를 기록하는 데 시간이 걸리고 공식 데이터에 따르면 1%의 성능 손실이 있기 때문에 Binlog를 활성화하지 않습니다.

활성화 여부는 개발 중 실제 상황에 따라 다릅니다.

일반적으로 Binlog 로그는 다음 두 가지 시나리오에서 활성화됩니다.

  • MySQL 마스터-슬레이브 클러스터가 배포되면 슬레이브에 대한 데이터 동기화를 용이하게 하기 위해 마스터 측에서 Binlog를 활성화해야 합니다.

  • 데이터가 복원되고 MySQL Binlog 도구를 사용하여 데이터가 복원됩니다.

3.2.1 Binlog 분류

MySQL Binlog에는 STATEMENT, MIXED, ROW의 세 가지 형식이 있습니다. 구성 파일에서 다음을 구성하도록 선택할 수 있습니다.

置 binlog_format= | 혼합 |

분류 소개하다 이점 결점
성명 문 수준에서 쓰기 작업을 수행하는 모든 문을 기록하므로 ROW 모드에 비해 공간이 절약되지만 update tt set create_date=now()와 같은 데이터 불일치가 발생할 수 있으며 배고픈 데이터는 실행 시간 공간 절약 데이터 불일치가 발생할 수 있음
행 수준은 각 작업 후 각 행 레코드의 변경 사항을 기록합니다. 갱신의 SQL 실행 결과가 10,000 행이고 ​​하나의 문장만 저장된다면 행이라면 10,000 행의 결과가 여기에 저장된다. 데이터의 절대적인 일관성을 유지합니다. 무슨 SQL이든 어떤 함수를 참조하든 실행 후의 효과만 기록하기 때문에 많은 공간을 차지
혼합 예를 들어 함수에 UUID()가 포함되어 있을 때, AUTO_INCREMENT 필드가 포함된 테이블이 업데이트될 때, INSERT DELAYED 문이 실행될 때, UDF를 사용할 때 ROW 방식으로 처리된다. 어느 정도의 일관성을 유지하면서 공간 절약 여전히 불일치가 발생하는 드문 경우가 있으며, 또한 binlog 모니터링이 필요한 상황에서는 statement와 mixed가 불편합니다.

위의 비교를 바탕으로 Canal은 모니터링 및 분석을 원하며 행 형식을 선택하는 것이 더 적합합니다.  

3.3 운하 작동 원리

  • Canal은 자신을 MySQL 슬레이브(슬레이브 라이브러리)로 위장하고 MySQL 마스터(메인 라이브러리)에 덤프 프로토콜을 보냅니다.

  • MySQL 마스터(메인 라이브러리)는 덤프 요청을 받고 바이너리 로그를 슬레이브(즉, 운하)로 푸시하기 시작합니다.

  • Canal은 Binlog 로그를 수신 및 구문 분석하고, 변경된 데이터를 획득하고, 후속 로직을 실행합니다.

 

4. 운하 적용 시나리오

4.1 데이터 동기화

Canal은 사용자가 MySQL 데이터를 Elasticsearch, Redis 및 기타 데이터 저장 매체에 실시간으로 동기화하는 것과 같은 다양한 데이터 동기화 작업을 수행하도록 도울 수 있습니다.

4.2 데이터베이스 실시간 모니터링

Canal은 MySQL의 업데이트 작업을 실시간으로 모니터링할 수 있으며 민감한 데이터가 수정된 경우 적시에 관련 담당자에게 알릴 수 있습니다.

4.3 데이터 분석 및 마이닝

Canal은 MySQL 증분 데이터를 Kafka와 같은 메시지 대기열에 게시하여 데이터 분석 및 마이닝을 위한 데이터 소스를 제공할 수 있습니다.

 

4.4 데이터베이스 백업

Canal은 MySQL 마스터 데이터베이스의 데이터 증분 로그를 대기 데이터베이스로 복사하여 데이터베이스 백업을 실현할 수 있습니다.

 

4.5 데이터 통합

Canal은 여러 MySQL 데이터베이스의 데이터를 통합하여 데이터 처리를 위한 보다 효율적이고 안정적인 솔루션을 제공할 수 있습니다.

4.6 데이터베이스 마이그레이션

Canal은 MySQL 데이터베이스 버전 업그레이드 및 데이터 마이그레이션 작업을 완료하는 데 도움을 줄 수 있습니다.

 

다섯째, MySQL 준비

5.1 데이터베이스 생성

새로운 라이브러리: canal-demo

 

5.2 테이블 생성

사용자 테이블

CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

5.3 Binlog 지원을 활성화하도록 구성 파일 수정

mysql의 구성 파일을 수정합니다. 이름은 my.ini 입니다.

server-id=1
log-bin=C:/ProgramData/MySQL/MySQL Server 8.0/binlogs/mysql-bin.log
binlog_format=row
binlog-do-db=canal-demo

server-id: 클러스터링 시 인스턴스 구분을 위해 사용되는 mysql 인스턴스 아이디

lob-bin: binlog 로그 파일 이름

binlog_format: binlog 로그 데이터 저장 형식

binlog-do-db: binlog 로그 데이터베이스를 활성화하도록 지정합니다.

참고: 일반적으로 동기화할 데이터베이스는 상황에 따라 지정하며, 설정하지 않으면 모든 데이터베이스에 Binlog가 활성화되어 있음을 의미합니다.

5.4 Binlog가 적용되는지 확인

MySQL 서비스를 다시 시작하고 Binlog 로그 보기

방법 1:

show  VARIABLES like 'log_bin'

 

방법 2:

지정된 디렉토리를 입력하십시오.

insert into user(name, age) values('dafei', 18);
insert into user(name, age) values('dafei', 18);
insert into user(name, age) values('dafei', 18);

 

 

6. 운하 설치 및 구성

6.1 다운로드

주소: Releases · alibaba/canal · GitHub

압축을 풀면 됩니다.

6.2 구성

6.2.1 canal.properties 구성 수정

canal.port = 11111
# tcp, kafka, rocketMQ, rabbitMQ, pulsarMQ
canal.serverMode = tcp

canal.destinations = example

canal.port: 기본 포트 11111

canal.serverMode: 서비스 모드, tcp는 입력 클라이언트, 다양한 메시지 미들웨어에 대한 xxMQ 출력을 의미합니다.

canal.destinations: Canal은 여러 MySQL 데이터베이스에서 데이터를 수집할 수 있으며 각 MySQL 데이터베이스에는 독립적인 구성 파일 컨트롤이 있습니다. 특정 구성 규칙: conf/ 디렉터리 아래에 배치할 폴더를 사용하고 폴더 이름은 MySQL 인스턴스를 나타냅니다. canal.destinations는 데이터를 모니터링해야 하는 데이터베이스를 구성하는 데 사용됩니다. 여러 개일 경우 구분하여 사용

6.2.2 MySQL 인스턴스 구성 파일 instance.properties 수정

구성/디렉토리

canal.instance.mysql.slaveId=20

# position info
canal.instance.master.address=127.0.0.1:3306

# username/password
canal.instance.dbUsername=root
canal.instance.dbPassword=admin

canal.instance.mysql.slaveId: 운하 슬레이브 스테이지 ID 사용

canal.instance.master.address: 데이터베이스 IP 포트

canal.instance.dbUsername: mysql 계정에 연결

canal.instance.dbPassword: mysql에 연결하기 위한 암호

6.3 시작

두 번 클릭하여 시작

 

7. 운하 프로그래밍

7.1 헬로월드

1>프로젝트 만들기: canal-hello

2> 관련 의존성 가져오기

<dependency>
    <groupId>com.alibaba.otter</groupId>
    <artifactId>canal.client</artifactId>
    <version>1.1.0</version>
</dependency>

3> 테스트 코드 작성

package com.langfeiyes.hello;

import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.Message;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CanalDemo {

    public static void main(String[] args) throws InvalidProtocolBufferException {
        //1.获取 canal 连接对象
        CanalConnector canalConnector = CanalConnectors.newSingleConnector(new InetSocketAddress("localhost", 11111), "example", "", "");
        while (true) {
            //2.获取连接
            canalConnector.connect();
            //3.指定要监控的数据库
            canalConnector.subscribe("canal-demo.*");
            //4.获取 Message
            Message message = canalConnector.get(100);
            List<CanalEntry.Entry> entries = message.getEntries();
            if (entries.size() <= 0) {
                System.out.println("没有数据,休息一会");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } else {
                for (CanalEntry.Entry entry : entries) {
                    // 获取表名
                    String tableName = entry.getHeader().getTableName();
                    //  Entry 类型
                    CanalEntry.EntryType entryType = entry.getEntryType();
                    //  判断 entryType 是否为 ROWDATA
                    if (CanalEntry.EntryType.ROWDATA.equals(entryType)) {
                        //  序列化数据
                        ByteString storeValue = entry.getStoreValue();
                        //  反序列化
                        CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(storeValue);
                        // 获取事件类型
                        CanalEntry.EventType eventType = rowChange.getEventType();
                        // 获取具体的数据
                        List<CanalEntry.RowData> rowDatasList = rowChange.getRowDatasList();
                        // 遍历并打印数据
                        for (CanalEntry.RowData rowData : rowDatasList) {
                            List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
                            Map<String, Object> bMap = new HashMap<>();
                            for (CanalEntry.Column column : beforeColumnsList) {
                                bMap.put(column.getName(), column.getValue());
                            }
                            Map<String, Object> afMap = new HashMap<>();
                            List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
                            for (CanalEntry.Column column : afterColumnsList) {
                                afMap.put(column.getName(), column.getValue());
                            }
                            System.out.println("表名:" + tableName + ",操作类型:" + eventType);
                            System.out.println("改前:" + bMap );
                            System.out.println("改后:" + afMap );
                        }
                    }
                }
            }
        }
    }
}

4> 테스트

canal-demo 라이브러리의 사용자 테이블에서 DML 작업을 수행하고 인쇄된 값을 관찰합니다.

운하 API 시스템 분석

 

7.2 스프링부트 통합

1>프로젝트 만들기: canal-sb-demo

2> 관련 의존성 가져오기

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-parent</artifactId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>top.javatool</groupId>
        <artifactId>canal-spring-boot-starter</artifactId>
        <version>1.2.6-RELEASE</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.12</version>
    </dependency>
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.21.4</version>
    </dependency>
</dependencies>

 3> 구성 파일

canal:
  server: 127.0.0.1:11111 #canal 默认端口11111
  destination: example
spring:
  application:
    name: canal-sb-demo
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/canal-demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
    username: root
    password: admin

4> 개체 객체

package com.langfeiyes.sb.domain;

public class User {
    private Long id;
    private String name;
    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

5> 모니터링 처리 클래스

package com.langfeiyes.sb.handler;

import com.langfeiyes.sb.domain.User;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;

@Component
@CanalTable(value = "user")
public class UserHandler implements EntryHandler<User> {
 
    @Override
    public void insert(User user) {
        System.err.println("添加:" + user);
    }
 
    @Override
    public void update(User before, User after) {
        System.err.println("改前:" + before);
        System.err.println("改后:" + after);

    }
    @Override
    public void delete(User user) {
        System.err.println("删除:" + user);
    }
}

6>수업 시작

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

7> 테스트

  • 먼저 운하 서버를 시작하십시오

  • 프로젝트 재시작

  • 사용자 테이블 수정

  • 관찰 결과

여덟, 같은 유형의 기술

유형 1: 로그 파싱 기반 데이터 동기화 구성 요소

이러한 유형의 컴포넌트는 주로 데이터베이스의 Binlog(MySQL) 또는 Redo Log(Oracle)와 같은 로그 파일을 파싱하여 데이터베이스의 추가, 삭제 및 수정 작업을 획득하고 이러한 작업을 기록합니다. 그런 다음 데이터 동기화를 위해 이러한 작업 기록을 다른 데이터베이스로 전송할 수 있습니다. 이러한 컴포넌트의 대표적인 제품으로는 Ali의 오픈소스 Canal , Tencent Cloud의 DBSync 등이 있다.

유형 2: ETL 기반 데이터 동기화 구성 요소

ETL은 Extract-Transform-Load로, 소스 시스템에서 데이터를 추출하고 데이터를 변환한 다음 최종적으로 대상 시스템으로 로드하는 것을 말합니다. 이러한 구성 요소는 일반적으로 복잡한 데이터 변환 규칙 및 데이터 매핑 관계를 작성해야 하며 빈번한 데이터 구조 변경, 대용량 데이터 및 여러 데이터 소스가 있는 시나리오에 적합합니다. 대표적인 제품으로는 알리바바 클라우드의 데이터웍스 , 인포매티카 파워센터 등이 있다.

유형 3: CDC 기반 데이터 동기화 구성 요소

CDC(Change Data Capture)는 변경 데이터 캡처로 데이터베이스의 데이터 변경 사항을 실시간 또는 준실시간으로 캡처하여 다른 데이터베이스로 전송할 수 있는 데이터 동기화 기술입니다. CDC 기술은 데이터베이스의 트랜잭션 로그 또는 리두 로그를 기반으로 구현되어 저지연, 고성능 데이터 동기화를 실현할 수 있습니다. CDC 구성요소의 대표적인 제품으로는 Oracle GoldenGate, IBM Infosphere Data Replication 등이 있습니다.

유형 4: 메시지 큐 기반 데이터 동기화 구성 요소

이러한 구성 요소는 일반적으로 데이터베이스에서 발생하는 변경 작업을 데이터 구조로 추상화하고 메시지 대기열을 통해 처리하기 위해 다른 시스템에 게시하여 비동기 전송 및 데이터 분리를 실현합니다. 대표적인 제품으로는 Apache Kafka, RabbitMQ 등이 있다.

9, Canal 공통 면접 질문

Q: 운하란 무엇입니까? 특징은 무엇입니까?

답변: Canal은 Alibaba에서 오픈 소스로 제공하는 Netty를 기반으로 하는 안정적인 고성능 분산 메시지 대기열로, 실시간 데이터 동기화 및 데이터 배포 시나리오에서 광범위한 응용 프로그램을 보유하고 있습니다. Canal에는 MySQL, Oracle 및 기타 데이터베이스의 로그 구문 분석 및 구독 지원, Kafka, RocketMQ, ActiveMQ 등과 같은 여러 데이터 출력 방법 지원, 데이터 필터링 및 형식 변환 지원, 낮은 대기 시간과 같은 우수한 기능이 있습니다. 및 높은 신뢰성 성능.

Q: Canal은 어떻게 작동합니까?

답변: Canal은 주로 데이터베이스의 binlog 로그를 구문 분석하여 데이터베이스의 추가, 삭제 및 수정 작업을 얻은 다음 이러한 변경 이벤트를 다운스트림 소비자에게 보냅니다. Canal의 핵심 구성 요소는 클라이언트와 서버의 두 부분으로 구성됩니다.클라이언트는 데이터베이스에 연결하여 로그 구문 분석을 시작하고 구문 분석된 데이터를 서버로 보내는 역할을 합니다.서버는 클라이언트가 보낸 데이터를 수신하고 필터링 및 배포를 담당합니다. 데이터. Canal은 또한 Kafka, RocketMQ, ActiveMQ 등과 같은 다양한 데이터 내보내기를 지원하여 추가 처리 및 분석을 위해 구문 분석된 데이터를 다른 메시지 대기열로 보낼 수 있습니다.

Q: Canal의 장단점은 무엇입니까?

답변: Canal의 장점은 주로 고성능, 분산형, 우수한 안정성, 데이터 필터링 및 변환 지원, 교차 데이터베이스 유형(예: MySQL, Oracle 등)을 포함합니다. 단점은 다음과 같습니다. 사용하기 어렵고 데이터베이스 로그에 특정 영향을 미치며 데이터 역추적을 지원하지 않습니다(즉, 기록 데이터를 얻을 수 없음).

Q: Canal은 비즈니스에서 어떤 애플리케이션 시나리오를 가지고 있습니까?

A: Canal은 주로 실시간 데이터 동기화 및 데이터 배포 시나리오에 사용되며 일반적인 애플리케이션 시나리오에는 데이터 백업 및 재해 복구, 증분 데이터 추출 및 동기화, 실시간 데이터 분석, 온라인 데이터 마이그레이션 등이 포함됩니다. 특히 인터넷 빅 데이터 시나리오에서 Canal은 다양한 데이터 처리 작업을 위한 중요한 도구 중 하나가 되었습니다.

추천

출처blog.csdn.net/langfeiyes/article/details/130711899