canal来实现mysql的数据同步

文 / @WordPress主题

本文介绍如何通过Canal来实现MySQL的数据同步。首先,我们需要了解Canal的工作原理,它是一个基于日志增量订阅和消费的组件,支持的业务包括数据库镜像、数据库实时备份、索引构建和实时维护、业务cache刷新、带业务逻辑的增量数据处理等。当前的Canal支持源端MySQL版本包括5.1.x,5.5.x,5.6.x,5.7.x,8.0.x。Canal的工作原理是通过同步MySQL的二进制日志文件来实现的,它将自己伪装成从服务器,从而读取日志并拿到数据。

在实现Canal之前,先通过主从复制简单实现MySQL的数据同步。我们可以使用Docker来搭建MySQL的主从复制环境,具体步骤是:

1.下载MySQL镜像,并启动Docke容器

docker run -itd --name mysql-1 -p 23306:3306 -e MYSQL_ROOT_PASSWORD=root mysql
docker run -itd --name mysql-2 -p 23307:3306 -e MYSQL_ROOT_PASSWORD=root mysql

2.在主从服务器中创建MySQL用户,并设置从服务器为主服务器的从服务器

在主服务器上执行:

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';
FLUSH PRIVILEGES;

在从服务器上修改my.cnf配置文件:

[mysqld]
server_id=100
log-bin=mysql-slave-bin
relay_log=edu-mysql-relay-bin

3.在从服务器中执行复制命令,并验证主从同步状态

在从服务器中执行以下命令:

mysql> CHANGE MASTER TO master_host='172.17.0.4',master_user='slave',master_password='123456',master_port=3306,master_log_file='mysql-bin.000001',master_log_pos=877,master_connect_retry=30;

接着,在从服务器中执行show slave status\G;命令,查看主从同步状态。

简单的主从复制完成后,就可以使用Canal来实现MySQL的数据同步了。具体步骤是:

1.下载Canal镜像,并启动Docker容器

docker pull canal/canal-server:latest
wget https://raw.githubusercontent.com/alibaba/canal/master/docker/run.sh
sh run.sh --name canal-server -e canal.auto.scan=false -e canal.destinations=test -e canal.instance.master.address=172.17.0.4:3306 -e canal.instance.dbUsername=canal -e canal.instance.dbPassword=canal -e canal.instance.connectionCharset=UTF-8 -e canal.instance.tsdb.enable=true -e canal.instance.gtidon=false

2.使用Canal的客户端来监听数据变化

Canal提供了多个客户端,本文使用canal-php作为例子。canal-php需要配置Canal的IP地址、端口号、用户名、密码等信息,也可以根据需要进行修改。

使用Laravel框架为例,安装canal-php,并监听数据变化:

composer require xingwenge/canal_php

namespace App\Console\Commands;

use xingwenge\canal_php\CanalClient;
use xingwenge\canal_php\CanalConnectorFactory;
use xingwenge\canal_php\Fmt;
use Illuminate\Console\Command;

ini_set('display_errors', 'On');
error_reporting(E_ALL);

class CanalDemo extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'CanalDemo';

/**
* The console command description.
*
* @var string
*/
protected $description = '测试canal';

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
try {
$client = CanalConnectorFactory::createClient(CanalClient::TYPE_SOCKET_CLUE);

$client->connect("172.17.0.5", 11111);//此处修改为自己的配置
$client->checkValid();
$client->subscribe("1001", "test", ".*\\..*");//对应启动容器时test的队列名
while (true) {
$message = $client->get(100);
if ($entries = $message->getEntries()) {
foreach ($entries as $entry) {
Fmt::println($entry);
}
}
sleep(1);
}

$client->disConnect();

} catch (\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
}
}

使用Canal实现MySQL的数据同步,可以方便地应用于数据库镜像、数据库实时备份、多级索引、搜索引擎、缓存等业务场景。

添加UTHEME为好友
扫码添加UTHEME微信为好友
· 分享WordPress相关技术文章,主题上新与优惠动态早知道。
· 微信端最大WordPress社群,限时免费入群。