社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

033-史上最全-mysql迁移到clickhouse的5种办法

赵安家 • 5 年前 • 599 次点击  
阅读 34

033-史上最全-mysql迁移到clickhouse的5种办法

这是坚持技术写作计划(含翻译)的第33篇,定个小目标999,每周最少2篇。

数据迁移需要从mysql导入clickhouse, 总结方案如下,包括clickhouse自身支持的三种方式,第三方工具两种。

create table engin mysql

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);
复制代码

官方文档: clickhouse.yandex/docs/en/ope…

注意,实际数据存储在远端mysql数据库中,可以理解成外表。
可以通过在mysql增删数据进行验证。

insert into select from

-- 先建表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = engine
-- 导入数据
INSERT INTO [db.]table [(c1, c2, c3)] select 列或者* from mysql('host:port', 'db', 'table_name', 'user', 'password')
复制代码

可以自定义列类型,列数,使用clickhouse函数对数据进行处理,比如 select toDate(xx) from mysql("host:port","db","table_name","user_name","password")

create table as select from

CREATE TABLE [IF NOT EXISTS] [db.]table_name
ENGINE =Log
AS 
SELECT *
FROM mysql('host:port', 'db', 'article_clientuser_sum', 'user', 'password')
复制代码

网友文章: jackpgao.github.io/2018/02/04/…

不支持自定义列,参考资料里的博主写的 ENGIN=MergeTree 测试失败。
可以理解成 create table 和 insert into select 的组合

Altinity/clickhouse-mysql-data-reader

Altinity公司开源的一个python工具,用来从mysql迁移数据到clickhouse(支持binlog增量更新和全量导入),但是官方readme和代码脱节,根据quick start跑不通。

## 创建表
clickhouse-mysql \
    --src-host=127.0.0.1 \
    --src-user=reader \
    --src-password=Qwerty1# \
    --table-templates-with-create-database \
    --src-table=airline.ontime > create_clickhouse_table_template.sql
## 修改脚本
vim create_clickhouse_table_template.sql

## 导入建表
clickhouse-client -mn < create_clickhouse_table_template.sql

## 数据导入
clickhouse-mysql \
     --src-host=127.0.0.1 \
     --src-user=reader \
     --src-password=Qwerty1# \
     --table-migrate \
     --dst-host=127.0.0.1 \
     --dst-table=logunified \
     --csvpool
复制代码

官方文档: github.com/Altinity/cl…

注意,上述三种都是从mysql导入clickhouse,如果数据量大,对于mysql压力还是挺大的。下面介绍两种离线方式(streamsets支持实时,也支持离线)
csv

## 忽略建表
clickhouse-client \
  -h host \
  --query="INSERT INTO [db].table FORMAT CSV" < test.csv
复制代码

但是如果源数据质量不高,往往会有问题,比如包含特殊字符(分隔符,转义符),或者换行。被坑的很惨。

  • 自定义分隔符, --format_csv_delimiter="|"
  • 遇到错误跳过而不中止, --input_format_allow_errors_num=10 最多允许10行错误, --input_format_allow_errors_ratio=0.1 允许10%的错误
  • csv 跳过空值(null) ,报 Code: 27. DB::Exception: Cannot parse input: expected , before: xxxx: (at row 69) ERROR: garbage after Nullable(Date): "8,002<LINE FEED>0205"  sed ' :a;s/,,/,\\N,/g;ta' |clickhouse-client -h host --query "INSERT INTO [db].table FORMAT CSV" 将 ,, 替换成 ,\N,

python clean_csv.py --src=src.csv --dest=dest.csv --chunksize=50000 --cols --encoding=utf-8 --delimiter=,

clean_csv.py参考我另外一篇 032-csv文件容错处理

streamsets

streamsets支持从mysql或者读csv全量导入,也支持订阅binlog增量插入,参考我另外一篇 025-大数据ETL工具之StreamSets安装及订阅mysql binlog
本文只展示从mysql全量导入clickhouse
本文假设你已经搭建起streamsets服务

image.png

启用并重启服务
image.png

上传mysql和clickhouse的jdbc jar和依赖包
便捷方式,创建pom.xml,使用maven统一下载

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.anjia</groupId>
  <artifactId>demo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>demo</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
        <groupId>ru.yandex.clickhouse</groupId>
        <artifactId>clickhouse-jdbc</artifactId>
        <version>0.1.54</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
  </dependency>
  </dependencies>
</project>
复制代码

如果本地装有maven,执行如下命令
mvn dependency:copy-dependencies -DoutputDirectory=lib -DincludeScope=compile 
所有需要的jar会下载并复制到lib目录下

image.png

然后拷贝到 streamsets /opt/streamsets-datacollector-3.9.1/streamsets-libs-extras/streamsets-datacollector-jdbc-lib/lib/ 目录下
image.png

重启streamsets服务
image.png
image.png

image.png

image.png

image.png

image.png

参考资料

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/36248
 
599 次点击