zoukankan      html  css  js  c++  java
  • 学习用Node.js和Elasticsearch构建搜索引擎(5):mac本机部署canal

    1、背景介绍

    最近做的一个项目需要快速检索数据,经过商讨后采用了ElasticSearch作为快速检索数据引擎,但是数据如何同步到ES中是个问题,我们最开始计划了定时任务、mysql trigger等方式,最后选择了比较好的canal组件,通过canal同步mysql中的数据到ES中,所以要学习一下canal。

    2、canal介绍

    早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于trigger的方式获取增量变更,不过从2010年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务,从此开启了一段新纪元。

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

    基于日志增量订阅&消费支持的业务:

    1. 数据库镜像
    2. 数据库实时备份
    3. 多级索引 (卖家和买家各自分库索引)
    4. search build
    5. 业务cache刷新
    6. 价格变化等重要业务消息

    canal更多相关信息参见:https://github.com/alibaba/

    3、开启MySQL的binlog功能

    1)、canal的原理是基于mysql binlog技术,所以这里一定需要开启mysql的binlog写入功能,建议配置binlog模式为row.

    mysql的安装可以去官网看:https://dev.mysql.com/downloads/mysql/

    本人机器上安装的mysql是5.6.19-osx10.7-x86_64,安装位置在/usr/local/mysql,下面修改mysql目录下的my.cnf配置文件,

    如果你的目录下没有该文件,没关系,新建一个就可以,注意下面标红的文字为新添加的内容。

    注意:修改my.cnf文件可能没有权限,那就重新设置一下权限再修改。另外不要把该文件设置成everyone可读写,不然mysql服务会认为该文件不安全,在读取时启动会跳过此文件。

    # For advice on how to change settings please see
    # http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
    
    [mysqld]
    
    # Remove leading # and set to the amount of RAM for the most important data
    # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
    # innodb_buffer_pool_size = 128M
    
    # Remove leading # to turn on a very important data integrity option: logging
    # changes to the binary log between backups.
    # log_bin
    log-bin = mysql-bin #开启binlog
    binlog-format = ROW #选择row模式
    server_id = 1 #配置mysql replication需要定义,不能喝canal的slaveId重复
    
    # These are commonly set, remove the # and set as required.
    # basedir = .....
    # datadir = .....
    # port = .....
    # server_id = .....
    # socket = .....
    
    # Remove leading # to set options mainly useful for reporting servers.
    # The server defaults are faster for transactions and fast SELECTs.
    # Adjust sizes as needed, experiment to find the optimal values.
    # join_buffer_size = 128M
    # sort_buffer_size = 2M
    # read_rnd_buffer_size = 2M 
    
    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES 

    2)、canal的原理是模拟自己为mysql slave,所以这里一定需要做为mysql slave的相关权限. 

    先启动mysql服务(如果没启动的话)。

    系统偏好设置—>最底下有一个mysql图标,点开

    点击start MySQL Server,启动mysql服务成功后会显示绿色的running.

    接下来打开命令行工具iTerm.

    $> mysql -uroot -p  #使用root账号登录mysql
    ...
    mysql> CREATE USER canal IDENTIFIED BY 'canal'; #创建用户canal密码也是canal
    mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; #授权部分需要的权限
    -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%';  #也可以用这个授权所有权限
    mysql>FLUSH PRIVILEGES; #刷新权限列表
    
    mysql>show variables like '%log%'; #看看先前开启的binlog是否生效了,没有的话重启一下mysql服务看看,还有问题就去看看mysql的错误日志
    +-----------------------------------------+------------------------------------------+
    | Variable_name | Value |
    +-----------------------------------------+------------------------------------------+
    | binlog_format | ROW |
    ...
    | log_bin | ON |

     3、部署canal server 

    1)、下载canal server.

    大家可以到这个地址 https://github.com/alibaba/canal/releases 去下载canalserver文件。我下载的是canal.deployer-1.0.24.tar.gz

    我下载之后解压并重命名成canal放在了/usr/local/目录下,由于官方的这个文件是已经编译好的,我们自己就不需要再编译了。

    在canal/bin目录下有几个脚本文件,startup.sh 启动服务用的,stop.sh 停止服务用的,startup.bat是windows下启动服务用的。

    在canal/logs目录下放的是日志文件。

    在canal/conf目录下放的是配置文件。

    2)、配置canal server应用参数:

    如果是跟着本教程来,按照下面的配置就行了

    $>cd /usr/local/canal/
    canal> vi conf/example/instance.properties

    ################################################
    ## mysql serverId
    canal.instance.mysql.slaveId = 1234

    # position info
    canal.instance.master.address = 127.0.0.1:3306
    canal.instance.master.journal.name =
    canal.instance.master.position =
    canal.instance.master.timestamp =

    #canal.instance.standby.address =
    #canal.instance.standby.journal.name =
    #canal.instance.standby.position =
    #canal.instance.standby.timestamp =

    # username/password
    canal.instance.dbUsername = canal
    canal.instance.dbPassword = canal
    canal.instance.defaultDatabaseName = 
    canal.instance.connectionCharset = UTF-8

    # table regex
    canal.instance.filter.regex = ...

    3)、启动canal server 

    $>cd /usr/local/canal
    canal> bin/startup.sh #启动服务
    ....
    启动完成后看一下日志
    canal> vi logs/canal/canal.log

    2017-05-26 15:56:41.994 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## start the canal server.
    2017-05-26 15:56:42.063 [main] INFO com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[172.16.96.181:11111]
    2017-05-26 15:56:42.511 [main] INFO com.alibaba.otter.canal.deployer.CanalLauncher - ## the canal server is running now ......

      看一下具体instance的日志
      canal>vi logs/example/example.log

    2017-05-26 15:56:42.248 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
    2017-05-26 15:56:42.253 [main] INFO c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
    2017-05-26 15:56:42.295 [main] WARN org.springframework.beans.TypeConverterDelegate - PropertyEditor [com.sun.beans.editors.EnumEditor] found through deprecated global PropertyEditorManager fallback - consider using a more isolated form of registration, e.g. on the BeanWrapper/BeanFactory!
    2017-05-26 15:56:42.367 [main] INFO c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example
    2017-05-26 15:56:42.469 [main] INFO c.a.otter.canal.instance.core.AbstractCanalInstance - subscribe filter change to .*..*
    2017-05-26 15:56:42.469 [main] INFO c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
    2017-05-26 15:56:42.469 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN c.a.otter.canal.parse.inbound.mysql.MysqlEventParser - prepare to find start position just show master status

     出现上面类型的日志就说明启动成功了。

     本人遇到过下面的错误日志:

    2017-05-26 15:45:08.317 [main] INFO  c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
    2017-05-26 15:45:08.323 [main] INFO  c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
    2017-05-26 15:45:08.376 [main] WARN  org.springframework.beans.TypeConverterDelegate - PropertyEditor [com.sun.beans.editors.EnumEditor] found through deprecated global PropertyEditorManager fallback - consider using a more isolated form of registration, e.g. on the BeanWrapper/BeanFactory!
    2017-05-26 15:45:08.482 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 
    2017-05-26 15:45:08.608 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - subscribe filter change to .*..*
    2017-05-26 15:45:08.609 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
    2017-05-26 15:45:08.616 [destination = example , address = /127.0.0.1:3306 , EventParser] ERROR c.a.otter.canal.parse.inbound.mysql.MysqlEventParser - dump address /127.0.0.1:3306 has an error, retrying. caused by 
    com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect /127.0.0.1:3306 failure:java.io.IOException: Error When doing Client Authentication:ErrorPacket [errorNumber=1045, fieldCount=-1, message=Access denied for user 'canal'@'localhost' (using password: YES), sqlState=28000, sqlStateMarker=#]
        at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.negotiate(MysqlConnector.java:208)
        at com.alibaba.otter.canal.parse.driver.mysql.MysqlConnector.connect(MysqlConnector.java:71)
        at com.alibaba.otter.canal.parse.inbound.mysql.MysqlConnection.connect(MysqlConnection.java:56)
        at com.alibaba.otter.canal.parse.inbound.mysql.MysqlEventParser.preDump(MysqlEventParser.java:86)
        at com.alibaba.otter.canal.parse.inbound.AbstractEventParser$3.run(AbstractEventParser.java:157)
        at java.lang.Thread.run(Thread.java:745)

    这个是canal@localhost的权限有问题,大家可以参照第的3—2节中,不用%,重新设置一下canan@localhost的权限就行了

    $> mysql -uroot -p  #使用root账号登录mysql
    ...
    mysql> CREATE USER canal@localhost IDENTIFIED BY 'canal'; #创建用户canal密码也是canal
    mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'localhost'; #授权部分需要的权限
    -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'localhost';  #也可以用这个授权所有权限
    mysql>FLUSH PRIVILEGES; #刷新权限列表

    4)、关闭服务。(这个暂时不执行了,让服务开着)

    $>cd /usr/local/canal
    canal> bin/stop.sh

    4、运行cancal client实例

    官网上有一个client例子,地址:https://github.com/alibaba/canal/tree/master/example/src/main/java/com/alibaba/otter/canal/example

    本人按照这个例子搭建了一个测试。

    本人eclipse工具好长时间没用起不来了,直接下载了开发工具intellij idea (v2017.1.3)。

    1)、创建一个新工程,类型选择Maven,Project SDK我选择的jdk1.7,1.8应该也可以(我没试过),直接next.

    2)、填写GroupId,ArtifactId,Version,这三个自己随便写吧。然后next。

    3)、工程名称地址默认就算了。 然后点finish.选择OK.

    4)、工程初始化成成功了,有一个小提示:Maven projects need to be imported ,选择Enable Auto-Import。

    5)、找到工程中的pom.xml文件,增加依赖,如下

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.jerry.happy</groupId>
        <artifactId>SimpleCanalClientTest</artifactId>
        <version>1.0.1</version>
    
        <dependencies>
            <dependency>
                <groupId>com.alibaba.otter</groupId>
                <artifactId>canal.client</artifactId>
                <version>1.0.24</version>
            </dependency>
        </dependencies>
    
    </project>

    6)、导入依赖。File->Project Structrue(或者快捷键cmd+;)打开工程设置。选择Modules,选择Dependencies,如下图勾选。

    如果没有选项,在工程上右键Run Maven->install 再试。 然后OK.

    7)、写代码。在java目录下创建包com.jerry.happy,并把官网地址:https://github.com/alibaba/canal/tree/master/example/src/main/java/com/alibaba/otter/canal/example中的两个文件

    AbstractCanalClientTest.java 和 SimpleCanalClientTest 拷过来,注意包名用现在自己的。

    8)、启动程序。选中SimpleCanalClientTest.java文件,右键Run 'SimpleCanalCli...main()' 执行启动。

    程序启动后,在下面控制台中看看,没有报错就是成功了。

    9)打开控制台操作数据库,触发数据库变更看效果。

    $> mysql -uroot -p  #使用root账号登录mysql

    mysql> use test; #切换数据库
    ERROR 1049 (42000): Unknown database 'test'
    mysql> create database test; #没有test数据库,创建一个
    Query OK, 1 row affected (0.00 sec)

    
    

    mysql> use test; #切换到test数据库
    Database changed
    mysql> CREATE TABLE `xdual` (`ID` int(11) NOT NULL AUTO_INCREMENT,`X` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ;  
    Query OK, 0 rows affected (0.01 sec) #成功创建一张表xdual

    
    

    mysql> insert into xdual(id,x) values(null,now());
    Query OK, 1 row affected (0.01 sec) #给表xdual中成功增加一条数据

    我们可以到intellij idea工具的控制台中看到如下类似记录,说明canal触发了,整个canal本机部署及测试通过。

    OK!。

  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/fhen/p/6909103.html
Copyright © 2011-2022 走看看