Spark Streaming可以用于实时流项目的开发,实时流项目的数据源除了可以来源于日志、文件、网络端口等,常常也有这种需求,那就是实时分析处理MySQL中的增量数据。面对这种需求当然我们可以通过JDBC的方式定时查询Mysql,然后再对查询到的数据进行处理也能得到预期的结果,但是Mysql往往还有其他业务也在使用,这些业务往往比较重要,通过JDBC方式频繁查询会对Mysql造成大量无形的压力,甚至可能会影响正常业务的使用,在基本不影响其他Mysql正常使用的情况下完成对增量数据的处理,那就需要 Canal 了。
假设Mysql中 canal_test 库下有一张表 policy_cred ,需要统计实时统计 policy_status 状态为1的 mor_rate 的的变化趋势,并标注比率的风险预警等级。
1. Canal
Canal [kə'næl] 是阿里巴巴开源的纯java开发的基于数据库binlog的增量订阅&消费组件。Canal的原理是模拟为一个Mysql slave的交互协议,伪装自己为MySQL slave,向Mysql Master发送dump协议,然后Mysql master接收到这个请求后将binary log推送给slave(也就是Canal),Canal解析binary log对象。详细可以查阅Canal的官方文档[alibaba/canal wiki]。
1.1 Canal 安装
Canal的server mode在1.1.x版本支持的有TPC、Kafka、RocketMQ。本次安装的canal版本为1.1.2,Canal版本最后在1.1.1之后。server端采用MQ模式,MQ选用Kafka。服务器系统为Centos7,其他环境为:jdk8、Scala 2.11、Mysql、Zookeeper、Kafka。
1.1.1 准备
安装Canal之前我们先把如下安装好
Mysql
a. 如果没有Mysql: 详细的安装过程可参考我的另一篇博客[Centos7环境下离线安装mysql 5.7 / mysql 8.0]
b. 开启Mysql的binlog。修改/etc/my.cnf,在[mysqld]下添加如下配置,改完之后重启 Mysql /etc/init.d/mysql restart
[mysqld]
#添加这一行就ok
log-bin=mysql-bin
#选择row模式
binlog-format=ROW
#配置mysql replaction需要定义,不能和canal的slaveId重复
server_id=1
c. 创建一个Mysql用户并赋予相应权限,用于Canal使用
mysql> CREATE USER canal IDENTIFIED BY 'canal';
mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%';
mysql> FLUSH PRIVILEGES;
Zookeeper
因为安装Kafka时需要Zookeeper,例如ZK安装后地址为:cdh3:2181,cdh4:2181,cdh5:2181
Kafka
例如安装后的地址为:node1:9092,node2:9092,node3:9092
安装后创建一个Topic,例如创建一个 example
kafka-topics.sh --create --zookeeper cdh3:2181,cdh4:2181,cdh5:2181 --partitions 2 --replication-factor 1 --topic example
1.1.2 安装Canal
1. 下载Canal
访问Canal的Release页
wget https://github.com/alibaba/canal/releases/download/canal-1.1.2/canal.deployer-1.1.2.tar.gz
2. 解压
注意 这里一定要先创建出一个目录,直接解压会覆盖文件
mkdir -p /usr/local/canal
mv canal.deployer-1.1.2.tar.gz /usr/local/canal/tar-zxvf canal.deployer-1.1.2.tar.gz
3. 修改instance 配置文件
vim $CANAL_HOME/conf/example/instance.properties,修改如下项,其他默认即可
## mysql serverId , v1.0.26+will autoGen , 不要和server_id重复
canal.instance.mysql.slaveId=3# position info。Mysql的url
canal.instance.master.address=node1:3306# table meta tsdb info
canal.instance.tsdb.enable=false# 这里配置前面在Mysql分配的用户名和密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset=UTF-8# 配置需要检测的库名,可以不配置,这里只检测canal_test库
canal.instance.defaultDatabaseName=canal_test
# enable druid Decrypt database password
canal.instance.enableDruid=false# 配置过滤的正则表达式,监测canal_test库下的所有表
canal.instance.filter.regex=canal_test\\..*# 配置MQ
## 配置上在Kafka创建的那个Topic名字
canal.mq.topic=example
## 配置分区编号为1
canal.mq.partition=1
4. 修改canal.properties配置文件
vim $CANAL_HOME/conf/canal.properties,修改如下项,其他默认即可
# 这个是如果开启的是tcp模式,会占用这个11111端口,canal客户端通过这个端口获取数据
canal.port= 11111# 可以配置为:tcp, kafka, RocketMQ,这里配置为kafka
canal.serverMode=kafka
# 这里将这个注释掉,否则启动会有一个警告
#canal.instance.tsdb.spring.xml= classpath:spring/tsdb/h2-tsdb.xml
##################################################
######### MQ #############
##################################################
canal.mq.servers= node1:9092,node2:9092,node3:9092canal.mq.retries= 0canal.mq.batchSize= 16384canal.mq.maxRequestSize= 1048576canal.mq.lingerMs= 1canal.mq.bufferMemory= 33554432# Canal的batch size, 默认50K, 由于kafka最大消息体限制请勿超过1M(900K以下)
canal.mq.canalBatchSize= 50# Canal get数据的超时时间, 单位: 毫秒, 空为不限超时
canal.mq.canalGetTimeout= 100# 是否为flat json格式对象
canal.mq.flatMessage= truecanal.mq.compressionType=none
canal.mq.acks=all
# kafka消息投递是否使用事务
#canal.mq.transaction= false
5. 启动Canal
$CANAL_HOME/bin/startup.sh
6. 验证
查看日志
启动后会在logs下生成两个日志文件:logs/canal/canal.log、logs/example/example.log,查看这两个日志,保证没有报错日志。
如果是在虚拟机安装,最好给2个核数以上。
确保登陆的系统的hostname可以ping通。
在Mysql数据库中进行增删改查的操作,然后查看Kafka的topic为 example 的数据
kafka-console-consumer.sh --bootstrap-server node1:9092,node2:9092,node3:9092 --from-beginning --topic example
7. 关闭Canal
不用的时候一定要通过这个命令关闭,如果是用kill或者关机