Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作

Maxwell

maxwell 是由美国zendesk开源,用java编写的Mysql实时抓取软件。 其抓取的原理也是基于binlog。

工具对比

  1. Maxwell 没有 Canal那种server+client模式,只有一个server把数据发送到消息队列或redis。
  2. Maxwell 有一个亮点功能,就是Canal只能抓取最新数据,对已存在的历史数据没有办法处理。而Maxwell有一个bootstrap功能,可以直接引导出完整的历史数据用于初始化,非常好用。
  3. Maxwell不能直接支持HA,但是它支持断点还原,即错误解决后重启继续上次点儿读取数据。
  4. Maxwell只支持json格式,而Canal如果用Server+client模式的话,可以自定义格式。
  5. Maxwell比Canal更加轻量级。

安装并解压

解压缩maxwell-1.25.0.tar.gz 到/opt/module目录下。

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第1张图片

数据库准备

  1. 在数据库中建立一个maxwell库用于存储Maxwell的元数据。
CREATE DATABASE maxwell ;
  1. 并且分配一个账号可以操作该数据库
GRANT ALL   ON maxwell.* TO 'maxwell'@'%' IDENTIFIED BY '123123';
  1. 分配这个账号可以监控其他数据库的权限
GRANT  SELECT ,REPLICATION SLAVE , REPLICATION CLIENT  ON *.* TO maxwell@'%'

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第2张图片

使用Maxwell监控抓取MySql数据

在任意位置建立maxwell.properties 文件(我选在/opt/module/maxwell-1.25.0)

producer=kafka
kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
kafka_topic=ODS_DB_GMALL_M

host=hadoop102
user=maxwell
password=123123

client_id=maxwell_1

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第3张图片

启动程序

/opt/module/maxwell-1.25.0/bin/maxwell --config /opt/module/maxwell-1.25.0/maxwell.properties >/dev/null 2>&1 &

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第4张图片

Kafka监控Topic

kafka-consumer.sh ODS_DB_GMALL_M

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第5张图片

测试

Spark实时项目第五天-Maxwell得安装及Maxwell版本的ODS层分流操作_第6张图片

Maxwell和Canal得特点

  1. 日志结构

canal 每一条SQL会产生一条日志,如果该条Sql影响了多行数据,则已经会通过集合的方式归集在这条日志中。(即使是一条数据也会是数组结构)
maxwell 以影响的数据为单位产生日志,即每影响一条数据就会产生一条日志。如果想知道这些日志是否是通过某一条sql产生的可以通过xid进行判断,相同的xid的日志来自同一sql。

  1. 数字类型

当原始数据是数字类型时,maxwell会尊重原始数据的类型不增加双引,变为字符串。
canal一律转换为字符串。

  1. 带原始字段定义

canal数据中会带入表结构。maxwell更简洁。

完成Maxwell的ODS层分流

增加BaseDBMaxwellApp

在scala\com\atguigu\gmall1122\realtime\app\ods\BaseDBMaxwellApp

import com.alibaba.fastjson.{JSON, JSONArray, JSONObject}
import com.atguigu.gmall.realtime.utils.{MyKafkaSinkUtil, MyKafkaUtil, OffsetManagerUtil}
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.TopicPartition
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.{DStream, InputDStream}
import org.apache.spark.streaming.kafka010.{HasOffsetRanges, OffsetRange}
import org.apache.spark.streaming.{Seconds, StreamingContext}

object BaseDBMaxwellApp {

  def main(args: Array[String]): Unit = {

    val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("ods_base_db_maxwell_app")

    val ssc = new StreamingContext(sparkConf,Seconds(5))
    val topic ="ODS_DB_GMALL_M";
    val groupId="base_db_maxwell_group"

    val offset: Map[TopicPartition, Long] = OffsetManagerUtil.getOffset(groupId,topic)

    var inputDstream: InputDStream[ConsumerRecord[String, String]]=null
    // 判断如果从redis中读取当前最新偏移量 则用该偏移量加载kafka中的数据  否则直接用kafka读出默认最新的数据
    if(offset!=null&&offset.size>0){
      inputDstream = MyKafkaUtil.getKafkaStream(topic,ssc,offset,groupId)
      //startInputDstream.map(_.value).print(1000)
    }else{
      inputDstream  = MyKafkaUtil.getKafkaStream(topic,ssc,groupId)
    }

    //取得偏移量步长
    var offsetRanges: Array[OffsetRange] =null
    val inputGetOffsetDstream: DStream[ConsumerRecord[String, String]] = inputDstream.transform { rdd =>
      offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
      rdd
    }

    val dbJsonObjDstream: DStream[JSONObject] = inputGetOffsetDstream.map { record =>
      val jsonString: String = record.value()
      val jsonObj: JSONObject = JSON.parseObject(jsonString)
      jsonObj

    }

    dbJsonObjDstream.foreachRDD{rdd=>
      rdd.foreachPartition{jsonObjItr=>

        for (jsonObj <- jsonObjItr ) {
          val dataObj: JSONObject = jsonObj.getJSONObject("data")
          val tableName = jsonObj.getString("table")
          val id = dataObj.getString("id")
          val topic = "ODS_T_" + tableName.toUpperCase
          if (tableName=="order_info"&&jsonObj.getString("type").equals("insert")){
            MyKafkaSinkUtil.send(topic, id, dataObj.toJSONString)
          }
        }
      }
      OffsetManagerUtil.saveOffset(groupId,topic,offsetRanges)

    }
    ssc.start()
    ssc.awaitTermination()


  }

}

你可能感兴趣的:(Maxwell,Canal,Gmall)