当前位置:   article > 正文

canal使用记录_something goes wrong with reason: something goes w

something goes wrong with reason: something goes wrong with channel:[id: 0x3

canal是阿里巴巴的来源项目。我们可以通过配置binlog实现数据库监控,得到数据库表或者数据的更新信息。
参考我的文档前先去官网看下,可能已经支持更高版本的MySQL了

1. 查看官方开源项目

https://github.com/alibaba/canal

2. 下载最新的canal.deployer-XXXX-SNAPSHOT.tar.gz

https://github.com/alibaba/canal/releases

3. 查看wiki

ps. 目前内部版本已经支持mysql和oracle部分版本的日志解析,当前的canal开源版本支持5.7及以下的版本(阿里内部mysql 5.7.13, 5.6.10, mysql 5.5.18和5.1.40/48)
所以需要安装mysql5.7以下的版本稳妥些

4. 去MySQL官网下载mysql并安装

5. 查看mysql安装目录

6. 复制一个my-default.ini改名叫my.ini

修改对应位置:
添加:

  1. #添加这一行就ok
  2. log-bin=mysql-bin
  3. #选择row模式
  4. binlog-format=ROW
  5. #配置mysql replaction需要定义,不能和canal的slaveId重复
  6. server_id=1
  7. character-set-server=utf8
  8. collation-server=utf8_general_ci

添加:

  1. [mysql]
  2. default-character-set = utf8
  3. [mysql.server]
  4. default-character-set = utf8
  5. [mysqld_safe]
  6. default-character-set = utf8
  7. [client]
  8. default-character-set = utf8

7. 重启mysql

  1. .6\bin>sc delete mysql
  2. \bin>net stop mysql
  3. \bin>mysqld --install mysql --defaults-file="C:\Program Files\MySQL\MySQL Server 5.6\my.ini"

8. 查看是否开启binlog

show variables like'log_%';

On:表示已开启

9. 创建数据库canal用户

官网是%,%是对所有非本地主机授权,不包括localhost。由于我们是在windows本机上做,所以需要配置为localhost.

10. 修改canal-deploy-> conf\example里的instance.properties

这两个新添的配置可以注解调,还不太明白具体的用处,可能是testdb 的 账号密码

  1. canal.instance.tsdb.dbUsername=canal
  2. canal.instance.tsdb.dbPassword=canal

注:这里的slaveId=1234不能和my.ini的一样

11. 在cmd下启动canal-deploy

如果没有报错那就是启动成功了

12. 创建canal-client服务

Pom或者gradle。主要依赖:

  1. compile group: 'org.jetbrains', name: 'annotations', version: '13.0'
  2. compile group: 'com.alibaba.otter', name: 'canal.client', version: '1.0.25'

13. 编写客户端类

  1. package com.shao.demo.canalclient;
  2. import java.net.InetSocketAddress;
  3. import java.util.List;
  4. import com.alibaba.otter.canal.client.CanalConnector;
  5. import com.alibaba.otter.canal.common.utils.AddressUtils;
  6. import com.alibaba.otter.canal.protocol.Message;
  7. import com.alibaba.otter.canal.protocol.CanalEntry.Column;
  8. import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
  9. import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
  10. import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
  11. import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
  12. import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
  13. import com.alibaba.otter.canal.client.*;
  14. import org.jetbrains.annotations.NotNull;
  15. /**
  16. * @author zhiqi.shao
  17. * @Date 2018/6/4 18:29
  18. */
  19. public class ClientSample {
  20. public static void main(String args[]) {
  21. // 创建链接
  22. CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(AddressUtils.getHostIp(),
  23. 11111), "example", "", "");
  24. int batchSize = 1000;
  25. int emptyCount = 0;
  26. try {
  27. connector.connect();
  28. connector.subscribe(".*\\..*");
  29. connector.rollback();
  30. int totalEmtryCount = 1200;
  31. while (emptyCount < totalEmtryCount) {
  32. Message message = connector.getWithoutAck(batchSize);
  33. // 获取指定数量的数据
  34. long batchId = message.getId();
  35. int size = message.getEntries().size();
  36. if (batchId == -1 || size == 0) {
  37. emptyCount++;
  38. System.out.println("empty count : " + emptyCount);
  39. try {
  40. Thread.sleep(1000);
  41. } catch (InterruptedException e) {
  42. e.printStackTrace();
  43. }
  44. } else {
  45. emptyCount = 0;
  46. // System.out.printf("message[batchId=%s,size=%s] \n", batchId, size);
  47. printEntry(message.getEntries());
  48. }
  49. connector.ack(batchId); // 提交确认 // connector.rollback(batchId); // 处理失败, 回滚数据 }
  50. System.out.println("empty too many times, exit");
  51. } finally {
  52. connector.disconnect();
  53. }
  54. }
  55. private static void printEntry(@NotNull List<Entry> entrys) {
  56. for (Entry entry : entrys) {
  57. if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
  58. continue;
  59. }
  60. RowChange rowChage = null;
  61. try {
  62. rowChage = RowChange.parseFrom(entry.getStoreValue());
  63. } catch (Exception e) {
  64. throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(),
  65. e);
  66. }
  67. EventType eventType = rowChage.getEventType();
  68. System.out.println(String.format("================> binlog[%s:%s] , name[%s,%s] , eventType : %s",
  69. entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
  70. entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
  71. eventType));
  72. for (RowData rowData : rowChage.getRowDatasList()) {
  73. if (eventType == EventType.DELETE) {
  74. printColumn(rowData.getBeforeColumnsList());
  75. } else if (eventType == EventType.INSERT) {
  76. printColumn(rowData.getAfterColumnsList());
  77. } else {
  78. System.out.println("-------> before");
  79. printColumn(rowData.getBeforeColumnsList());
  80. System.out.println("-------> after");
  81. printColumn(rowData.getAfterColumnsList());
  82. }
  83. }
  84. }
  85. }
  86. private static void printColumn(@NotNull List<Column> columns) {
  87. for (Column column : columns) {
  88. System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());
  89. }
  90. }
  91. }

14. 启动客户端

  1. use canal_test;
  2. CREATE TABLE user (
  3. uid INT(4) PRIMARY KEY NOT NULL AUTO_INCREMENT,
  4. name VARCHAR(10) NOT NULL
  5. );
  6. insert into user (name) values('shaoshao');

15. 关于update

rowData.getAfterColumnsList()

16. 常见错误

  1. 服务端:com.alibaba.otter.canal.parse.exception.CanalParseException: can't find start position for example
    是由于你改了配置文件,导致meta.dat 中保存的位点信息和数据库的位点信息不一致;导致canal抓取不到数据库的动作;
    解决方法:删除meta.dat删除,再重启canal,问题解决;
  2. 客户端:java.lang.OutOfMemoryError: Java heap space
    canal消费端挂了太久,在zk对应conf下节点的
    /otter/canal/destinations/test_db/1001/cursor 位点信息是很早以前,导致重启canal时,从很早以前的位点开始消费,导致canal服务器内存爆掉
  3. 服务端ERROR c.a.otter.canal.server.netty.handler.SessionHandler - something goes wrong with channel:[id: 0x0191aafd, /192.168.10.68:49502 => /192.168.10.68:11111], exception=java.io.IOException:
    当客户端停掉后,canal服务端会报此异常
    客户端:com.alibaba.otter.canal.protocol.exception.CanalClientException: something goes wrong with reason: something goes wrong with channel:[id: 0x01311037, /192.168.10.68:52086 => /192.168.10.68:11111], exception=com.alibaba.otter.canal.server.exception.CanalServerException: destination:example should start first
    当服务端停掉或者重启中,客户端连不上就会抛出此异常。场景修改了服务点的配置文件此时服务端会重启,客户端就会报次异常

17. 消费过滤

canalConnector.subscribe("canal_test\..");//客户端只消费canal_test库的数据变化
subscribe(filter)方法;有的话,filter需要和instance.properties的canal.instance.filter.regex一致,否则subscribe的filter会覆盖instance的配置,如果subscribe的filter是.
\..*,那么相当于你消费了所有的更新数据。

18. 配置

  1. 【instance.properties配置定义优先级高于canal.properties】
  2. 修改了服务端配置文件,服务器会自动重启

19. 关于HA机制的设计

canal server: 为了减少对mysql dump的请求,不同server上的instance要求同一时间只能有一个处于running,其他的处于standby状态.
canal client: 为了保证有序性,一份instance同一时间只能由一个canal client进行get/ack/rollback操作,否则客户端接收无法保证有序。

20. Canal的工作原理

原理相对比较简单:

  1. canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
  2. mysql master收到dump请求,开始推送binary log给slave(也就是canal)
  3. canal解析binary log对象(原始为byte流)

21. 链接方式(参考:http://www.importnew.com/25189.html

1. HA配置架构图

2. 单连

3. 两个client+两个instance+1个mysql

当mysql变动时,两个client都能获取到变动

4. 一个server+两个instance+两个mysql+两个client

5. instance****的standby配置

Standby:备库

22. 总结

这里总结了一下Canal的一些点,仅供参考:

  1. 原理:模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议;mysql master收到dump请求,开始推送binary log给slave(也就是canal);解析binary log对象(原始为byte流)
  2. 重复消费问题:在消费端解决。
  3. 采用开源的open-replicator来解析binlog
  4. canal需要维护EventStore,可以存取在Memory, File, zk
  5. canal需要维护客户端的状态,同一时刻一个instance只能有一个消费端消费
  6. 数据传输格式:protobuff
  7. 支持binlog format 类型:statement, row, mixed. 多次附加功能只能在row下使用,比如otter
  8. binlog position可以支持保存在内存,文件,zk中
  9. instance启动方式:rpc/http; 内嵌
  10. 有ACK机制
  11. 无告警,无监控,这两个功能都需要对接外部系统
  12. 方便快速部署。

23. 我调试成功的代码地址

https://gitee.com/zhiqishao/canal-client

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/911107
推荐阅读
相关标签
  

闽ICP备14008679号