[ClickHouse] 使用 Bifrost 全量(实时)同步 MySQL 数据

1. 简介

本文记录一个从 MySQL 同步数据到 ClickHouse 的方案. 在 GitHub 上以 MySQL 和 ClickHouse 为关键字搜索到几个相关的开源项目, 首先试了下 synch , 结果在安装依赖包 mysqlclient 时一直失败, 然后改为使用 Bifrost 这个项目.

Bifrost 目前有接近 700 个 star, 从这两天的使用来看, Bifrost 的功能比较齐全, 基本能满足我们的使用场景, 比如全量同步/增量同步/表的批量操作等, 而且经过测试发现速度还是挺快的, 要说不足的话, 主要在于界面的操作不够简洁自然, 好在官方文档比较详细, 第一次使用不会遇到太多困难.

2. 安装

具体的安装和使用可以参考官方文档, 安装时推荐使用二进制安装方式, 第一次安装后若出现无法打开管理界面的情况, 可能是因为没有生成 HTTPS 证书, 这一点需要注意, 生成证书的命令如下
[ClickHouse] 使用 Bifrost 全量(实时)同步 MySQL 数据_第1张图片

3. 启动

安装完成后, 进入 bin 目录, 执行 ./Bifrost-server start 启动项目, 下面是安装好之后的管理界面
[ClickHouse] 使用 Bifrost 全量(实时)同步 MySQL 数据_第2张图片

4. 同步方式

[ClickHouse] 使用 Bifrost 全量(实时)同步 MySQL 数据_第3张图片

问题汇总

1. 配置完数据同步信息后, 若数据没有开始同步, 问题可能是:
  • MySQL 的 binlog 没有打开
  • MySQL 的 GTID_MODE=OFF, 开启命令为
SET GLOBAL ENFORCE_GTID_CONSISTENCY = 'WARN';
SET GLOBAL ENFORCE_GTID_CONSISTENCY = 'ON';
SET GLOBAL GTID_MODE = 'OFF_PERMISSIVE';
SET GLOBAL GTID_MODE = 'ON_PERMISSIVE';
SET GLOBAL GTID_MODE = 'ON';
2. 在重启服务的时候, 有可能会遇到配置文件被覆盖的情况, 具体原因不太清楚, 应对方法是备份配置文件, 配置文件的路径为 ./data/db.Bifrost
3. 有时同步位点会落后于 MySQL 的 binlog 位点, 为了保证数据的一致性, 需要定期检查同步过程是否正常, 检查方式为比对当前同步位点和MySQL的最新位点, 检查代码如下

注意填写正确的IP/端口/用户名/密码/数据源名称(代码里的MySQL_SOURCE)

import requests
import json
import pandas as pd
import time

def is_pos_right():
    '''检查 Bifrost 当前同步位点是否等于 MySQL 最新位点'''
    url = 'http://ip:21036/dologin'
    data = {'UserName': 'xxx', 'Password': 'xxx'}
    header = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36'}
    ret = requests.post(url, data=json.dumps(data), headers=header)
    cookie = 'xgo_cookie=' + ret.cookies.get_dict()['xgo_cookie']
    header['Cookie'] = cookie
    
    ret = requests.post(
        'http://ip:21036/db/get_last_position',
        json={'DbName': 'MySQL_99'}, 
        headers=header).text
    ret = json.loads(ret)
    # Bifrost 当前同步位点
    curr_pos = f"{ret['data']['BinlogFile']}{ret['data']['BinlogPosition']}"
    # MySQL 最新位点
    last_pos = f"{ret['data']['CurrentBinlogFile']}{ret['data']['CurrentBinlogPosition']}"
    # 同步延迟
    delay = ret['data']['DelayedTime']

    if curr_pos == last_pos:
        return True

    if delay >= 600:
        return False
    else:
        time.sleep(10)
        is_pos_right()


if __name__ == '__main__':
    if is_pos_right():
        print('Bifrost is working correctly!')
    else:
        raise Exception('Bifrost is not working correctly!')

你可能感兴趣的:(ClickHouse,MySQL,mysql,clickhouse,Bifrost,数据同步,数据库)