otter

背景

***公司系统间的数据同步通过http接口通信,这种方式会导致数据同步高峰期间nginx的负载流量增加,从而影响业务流量。其二就是http方式的不稳定性,会导致一些数据不一致的问题。针对这个现象,目前提出2中解决方式,第一种可以通过高可用消息队列来进行解耦,第二种通过数据库底层binlog来监听数据变化。

otter介绍

otter为阿里的一款增量数据同步工具,基于数据库增量日志解析,准实时同步到本机房或异地机房的mysql/oracle数据库.一个分布式数据库同步系统。

otter工作原理

原理描述:

  1. 基于Canal开源产品,获取数据库增量日志数据。
  2. 典型管理系统架构,manager(web管理)+node(工作节点).manager运行时推送同步配置到node节点.node节点将同步状态反馈到manager上.
  3. 基于zookeeper,解决分布式状态调度的,允许多node节点之间协同工作.

Otter目前支持了什么

  1. 单向同步, mysql/oracle互相同步
  2. 双向同步,无冲突变更
  3. 文件同步,本地/aranda文件
  4. 双A同步,冲突检测&冲突补救
  5. 数据迁移,中间表/行记录同步

    典型的场景是账户信息表和账户交易明细表,更新账户余额后需要登记一条账户明细,并且保证在一个事务里,用户可以通过交易明细表查看交易记录,但是交易明细表的数据量是逐步递增的,用户量多的系统,几个月下来的数据超过千万了,表数据量一多就导致查询和插入变慢,而一开始就对账户明细做分表处理就难于保证强一致性事务,通过otter可以将记录同步导历史表,并且进行分表处理,用户往年的交易记录就可以查询历史表了,而原交易明细表就可以删除一个月甚至几天前的数据;

环境准备

  1. otter manager依赖于mysql进行配置信息的存储,所以需要预先安装mysql,并初始化otter manager的系统表结构
  2. 整个otter架构依赖了zookeeper进行多节点调度,所以需要预先安装zookeeper,不需要初始化节点,otter程序启动后会自检.
  3. 安装jdk1.6+

    官方文档:https://github.com/alibaba/otter/wiki/Manager_Quickstart
    https://github.com/alibaba/otter/wiki/Node_Quickstart

名词解释

  1. Channel:同步通道,单向同步中一个Pipeline组成,在双向同步中有两个Pipeline组成;Pipeline:从源端到目标端的整个过程描述,主要由一些同步映射过程组成;
  2. DataMediaPair:根据业务表定义映射关系,比如源表和目标表,字段映射,字段组等;
  3. DataMedia:抽象的数据介质概念,可以理解为数据表/mq队列定义;
  4. DataMediaSource: 抽象的数据介质源信息,补充描述DateMedia;
  5. ColumnPair: 定义字段映射关系;
  6. ColumnGroup: 定义字段映射组;
  7. Node: 处理同步过程的工作节点,对应一个jvm;

采坑问题

  1. mysql需要开启binlog,并且binlog的模式一定要Row。
  2. mysql5.6版本需要binlog_checksum设置为none,默认开始crc校验。
  3. mysql mater节点需要设置server-id,server-id需要和manager上配置的node的id一致。错误内容如下:
    1
    2
    3
    4
    5
    pid:1 nid:1 exception:canal:源数据库cancal:java.io.IOException: Received error packet: errno = 1236, sqlstate = HY000 errmsg = Misconfigured master - server_id was not set
    at com.alibaba.otter.canal.parse.inbound.mysql.dbsync.DirectLogFetcher.fetch(DirectLogFetcher.java:105)
    at com.alibaba.otter.canal.parse.inbound.mysql.MysqlConnection.dump(MysqlConnection.java:146)
    at com.alibaba.otter.canal.parse.inbound.AbstractEventParser$3.run(AbstractEventParser.java:227)
    at java.lang.Thread.run(Thread.java:745)

参考资料

  1. https://github.com/alibaba/otter/wiki
  2. https://github.com/alibaba/otter/wiki/Faq
  3. https://blog.csdn.net/wudufeng/article/details/78688240
  4. https://yq.aliyun.com/articles/223077?utm_content=m_32233
  5. https://my.oschina.net/u/860872/blog/1609715
  6. https://www.cnblogs.com/findumars/p/6294542.html
  7. mysql binlog优化
    https://www.cnblogs.com/doseoer/p/6132454.html
  8. binlog采坑 https://www.cnblogs.com/276815076/p/7993712.html
  9. https://yq.aliyun.com/articles/223077?utm_content=m_32233
  10. https://blog.csdn.net/wudufeng/article/details/78688240