學習用Node.js和Elasticsearch構建搜索引擎(5):mac本機部署canal

一、背景介紹

最近作的一個項目須要快速檢索數據,通過商討後採用了ElasticSearch做爲快速檢索數據引擎,可是數據如何同步到ES中是個問題,咱們最開始計劃了定時任務、mysql trigger等方式,最後選擇了比較好的canal組件,經過canal同步mysql中的數據到ES中,因此要學習一下canal。html

二、canal介紹

早期,阿里巴巴B2B公司由於存在杭州和美國雙機房部署,存在跨機房同步的業務需求。不過早期的數據庫同步業務,主要是基於trigger的方式獲取增量變動,不過從2010年開始,阿里系公司開始逐步的嘗試基於數據庫的日誌解析,獲取增量變動進行同步,由此衍生出了增量訂閱&消費的業務,今後開啓了一段新紀元。java

ps. 目前內部版本已經支持mysql和oracle部分版本的日誌解析,當前的canal開源版本支持5.7及如下的版本(阿里內部mysql 5.7.13, 5.6.10, mysql 5.5.18和5.1.40/48)mysql

基於日誌增量訂閱&消費支持的業務:linux

  1. 數據庫鏡像
  2. 數據庫實時備份
  3. 多級索引 (賣家和買家各自分庫索引)
  4. search build
  5. 業務cache刷新
  6. 價格變化等重要業務消息

canal更多相關信息參見:https://github.com/alibaba/git

三、開啓MySQL的binlog功能

1)、canal的原理是基於mysql binlog技術,因此這裏必定須要開啓mysql的binlog寫入功能,建議配置binlog模式爲row.github

mysql的安裝能夠去官網看:https://dev.mysql.com/downloads/mysql/spring

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

若是你的目錄下沒有該文件,不要緊,新建一個就能夠,注意下面標紅的文字爲新添加的內容。數據庫

注意:修改my.cnf文件可能沒有權限,那就從新設置一下權限再修改。另外不要把該文件設置成everyone可讀寫,否則mysql服務會認爲該文件不安全,在讀取時啓動會跳過此文件。apache

# 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 |

 

 三、部署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

四、運行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!。

相關文章
相關標籤/搜索