先说下项目情况, 数据库是只用于管理后台供管理员配置使用,不影响任何业务的主流程,单机房可以满足需求。 可是客户非要求用双机房双写,本着简单解决问题的想法,我们就打算采用单点写双读。可是结果。。。。郁闷的是,人家都懒得跟我们说一声原因,怎么问都往数据不一致问题上绕, ,单写!额。。。开发工期很紧,我们先开发了,到最后都部署了,又跟客户沟通 数据库同步问题。这次在绕了好几天后,dba终于开口说,原因是Mysql本身的复制机制在跨机房情况下不可靠。 泪奔.......
otter 开源了 ,这个时间点太好了,刚好能用上,ye!向otter的开发者致敬!
otter的wiki页面:https://github.com/alibaba/otter
otter的环境需要:mysql ,jdk, zookeeper , node , aria2 , manager
为了防止otter的闪断,我把一些 软件上传到了百度云上:
http://pan.baidu.com/share/link?uk=3708161223&shareid=2987646776#dir
其他的就不说了,直接说安装和使用。
1 安装mysql, jdk ,zookeeper
otter只支持5.5及以下版本的Mysql,不支持maridb
此处假设安装了 数据库A:192.168.85.10:3306
数据库B: 192.168.85.11:3306
jdk,我安装的是7,安装完后,配置环境变量
zookeeper,可以只安装一个,可以以集群形式安装。
我现在只安装了一个,zookeeper的地址: 192.168.85.10:2181
2 安装node和aria2
node 需要aria2支持,我是在AB机房各安装了一套。
安装node:
创建目录:mkdir node
进入目录:cd node
下载node:
解压缩:tar zxvf node.deployer-$version.tar.gz
修改node的配置:vi conf/otter.properties
otter.manager.address =172.20.150.70:1099 ##对用manager中otter.properties的配置otter.communication.manager.port
node的启动/停止:
cd bin
startup.sh/stop.sh
安装aria2:
下载aria2:
解压缩:tar zxvf aria2-$version.tar.gz
为了方便切换目录:mv aria2-$version aria2
进入目录: cd aria2
编译:
./configure
Make
Make install
( 我本地安装的目录是/usr/local/aria2,安装后 ,bin目录在/usr/local/bin/)
3 安装manager
创建目录:mkdir manager
进入目录:cd manager
下载:wget https://github.com/alibaba/otter/releases/download/otter-x.y.z/manager.deployer-x.y.z.tar.gz
解压缩:tar zxvf manager.deployer-$version.tar.gz
安装manager的 数据库:
下载初始化sql:wget https://raw.github.com/alibaba/otter/master/manager/deployer/src/main/resources/sql/otter-manager-schema.sql
进入Mysql中执行:mysql> source /usr/local/otter-manager-schema.sql
修改manager的配置文件:vi conf/otter.properties
## otter manager domain name
otter.domainName = 172.20.150.70##本地的域名
## otter manager http port
otter.port = 8080 ##对外访问的端口号
## jetty web config xml
otter.jetty = jetty.xml
## otter manager database config
otter.database.driver.class.name = com.mysql.jdbc.Driver
otter.database.driver.url = jdbc:mysql://192.168.85.10:3308/otter##otter数据的配置
otter.database.driver.username = canal
otter.database.driver.password = canal
## otter communication port
otter.communication.manager.port = 1099##对应Node中的配置
## otter communication pool size
otter.communication.pool.size = 10
## default zookeeper address
otter.zookeeper.cluster.default = 192.168.85.10:2181##zookeeper
manager的启动/停止:
cd bin
tartup.sh/stop.sh
4 调试
启动预装好的Mysql,zookeeper,manager.
4.1 在 manager的界面,添加Node,如下图:
机器管理—》Node管理
添加完成后,根据添加后的node序号,如下图中,192.168.85.10中对应的序号是1,那么进入10机器下的node目录,执行echo 1 > conf/nid,然后启动node.
4.2 添加Zookeeper:
机器管理-》Zookeeper管理
如图,点击添加按钮,添加内容参考下图:
4.3 数据源配置:
配置管理-》数据源配置,点击添加按钮
数据源配置填写需要同步的两个数据库信息
添加内容如下图所示,添加完成后,点击验证连接数据源
4.4 数据表配置:
配置管理-》数据表配置,点击添加按钮。
数据表配置需要 同步的表的信息
添加 数据库的名称,数据表的名称和数据源名称,并点击验证连接表
4.5 canal配置:
配置管理-》canal配置,点击添加按钮。
canal需要添加两个,每一个对应一个 数据库信息,从配置的 数据库中,拉取bin-log信息。
4.5 同步管理:
1)添加channel
2) channel下需要配置pipeline,点击channel的名字,可以添加pipeline
3)添加完成pipeline后,点击pipeline的名字,添加映射关系,映射关系配置 同步的原表和目标表。
4)配置完成后,启动channel.
需要注意的是,如果配置的双通道,就是双机房双写,那么需要点击使用文档-》 数据库初始化页面。
在双机房的 数据库同时执行初始化SQL.
5)启动后,对双机房中的相应表分别进行插入,更新或其他操作,验证双机房 同步结果~
终于 同步了!再次感谢otter的开发者agapple ,否则我还不定在哪边绕呢。
项目背景
阿里巴巴B2B公司,因为业务的特性,卖家主要集中在国内,买家主要集中在国外,所以衍生出了杭州和美国异地机房的需求,同时为了提升用户体验,整个机房的架构为双A,两边均可写,由此诞生了otter这样一个产品。
otter第一版本可追溯到04~05年,此次外部开源的版本为第4版,开发时间从2011年7月份一直持续到现在,目前阿里巴巴B2B内部的本地/异地机房的同步需求基本全上了otte4。
目前同步规模:
- 同步数据量6亿
- 文件同步1.5TB(2000w张图片)
- 涉及200+个数据库实例之间的同步
- 80+台机器的集群规模
项目介绍
名称:otter ['ɒtə(r)]
译意: 水獭,数据搬运工
语言: 纯java开发
定位: 基于数据库增量日志解析,准实时同步到本机房或跨机房的mysql/oracle数据库.
工作原理
原理描述:
1. 基于Canal开源产品,获取数据库增量日志数据。 什么是Canal, 请点击
2. 典型管理系统架构,manager(web管理)+node(工作节点)
a. manager运行时推送同步配置到node节点
b. node节点将同步状态反馈到manager上
3. 基于zookeeper,解决分布式状态调度的,允许多node节点之间协同工作.
什么是canal?
otter之前开源的一个子项目,开源链接地址:http://github.com/alibaba/canal
otter能解决什么?
1. 异构库同步
a. mysql -> mysql/oracle. (目前开源版本只支持mysql增量,目标库可以是mysql或者oracle,取决于canal的功能)
2. 单机房同步 (数据库之间RTT < 1ms)
a. 数据库版本升级
b. 数据表迁移
c. 异步二级索引
3. 跨机房同步 (比如阿里巴巴国际站就是杭州和美国机房的数据库同不,RTT > 200ms,亮点)
a. 机房容灾
4. 双向同步
a. 避免回环算法 (通用的解决方案,支持大部分关系型数据库)
b. 数据一致性算法 (保证双A机房模式下,数据保证最终一致性,亮点)
5. 文件同步
a. 站点镜像 (进行数据复制的同时,复制关联的图片,比如复制产品数据,同时复制产品图片).
单机房复制示意图:
说明:
a. 数据on-Fly,尽可能不落地,更快的进行数据同步. (开启node loadBalancer算法,如果Node节点S+ETL落在不同的Node上,数据会有个网络传输过程)
b. node节点可以有failover / loadBalancer.
跨机房复制示意图:
说明:
a. 数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工作 (一般是Select和Extract在一个机房的Node,Transform/Load落在另一个机房的Node)
b. node节点可以有failover / loadBalancer. (每个机房的Node节点,都可以是集群,一台或者多台机器)
相关名词解释
otter核心model关系图
名词解释
- Pipeline:从源端到目标端的整个过程描述,主要由一些同步映射过程组成
- Channel:同步通道,单向同步中一个Pipeline组成,在双向同步中有两个Pipeline组成
- DateMediaPair:根据业务表定义映射关系,比如源表和目标表,字段映射,字段组等
- DateMedia : 抽象的数据介质概念,可以理解为数据表/mq队列定义
- DateMediaSource : 抽象的数据介质源信息,补充描述DateMedia
- ColumnPair : 定义字段映射关系
- ColumnGroup : 定义字段映射组
- Node : 处理同步过程的工作节点,对应一个jvm
otter的S/E/T/L stage阶段模型
说明:为了更好的支持系统的扩展性和灵活性,将整个同步流程抽象为Select/Extract/Transform/Load,这么4个阶段.
Select阶段: 为解决数据来源的差异性,比如接入canal获取增量数据,也可以接入其他系统获取其他数据等。
Extract/Transform/Load 阶段:类似于数据仓库的ETL模型,具体可为数据join,数据转化,数据Load的
相关实现介绍
QuickStart
See the page for quick start: QuickStart.
AdminGuide
See the page for admin deploy guide : AdminGuide
目录
一、前奏
本安装步骤是根据目前测试环境已经搭建好的otter部署情况为场景,说明如何安装一个otter环境,生产环境的安装可以此文档为蓝本,做相应的配置修改。文档中所有的截图和配置文件所显示的内容信息都可以从机子上找到。大致部署情况如下:
10.0.30.190:manager、node
10.0.30.201:manager 站点所依赖的mysql数据库
10.0.30.188:部署zookeeper 。
Ps:188机子上也安装了一个node,主要是为集群做准备的,文档中所提到的node安装步骤以安装在190机子上的node为说明对象,集群中其它机器上node的安装步骤类似。
二、Manager网站安装
环境准备
otter的环境需要mysql ,jdk, zookeeper , node , manager
1. otter数据库初始化
otter manager依赖于mysql进行配置信息的存储,所以需要预先安装mysql,并初始化otter manager所需的系统库和表。
登录201的机子,执行source命令导入sql脚本文件:
source otter-manager-schema.sql
执行show databases可以看到脚本创建了一个名字叫otter的数据库
2. zookeeper安装
安装一个zookeeper到188机子(整个otter架构依赖了zookeeper进行多节点调度,所以需要预先安装zookeeper)
manager启动步骤
1. 在190机子上解压缩manager的安装包
mkdir /usr/ottermanager
tar zxvf manager.deployer-4.2.7.tar.gz /usr/ottermanager
2. 修改namager的配置文件信息(/conf/otter.properties)
注:只需要修改标红色的配置
## otter manager网站域名地址 #修改为正确访问ip,生成URL使用
otter.domainName = 10.0.30.190
## otter manager 的web管理后台端口
otter.port = 8085
## jetty web config xml
otter.jetty = jetty.xml
## otter manager 所依赖的数据库配置 ,修改为正确数据库信息
otter.database.driver.class.name = com.mysql.jdbc.Driver
otter.database.driver.url = jdbc:mysql://10.0.30.201:3306/otter
otter.database.driver.username = belle #用户名和密码请DBA配合授权
otter.database.driver.password = belle@belle
## otter communication port(manager和node通讯端口,保留默认1099)
otter.communication.manager.port = 1099
## otter communication pool size
otter.communication.pool.size = 10
## manager依赖的zookeeper 地址
otter.zookeeper.cluster.default = 10.0.30.188:2181
## default zookeeper sesstion timeout = 90s
otter.zookeeper.sessionTimeout = 90000
## otter arbitrate connect manager config
otter.manager.address = ${otter.domainName}:${otter.communication.manager.port}
3. 准备启动
进入安装目录/bin/下,输入:sh startup.sh启动manager web网站。
4. 查看日志
vi logs/manager.log
出现类似日志,代表启动成功:
2013-08-14 13:19:45.911 [] WARN com.alibaba.otter.manager.deployer.JettyEmbedServer - ##Jetty Embed Server is startup!
2013-08-14 13:19:45.911 [] WARN com.alibaba.otter.manager.deployer.OtterManagerLauncher - ## the manager server is running now ......
5. 验证
访问: http://10.0.30.190:8085/(详细地址根据步骤2的配置信息),出现otter的页面,即代表启动成功
初始密码为:admin/admin,即可完成登录. 目前:匿名用户只有只读查看的权限,登录为管理员才可以有操作权限
6. 关闭
sh stop.sh
三、Node 安装
环境准备
otternode会受ottermanager进行管理,所以需要预先安装ottermanager,参见:Manager网站安装
1.生成nid
完成manager安装后,需要在manager页面为node定义配置信息,并生一个唯一id.
a. 首先访问manager web页面”机器管理”菜单,选择“zookeeper管理”子菜单,点击页面“添加”按钮以注册一个zookeeper。
b. 从”node管理”菜单中选择添加node按钮,往manager注册一个node节点信息。
几点说明:
· 机器名称:可以随意定义,方便自己记忆即可
· 机器ip:对应node节点将要部署的机器ip,如果有多ip时,可选择其中一个ip进行暴露. (此ip是整个集群通讯的入口,实际情况千万别使用127.0.0.1,否则多个机器的node节点会无法识别)
· 机器端口:对应node节点将要部署时启动的数据通讯端口,建议值:2088
· 下载端口:对应node节点将要部署时启动的数据下载端口,建议值:9090
· 外部ip :对应node节点将要部署的机器ip,存在的一个外部ip,允许通讯的时候走公网处理。
· zookeeper集群:为提升通讯效率,不同机房的机器可选择就近的zookeeper集群.
· 机器添加完成后,跳转到机器列表页面,获取对应的机器序号nid
· 通过这两部操作,获取到了node节点对应的唯一标示,称之为nodeid,简称:nid. 记录该nid,后续启动nid时会使用
node启动步骤
1. 解压缩node安装包node.deployer-4.2.7.tar.gz
mkdir /usr/ottermanager/nodedeveloper (为方便管理,直接安装在manager目录下)
tar zxvf node.deployer-4.2.7.tar.gz /usr/ottermanager/ nodedeveloper
2. 修改配置
a. nid配置 (将环境准备中添加机器后获取到的序号,保存到conf目录下的nid
文件,比如我添加的机器对应序号为1)
echo 1 > conf/nid
b. otter.properties配置修改
打开文件/usr/ottermanager/nodedeveloper/conf/otter.properties
Vi /usr/ottermanager/ nodedeveloper/conf/otter.properties,修改如下内容:
##修改为正确的manager服务地址
otter.manager.address = 10.0.30.190:1099
3. 启动node
进入/usr/ottermanager/nodedeveloper/bin。
输入命令:sh startup.sh
4. 查看日志
打开日志: vi /usr/ottermanager/nodedeveloper/logs/node/node.log
看到如下日志,代表node启动完成:
2013-08-14 15:42:16.886 [main] INFO com.alibaba.otter.node.deployer.OtterLauncher - INFO ## the otter serveris running now ......
5. 验证
访问: http://10.0.30.190:8085/node_list.htm,查看对应的节点状态,如果变为了已启动,代表已经正常启动。(ps,如果是未启动,会是一个红色高亮)
6. 关闭
sh stop.sh
关闭后,可查看下manager页面,检查下节点状态变为“未启动”
四、附加章节—添加一个从商品库到分销库的数据同步。
场景分析
将10.0.30.131机子上yitian_b2c_db 库(源库)的tbl_commodity_style表数据同步到dms_db 库(目的库)上的tbl_dms_commodity_style表。
由于otter是一个基于binlog的增量日志同步工具,首次同步的时候涉及到历史数据的拷贝,binlog日志位点的设置比较难找。因此对于初始数据的拷贝,采用原始的方法,先在源库创建tbl_dms_commodity_style表,用来临时保存tbl_commodity_style表数据的备份。记录下master的位点信息(作为otter同步任务的初始位置,假设是position1),同时快速备份tbl_commodity_style的数据到tbl_dms_commodity_style。再把临时表tbl_dms_commodity_style的数据恢复到目的库dms_db。
新建的同步任务中引用的canal必须位点设置为position1。如此一来,既能把历史数据导入到目的库的表,又能保证position1后添加的数据能被otter同步到。
具体步骤:
1. 创建基础业务表
dms_db 库和yitian_b2c_db库分别上执行create table脚本,两边同时创建tbl_dms_commodity_style表
2. 业务数据备份
执行mysql 的insertinto tbl_dms_commodity_style select ... 语句将源库的tbl_commodity_style数据备份到源库的tbl_dms_commodity_style表。同时快速记录此时masterstatus 的位点信息,假设为position1。此步骤很重要,要确保及时性,防止出现以下两种情况导致的数据不一致性:
a. 先记录位点信息,再备份数据,此时有可能中间数据库执行了inser/update/delete语句。后期同步任务启动的时候,会重复执行了这些语句,有风险。(可选)
b. 先备份数据,再记录位点。此时中间插入了数据,由于插入的数据日志位点在我们记录的位点之前,那么后期同步任务启动的时候,会丢失数据。
附图,131master状态:
3. 创建canal
其中canal的位点信息根据show master status的信息输入自定义。
a.创建针对131机子master binlog的canal。
4. 创建数据源(添加表映射用到)
5. 添加源库的表和目的库的表
源库的表
目的库表
添加完毕之后从列表中可以看到:
6. 新建同步通道channel.
同步一致性选择基于当前日志变更,同步模式选择“行记录模式”,不开启数据一致性。
创建完毕后可以看到
7. 新建一个pipeline.
点击“131-131”进入该channel所属的 Pipeline管理页面。
新建pipeline:
点击“保存”后在pipeline管理页面看到新建的记录
点击“pipline131”添加表映射:
8. 新建表映射
选完表后点击下一步看到源库表和目的库表的字段
分别从源库和目的库选择需要同步的字段,点击按钮,如上选择了id和supplier_code,注意两边需要同步的字段一一对应。选完后直接保存。
表映射创建完毕,回到pipeline管理页面。可以看到
由此,一个同步任务创建完毕了,我们回到channel页面,可以点击“启用”开始同步任务了。
9. 检查是否生效.(pipeline对应的日志)
每个同步任务的pipeline都可以从菜单上看到“吞吐量“,”延迟时间“,”同步进度“,”历史吞吐量“,”日志记录“具体用法待续。
ps:channel和pipline的概念参考:https://github.com/alibaba/otter/wiki/Introduction
单向同步中每个channel只能有一个pipeline,双向同步每个channel有两个pipeline,目前我们的同步是单向的。每一个canal也只能提供给一个pipeline.所以如果我们要创建新的同步任务的话,如商品库到无线的数据同步,需新建canal.