- 工作流程
- 环境
- 目标
- 名词解释
- 安装
- 配置
- 配置mysql
- 导入 manager 系统表
- 导入 node 同步算法依赖的系统表
- 管理配置
- 添加zookeeper主机
- 添加node
- 添加数据源
- 添加数据表
- 添加Canal配置
- 添加channel配置
- 添加pipeline配置
- 添加映射关系
- 启动同步
- 关于双A同步(数据的一致性问题)
- 相关参考
otter是一款基于Java且免费、开源基于数据库增量日志解析,准实时同步到本机房或异地机房的mysql/oracle数据库的解决方案。
工作流程
otter基于zookeeper解决分布式状态调度,由manager(web管理)和node(工作节点)组成。manager运行时推送同步配置到node节点上,node节点将同步状态反馈到manger上。
环境
- 主机A: 192.168.1.101
- 主机B: 192.168.1.102
- 系统: ubuntu 14.04.5
- MySQL: 5.6.33
- Zookeeper: 3.4.9
- otter: 4.2.14
目标
实现主机A(manager+node+zookeeper)和主机B(node)两台主机上的mysql数据库test
的双向同步。
名词解释
- Pipeline:从源端到目标端的整个过程描述,主要由一些同步映射过程组成
- Channel:同步通道,单向同步中一个Pipeline组成,在双向同步中有两个Pipeline组成
- DataMediaPair:根据业务表定义映射关系,比如源表和目标表,字段映射,字段组等
- DataMedia : 抽象的数据介质概念,可以理解为数据表/mq队列定义
- DataMediaSource : 抽象的数据介质源信息,补充描述DateMedia
- ColumnPair : 定义字段映射关系
- ColumnGroup : 定义字段映射组
- Node : 处理同步过程的工作节点,对应一个jvm
安装
MySQL(主机A、主机B)
apt install mysql-server-5.6
JDK(主机A、主机B)
add-apt-repository ppa:openjdk-r/ppa
apt update
apt install openjdk-8-jre
java -version
#=> openjdk version "1.8.0_111"
# or
add-apt-repository -y ppa:webupd8team/java
apt update
apt -y install oracle-java8-installer
aria2, otter的node端需要(主机A, 主机B)
apt install aria2
zookeeper (主机A)
wget http://mirror.jax.hugeserver.com/apache/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz
tar zvxf zookeeper-3.4.9.tar.gz
mv zookeeper-3.4.9 /usr/local/zookeeper
cd /usr/local/zookeeper/conf
cp zoo_sample.cfg zoo.cfg
cd ../bin
./zkServer.sh start
# ZooKeeper JMX enabled by default
# Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
# Starting zookeeper ... STARTED
manager (主机A)
wget https://github.com/alibaba/otter/releases/download/v4.2.14/manager.deployer-4.2.14.tar.gz
mkdir -p /usr/local/otter_manager
tar zvxf manager.deployer-4.2.14.tar.gz -C /usr/local/otter_manager
cd /usr/local/otter_manager
# 配置数据库连接及zookeeper连接和管理信息
vim conf/otter.properties
# 启动
cd bin/
./startup.sh
# 查看log
cd ..
tail -f logs/manager.log
# 2017-01-05 18:25:26.196 [] INFO com.alibaba.otter.manager.deployer.OtterManagerLauncher - ## start the manager server.
# 2017-01-05 18:25:35.981 [] INFO com.alibaba.otter.manager.deployer.JettyEmbedServer - ##Jetty Embed Server is startup!
# 2017-01-05 18:25:35.981 [] INFO com.alibaba.otter.manager.deployer.OtterManagerLauncher - ## the manager server is running now ......
# 查看进程
ps -ef | grep "/usr/local/otter_manager" | grep -v grep | awk '{print $2}'
# 11557
netstat -nutlp | grep 11557
# tcp 0 0 0.0.0.0:1099 0.0.0.0:* LISTEN 11557/java
# tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 11557/java
node (主机A、主机B)
wget https://github.com/alibaba/otter/releases/download/v4.2.14/node.deployer-4.2.14.tar.gz
mkdir -p /usr/local/otter_node
tar zvxf node.deployer-4.2.14.tar.gz -C /usr/local/otter_node
cd /usr/local/otter_node
# 配置
vim conf/otter.properties
# 建立配置文件中的目录
mkdir htdocs download extend
# 在manager管理页面配置并添加node后,将生成的id写入nid文件
cd conf
# 这里主机A的nid为1,主机B的nid为2
echo 1 > nid
# 启动
cd bin
./startup.sh
# 查看log
cd ..
tail -f logs/node/node.log
# 2017-01-05 19:03:45.563 [main] INFO com.alibaba.otter.node.deployer.OtterLauncher - INFO ## the otter server is running now ......
# 查看进程
ps -ef | grep "/usr/local/otter_manager" | grep -v grep | awk '{print $2}'
配置
配置mysql
在 my.cnf (/etc/mysql/my.cnf) 的 [mysqld]
节点下启用binlog和外部访问
log-bin=mysql-bin
binlog-format=ROW
character_set_server=utf8
# 这里manager端为1, node端为大于1的数字,每个node不重复
server-id=1
# 允许外部访问
bind-address = 0.0.0.0
建立用户otter,并设置外部访问权限
mysql> GRANT ALL PRIVILEGES ON *.* TO 'otter'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
导入 manager 系统表
这里只需要导入主机A
wget https://raw.github.com/alibaba/otter/master/manager/deployer/src/main/resources/sql/otter-manager-schema.sql
mysql -uroot -p < otter-manager-schema.sql
# show databases;
# +---------------------+
# | Database |
# +---------------------+
# | information_schema |
# | mysql |
# | otter |
# | performance_schema |
# +---------------------+
# 4 rows in set (0.01 sec)
导入 node 同步算法依赖的系统表
需要同步的两个数据库(主机A、主机B)都需要导入
wget https://raw.githubusercontent.com/alibaba/otter/master/node/deployer/src/main/resources/sql/otter-system-ddl-mysql.sql
mysql -uroot -p < otter-system-ddl-mysql.sql
# show databases;
# +--------------------+
# | Database |
# +--------------------+
# | information_schema |
# | mysql |
# | otter |
# | performance_schema |
# | retl |
# +--------------------+
# 5 rows in set (0.00 sec)
管理配置
打开 http://192.168.1.101:8080
并点击右上角图标进行管理员登录,默认帐号为 admin / admin
添加zookeeper主机
点击 机器管理 -> zookeeper管理 -> 添加
- 集群名字: mysql_test
- ZooKeeper集群: 192.168.1.101:2181; (多个分行)
点击保存
添加node
点击 机器管理 -> node管理 -> 添加
- 机器名称: 101
- 机器IP: 192.168.1.101
- 机器端口: 2088
- 下载端口: 9090
- zookeeper集群: mysql_test
其他默认,点击保存,同理添加主机B
添加数据源
点击 配置管理 -> 数据源配置 -> 添加
- 数据库名字: mysql_101
- 类型: MySQL
- 用户名: otter
- 密码: 123456
- URL: jdbc:mysql://192.168.1.101:3306
- 编码: UTF8
点击保存,同理添加主机B的数据源
添加数据表
点击 配置管理 -> 数据表配置 -> 添加
这里添加主机A的数据表
- schema name: test
- table name: .* (这里是指同步所有数据表,所以两个数据库的数据表结构要完全一样)
- 数据源: mysql_101
测试查询并保存,同理添加主机B的数据表
添加Canal配置
点击 配置管理 -> Canal配置 -> 添加
添加主机A的Canal配置
- canal名称: mysql_101
- zookeeper集群: mysql_test
- 数据库地址: 192.168.1.101:3306;
- 数据库帐号: otter
- 数据库密码: otter (这里的帐号和密码都是来自otter-system-ddl-mysql.sql,生产环境请自行修改)
- 位点自义定设置如下:
进入mysql命令行,使用如下命令查询binlog位点目录名及起始位置
show master status;
# +------------------+----------+--------------+------------------+-------------------+
# | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
# +------------------+----------+--------------+------------------+-------------------+
# | mysql-bin.000001 | 221277 | | | |
# +------------------+----------+--------------+------------------+-------------------+
# 1 row in set (0.00 sec)
显示当前时间戳:
select unix_timestamp(now());
# +-----------------------+
# | unix_timestamp(now()) |
# +-----------------------+
# | 1483973034 |
# +-----------------------+
# 1 row in set (0.00 sec)
生成的位点信息如下:
{"journalName":"mysql-bin.000001","position":221277,"timestamp":1483973034};
其他选项使用默认,同理添加主机B的Canal配置
添加channel配置
一个channel配置两个pipeline。
注意: 两个单向的canal和映射配置,在一个channel下配置为两个pipeline。 如果是两个channel,每个channel一个pipeline,将不会使用双向回环控制算法,也就是会有重复回环同步。 每个pipeline各自配置canal,定义映射关系。
点击 同步管理 -> channel管理 -> 添加
- channel name: 101<>102
其他选项使用默认。
添加pipeline配置
点击 同步管理 -> 101<>102 -> 添加
- pipeline名字: 101»102
- Select机器: mysql_101
- Load机器: mysql_102
- canal名字: mysql_101
- 高级设置 -> 支持ddl同步: 否
其他使用默认,点击保存,同理添加反向(102»101)的pipeline配置
添加映射关系
点击 同步管理 -> 101<>102 -> 101»102 -> 添加
- 源数据表: mysql_101数据源的
test
数据库 - 目标数据表: mysql_102数据库的
test
数据库
点击保存,同理添加反向pipeline的映射关系
启动同步
回到 同步管理,点击名字为 101<>102
的channel后面的启用
,即可开启同步。
然后就可以在101和102的名为test
的数据库中建立测试表来查看两台机器是否实现同步。
关于双A同步(数据的一致性问题)
双A同步相比于双向同步,主要区别是双A机房会在两地修改同一条记录,而双向同步只是两地的数据做互相同步,两地修改的数据内容无交集。
所以双A同步需要额外处理数据同步一致性问题. 同步一致性算法:Otter数据一致性 ,目前开源版本主要是提供了单向回环补救的一致性方案。
双A同步相比于双向同步,整个配置主要是一些参数上有变化,具体步骤:
- channel配置中的 “是否开启数据一致性” 设置为: 是
- channel中的两个pipeline配置中需要将基中一个设置为主站点,并且在高级设置中,将其中一个设置为false,另一个设置为 true
- 每个pipeline各自配置canal,定义映射关系
相关参考
- otter wiki
- symmtricds - 开源的数据同步和复制的解决方案,专业版需付费
- pervasync - 收费商业数据同步解决方案
- 原文地址:https://junnan.org/2017/01/mysql-two-way-synchronization-use-otter.html