暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Clickhouse-mysql-实时数仓建设

骚明的大数据之旅 2021-10-26
941

本文介绍如何使用MaterializeMySQL引擎将MySQL(自建MySQL或RDS MySQL)数据同步到云数据库ClickHouse。这是一个不应在生产中使用的实验性功能。

参考链接:https://clickhouse.com/docs/zh/engines/database-engines/materialized-mysql/

1、背景信息

使用 MySQL 中存在的所有表以及这些表中的所有数据创建 ClickHouse 数据库。

ClickHouse 服务器用作 MySQL 副本。它读取 binlog 并执行 DDL 和 DML 查询。

2、创建数据库

CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster]
ENGINE = MaterializeMySQL('host:port', ['database' | database], 'user', 'password') [SETTINGS ...]

引擎参数

  • host:port— MySQL服务地址

  • database— MySQL数据库名称

  • user— MySQL用户名

  • password — MySQL用户密码

3、配置属性

  • max_rows_in_buffer— 允许数据缓存到内存中的最大行数(对于单个表和无法查询的缓存数据)。当超过行数时,数据将被物化。默认值: 65505

  • max_bytes_in_buffer— 允许在内存中缓存数据的最大字节数(对于单个表和无法查询的缓存数据)。当超过行数时,数据将被物化。默认值: 1048576.

  • max_rows_in_buffers— 允许数据缓存到内存中的最大行数(对于数据库和无法查询的缓存数据)。当超过行数时,数据将被物化。默认值: 65505.

  • max_bytes_in_buffers— 允许在内存中缓存数据的最大字节数(对于数据库和无法查询的缓存数据)。当超过行数时,数据将被物化。默认值: 1048576.

  • max_flush_data_time— 允许数据在内存中缓存的最大毫秒数(对于数据库和无法查询的缓存数据)。当超过这个时间时,数据将被物化。默认值: 1000.

  • max_wait_time_when_mysql_unavailable— 当MySQL不可用时重试间隔(毫秒)。负值禁止重试。默认值: 1000.

  • allows_query_when_mysql_lost — 当mysql丢失时,允许查询物化表。默认值: 0 (false).

CREATE DATABASE mysql ENGINE = MaterializeMySQL('localhost:3306', 'db', 'user', '***') 
SETTINGS
allows_query_when_mysql_lost=true,
max_wait_time_when_mysql_unavailable=10000;

4、MySQL服务器端配置

为了MaterializeMySQL正确的工作,有一些强制性的MySQL侧配置设置应该设置:

  • default_authentication_plugin = mysql_native_password,因为MaterializeMySQL只能使用此方法授权。

  • gtid_mode = on,因为要提供正确的MaterializeMySQL复制,基于GTID的日志记录是必须的。注意,在打开这个模式On时,你还应该指定enforce_gtid_consistency = on

5、虚拟列

当使用MaterializeMySQL数据库引擎时,ReplacingMergeTree表与虚拟的_sign_version列一起使用。

  • _version— 同步版本。类型UInt64.

  • _sign— 删除标记。类型 Int8. Possible values:

    • 1— 行不会删除,

    • -1 — 行被删除。

4、案例

首先在MySQL中配置 my.cnf

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

# 配置flink-mysql-cdc
server-id=1
log-bin=mysql-bin
binlog_format=row
binlog-do-db=wmy
binlog-do-db=db

# clickhouse
gtid-mode=on
enforce-gtid-consistency=1 # 设置为主从强一致性
log-slave-updates=1 # 记录日志

systemctl restart mysqld

在MySQL中创建库和表

CREATE DATABASE db;
CREATE TABLE db.test (a INT PRIMARY KEY, b INT);

在clickhouse中创建库

CREATE DATABASE mysql ENGINE = MaterializeMySQL('192.168.21.113:3306', 'db', 'root', '000000') 
SETTINGS
allows_query_when_mysql_lost=true,
max_wait_time_when_mysql_unavailable=10000;
SET allow_experimental_database_materialize_mysql = 1
# 因为该功能目前还处于实验阶段,在使用之前需要开启

可以查看是否有表

INSERT INTO db.test VALUES (1, 11), (2, 22);
DELETE FROM db.test WHERE a=1;
ALTER TABLE db.test ADD COLUMN c VARCHAR(16);
UPDATE db.test SET c='Wow!', b=222;
SELECT * FROM db.test;

下面每执行一步操作的话就去clickhouse里面去查看

5、注意

目前20.8 testing版本使用的监听事件方式为UpdateRowsEventV2 ,而20.8 prestable只后的版本使用的gtid的binlog监听方式,这种方式在mysql主从模式下可以确保数据同步的一致性,但使用过程中可能会有一些意向不到问题,建议大家先使用testing版本进行测试,等20.8稳定版出来后再测试gtid的同步模式。


查询clickhouse对应的表,已可以实时看到数据变化


通过上面的测试我们发现clickhouse的删除动作也是实时同步的,原因在于我们创建的MaterializeMySQL engine会默认为每一张表生成ReplacingMergeTree engine,当clickhouse遇到删除的binlog操作时,会将这条数据的_sign字段设为-1;

目前ReplacingMergeTree还只是标记性删除,并非物理上的实际删除,索引随着删除日志的增多,查询过滤会有一定的负担。

MaterializeMySQL DataBase中的ReplacingMergeTree Engine表查询不再需要额外添加final修饰符了:


  • 需要注意的是20.8版本目前还不是稳定版,如果mysql中没有设置主键字段时,会在创建MaterializeMySQL数据库时报错:

  • 主键字段和索引字段不允许为NULL

  • 不过该ISSUES目前已被重视,20.7版本在create table 时解决了这个问题,可以通过设置allow_nullable_key=1来解决,但因为MaterializeMySQL是自动创建的数据表,所以该问题还是存在的,相信不久的版本在创建MaterializeMySQL DataBase时 也会解决这个问题

  • clickhouse单线程写入能力可以达到每秒几十万,在一般业务体系下增量更新的模式是完全没有问题的。

CREATE DATABASE mysql ENGINE = MaterializeMySQL('192.168.21.113:3306', 'db', 'root', '000000') 
SETTINGS
allows_query_when_mysql_lost=true,
max_wait_time_when_mysql_unavailable=10000,
SETTINGS allow_nullable_key = 1;

目前这个只是一个实验阶段,相信在未来的时间里面这个会用得很多,在实时数仓的场景中


文章转载自骚明的大数据之旅,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论