• 工作流程
  • 环境
  • 目标
  • 名词解释
  • 安装
  • 配置
    • 配置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/ppaapt updateapt install openjdk-8-jrejava -version#=> openjdk version "1.8.0_111"# oradd-apt-repository -y ppa:webupd8team/javaapt updateapt -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.gztar zvxf zookeeper-3.4.9.tar.gzmv zookeeper-3.4.9 /usr/local/zookeepercd /usr/local/zookeeper/confcp zoo_sample.cfg zoo.cfgcd ../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.gzmkdir -p /usr/local/otter_managertar zvxf manager.deployer-4.2.14.tar.gz -C /usr/local/otter_managercd /usr/local/otter_manager# 配置数据库连接及zookeeper连接和管理信息vim conf/otter.properties# 启动cd bin/./startup.sh# 查看logcd ..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}'# 11557netstat -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.gzmkdir -p /usr/local/otter_nodetar zvxf node.deployer-4.2.14.tar.gz -C /usr/local/otter_nodecd /usr/local/otter_node# 配置vim conf/otter.properties# 建立配置文件中的目录mkdir htdocs download extend# 在manager管理页面配置并添加node后,将生成的id写入nid文件cd conf# 这里主机A的nid为1,主机B的nid为2echo 1 > nid# 启动cd bin./startup.sh# 查看logcd ..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-binbinlog-format=ROWcharacter_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.sqlmysql -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.sqlmysql -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,定义映射关系