Maxwell:实时监控MySQL数据库的数据变更操作(包括增删改),并以JSON格式发送给Kafka

官网地址:http://maxwells-daemon.io/

在这里插入图片描述
在这里插入图片描述

字段解释
database变更数据所属的数据库
table表更数据所属的表
*type*数据变更类型
*ts*数据变更发生的时间
xid事务id
commit事务提交标志,可用于重新组装事务
*data*对于insert类型,表示插入的数据;对于update类型,标识修改之后的数据;对于delete类型,表示删除的数据
*old*对于update类型,表示修改之前的数据,只包含变更字段
Maxwell原理
·实时读取mysql数据库中的二进制日志(binlog),从中获取变更数据,再将变更数据以JSON格式发送至Kafka;
maxwell将自己伪装成slave,并遵循MySQL主从复制的协议,从master同步数据
·MySQL主从复制
·maxsql的binlog模式
	·statement based:基于语句
	·Row-based:基于行
	·mixed:混合模式,默认
	statement based,可能导致数据不一致的自动切换Row-based

在这里插入图片描述

Maxwell安装部署
地址:https://github.com/zendesk/maxwell/releases/download/v1.29.2/maxwell-1.29.2.tar.gz(注:Maxwell-1.30.0及以上版本不再支持JDK1.8。)
·修改mysql配置---/etc/my.conf
	·增加配置
		#数据库id
		server-id = 1
		#启动binlog,该参数的值会作为binlog的文件名
		log-bin=mysql-bin
		#binlog类型,maxwell要求为row类型
		binlog_format=row
		#启用binlog的数据库,需根据实际情况作出修改
		binlog-do-db=gmall
·Maxwell需要在MySQL中存储其运行过程中的所需的一些数据,包括binlog同步的断点位置(Maxwell支持断点续传)等等,故需要在MySQL为Maxwell创建数据库及用户。
·创建maxwell数据库以及用户
	·创建数据库
		·CREATE DATABASE maxwell;
	·如果没有初始化mysql,需要调整策略级别
    	·set global validate_password_policy=0;
    	·set global validate_password_length=4;
    ·创建maxwell用户并赋予其必要权限
    	· CREATE USER 'maxwell'@'%' IDENTIFIED BY 'maxwell';
    	· GRANT ALL ON maxwell.* TO 'maxwell'@'%';
    	· GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'maxwell'@'%';
·配置maxwell的config.properties
	#Maxwell数据发送目的地,可选配置有stdout|file|kafka|kinesis|pubsub|sqs|rabbitmq|redis
	producer=kafka
	#目标Kafka集群地址
	kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
	#目标Kafka topic,可静态配置,例如:maxwell,也可动态配置,例如:%{database}_%{table}
	kafka_topic=maxwell
	
	#MySQL相关配置
	host=hadoop102
	user=maxwell
	password=maxwell
	jdbc_options=useSSL=false&serverTimezone=Asia/Shanghai
·启停maxwell	
	·/opt/module/maxwell/bin/maxwell --config /opt/module/maxwell/config.properties --daemon
	· ps -ef | grep maxwell | grep -v grep | grep maxwell | awk '{print $2}' | xargs kill -9
Maxwell启停脚本
#!/bin/bash
if [[ $# -lt 1 ]]; then
	echo "Pleace Input Args"
	exit
fi

MAXWELL_HOME=/opt/module/maxwell

status_maxwell(){
	#grep -v grep:过滤掉包含grep的进程性 ; wc -l:wc统计文件的行数:line
	result=`ps -ef |grep maxwell |grep -v grep |wc -l`
	return $result
}

start_maxwell(){
	status_maxwell
	# $?:能调上一个命令的返回结果
	if [[ $? -lt 1 ]]; then
		echo "启动maxwell"
		$MAXWELL_HOME/bin/maxwell --config $MAXWELL_HOME/config.properties --daemon
	else
		echo "Maxwell已经启动,请勿再次启动"
	fi
}

stop_maxwell(){
	status_maxwell
	if [[ $? -eq 0 ]]; then
		echo "Maxwell未启动"
	else
		#xargs之前的结果作为参数传给后面
		ps -ef | grep maxwell |grep -v grep | awk '{print $2}'| xargs kill -9
	fi
}



case $1 in
	"start" )
		start_maxwell
		;;
	"stop" )
		stop_maxwell
		;;
	"restart" )
		stop_maxwell
		start_maxwell
		;;				
esac
使用Maxwell将增量同步的数据导入kafka
·修改maxwell的config.properties
	·Kafka的topic以表名来自动创建
		·kafka_topic=%{table}
	·表过滤(include包含、exclude不包含)
		·filter= include:gmall.cart_info,include:gmall.comment_info,include:gmall.coupon_use
·修改kafka自动创建的topic的分区数与副本数量
	·num.partitions=3
	·default.replication.factor=3
从Kafka上传到hdfs
	·编写agent的.conf
# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source | kafka source 头信息中会自带topic和时间戳,时间为进入flume的时间
a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.kafka.bootstrap.servers = hadoop101:9092,hadoop102:9092,hadoop103:9092
a1.sources.r1.kafka.topics = cart_info,comment_info,coupon_use,favor_info,order_detail_activity,order_detail_coupon,order_detail,order_info,order_refund_info,order_status_log,payment_info,refund_payment,user_info
a1.sources.r1.kafka.consumer.group.id = group
a1.sources.r1.interceptors = i1
a1.sources.r1.interceptors.i1.type = com.collect.interceptor.db.TimestampInterceptor$Builder

# Describe the sink
a1.sinks.k1.type = hdfs
###kafka source中有两个参数 setTopicHeader:默认为true topicHeader:默认为topic;表示头信息中有一对kv值,key为topic、value为kafka的topic,因此在hdfs sink中可以使用占位符%{topic}来直接获取topic
a1.sinks.k1.hdfs.path = /origin_data/gmall/db/%{topic}_inc/%Y-%m-%d

a1.sinks.k1.hdfs.rollInterval = 10
a1.sinks.k1.hdfs.rollSize = 134217728
a1.sinks.k1.hdfs.rollCount = 0
##控制输出文件时原生文件,不序列化同时可以压缩
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = gzip

# Use a channel which buffers events in file
a1.channels.c1.type = file
#如果之前使用过file channel,需要将下面behavior进行修改
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/behavior2
a1.channels.c1.dataDirs = /opt/module/flume/data/behavior2

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1
·拦截器(记得分发到集群lib下)
public class TimestampInterceptor implements Interceptor {
    @Override
    public void initialize() {

    }

    @Override
    public Event intercept(Event event) {
        /*
            需求:将maxwell发送的json数据中的时间戳提取
            放入到event的headers信息中,作为hdfs sink存储目录的时间(占位符)使用
         */
        String body = new String(event.getBody());
        JSONObject js = JSONObject.parseObject(body);
        String ts = js.getString("ts");
        Map<String, String> headers = event.getHeaders();
        headers.put("timestamp",ts + "000");
        return event;
    }

    @Override
    public List<Event> intercept(List<Event> events) {
        for (Event event : events) {
            intercept(event);
        }
        return events;
    }

    @Override
    public void close() {

    }
    public static class Builder implements Interceptor.Builder{
        @Override
        public Interceptor build() {
            return new TimestampInterceptor();
        }

        @Override
        public void configure(Context context) {

        }
    }
}
历史数据全量同步
·对历史数据进行全量同步
	·bin/maxwell-bootstrap --database 数据库名 --table 表名 --config config.properties
·bootstrap数据格式
	注意事项:
		1)第一条type为bootstrap-start和最后一条type为bootstrap-complete的数据,是bootstrap开始和结束的标志,不包含数据,中间的type为bootstrap-insert的数据才包含数据。
		2)一次bootstrap输出的所有记录的ts都相同,为bootstrap开始的时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GambleLife

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值