비디오 튜토리얼 포털:
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은 다양한 데이터 처리 작업을 위한 중요한 도구 중 하나가 되었습니다.