sgg快餐项目-2项目前数据同步

一、同步策略选择

数据同步就是通过同步工具将数据拿到数仓中。

同步策略:

  • 全量同步:每次同步将表的所有数据都同步过来。

优点:同步逻辑简单,使用简单

缺点:有数据冗余。

适用于数据量小的情况。

  • 增量同步:只同步改变的数据。

增量同步通常在首日需要做全量同步。

优点:没有数据冗余

缺点:同步逻辑相对比较复杂,使用比较麻烦。

适用于数据量大,变化频率低的数据。(如果数据量大且变化频率高,建议全量同步)

针对本快餐项目,哪些表使用增量,哪些使用全量?

全量同步通常使用DataX、Sqoop等基于select的离线同步工具。而增量同步既可以使用DataX、Sqoop等工具,也可使用Maxwell、Canal等工具, 在本项目中,全量使用DataX,增量使用Maxwell。

 二、Datax安装部署

2.1 DataX简介

简介:DataX 是阿里巴巴开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。(把hdfs导入到mysql,把mysql数据导入到hdfs)

总结:DataX就是不同数据源之间的桥梁。

2.2 DataX架构

2.3 DataX运行流程

  • job: 发起一个数据采集任务,就是一个job.

  • Taskgroup的并发:比如一个taskgroup里边有10个任务,但是他的并发数是5,那么他会同时5个task一起跑,跑完其他的再跑.

2.4 dataX调度

2.5 DataX安装部署

        安装DataX

  • 将datax安装包上传到/opt/software
  • 解压到/opt/module并且改名字

datax安装之后不需要进行任何的配置就可以使用,那怎么用?

(根据以往的组件使用经验,一般都是在bin目录下有个脚本,然后运行这个脚本就可以启动或停止)

cd /opt/module/datax/bin
python /opt/module/datax/bin/datax.py /opt/module/datax/job/job.json

-- 注意DataX的作用就是把数据从某个数据源读出来,再写入某个数据源。

  使用/opt/module/datax/bin/datax.py 文件,该文件运行的话需要一个配置文件,该配置文件会指明一些参数:reader在哪,writer在哪等。

-- 那该json文件格式是什么?

 datax提供了生成json文件的模型,我们通过该命令生成json文件模板,然后再对其进行修改。

python bin/datax.py -r mysqlreader -w hdfswriter

2.6  同步MySQL数据到HDFS案例

案例要求:同步gmall数据库中base_province表数据到HDFS的/base_province目录

需求分析:要实现该功能,需选用MySQLReader和HDFSWriter,MySQLReader具有两种模式分别是TableModeQuerySQLMode,前者使用table,column,where等属性声明需要同步的数据;后者使用一条SQL查询语句声明需要同步的数据。(使用sql语句也会涉及到table,column,where,只不过使用sql语句。)

1.准备json文件:github.com 从该github网址下,mysql读的地方,复制json模板。(tablemodule)

{
    "job": {
        "setting": {
            "speed": {
                 "channel": 3  # 并发度
            },
            "errorLimit": {
                "record": 0,
                "percentage": 0.02
            }
        },
        "content": [
            {
                "reader": {
                    "name": "mysqlreader",
                    "parameter": {
                        "username": "root",
                        "password": "000000",  # mysql的账户和密码
                        "column": [
                            "id",
                            "create_time",
                            "phone_number"   # 读取哪些列的数据。
                        ],
                        "splitPk": "id",  # 表示使用哪个字段对表进行切片,一般推荐使用主键,不切片就不写,表示一个表一个切片,这是切片会分成多个task读取。
                        "where":"id<=100 and id>=5"  # 条件
                        "connection": [
                            {
                                "table": [
                                    "customer"  # 导哪张表的数据,如果是多张表必须保证表的字段一样。
                                ],
                                "jdbcUrl": [
     "jdbc:mysql://hadoop102:3306/fast_food"  # mysql库的地址
                                ]
                            }
                        ]
                    }
                },
               

2.把该json文件中的writer部分删除,还是在刚才的网址,复制hdfs的writer部分。

"writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "hdfs://hadoop102:8020",  # hdfs地址
                        "fileType": "text",  # 保存数据的形式
                        "path": "/datas",  # 保存数据的路径
                        "fileName": "customer",  # 文件名的前缀,hdfswriter写入时的文件名,实际执行时会在文件名后添加随机的后缀作为实际文件名
                           # column:读几个字段,写几个字段,不支持部分写入
                        "column": [
                            {
                                "name": "id",
                                "type": "string"
                            },
                            {
                                "name": "create_time",
                                "type": "string"
                            },
                            {
                                "name": "phone_nuber",
                                "type": "string"
                            }
                            
                        ],
                        "writeMode": "append",  # append 有该文件时,追加 |nonconflict 有该文件时报错|truncate 有该文件时,清除再写入
                        "fieldDelimiter": "\t",
                    }
                }
            }
        ]
    }
}

3.在/opt/module/datax/job目录下,创建该文件,取名test.json

4.启动:python bin/datax.py job/test.json(这样会报错,因为hdfs写数据的哪个目录必须先存在)

5.创建datas目录: hdfs dfs -mkdir /datas,之后在执行。

注意:

  1. datax读写数据是为了将数据导入到数据仓库,比如从sql中读数据,然后写到hdfs上,后边hive就可以拿hdfs的数据去分析。
  2. hdfs写数据由两种type:text和orc
  • 使用text时,列名可以随便写,因为text的方式,列名不会被保存,但是列的类型要和后续hive建表时的类型一致。
  • 使用orc时,列名和类型必须和hive表一致.

QuerySQLMode的形式配置和上边不同的是:不需要where,colunm,table,在connection下添加一个querysql字段:

一个sql语句是一个切片。

"querySql":
{"select id ,create_time,phone_number from customer where id >=5 and id <=100"}

 2.7 同步HDFS数据到MySQL

案例要求:同步HDFS上的/base_province目录下的数据到MySQL gmall数据库下的test_province表。

需求分析:要实现该功能,需选用HDFSReaderMySQLWriter

2.8 DataX传参 

在把数据写到hdfs上时,(如2.6),需要配置一个hdfs的位置来保存这个数据,但是实际生产中,每天上传数据的目录不一样,这时候需要将目录以参数的方式传给DataX的json文件。

1.首先需要在hdfs上创建相应的目录。

hdfs dfs -mkdir /datas/2023-06-16

2.修改hdfs上边写的路径:

"path":"datas/"--->
"path":"datas/${dt} # 这里使用shell脚本的方式进行接收参数。

3.将参数传递给配置文件

python bin/datax.py -p "-Ddt=2023-06-16" job/test.json

2.9 DataX的优化 

2.9.1 速度调整

这里的限速表示多少条数据。 

channel表示并发数,同时跑几个task。

 配置示例:

{
    "core": {
        "transport": {
            "channel": {
                "speed": {
                    "byte": 1048576 //单个channel byte限速1M/s
                }
            }
        }
    },
    "job": {
        "setting": {
            "speed": {
                "byte" : 5242880 //总byte限速5M/s
            }
        },
        ...
    }
}

2.9.2 内存调整

对应job里边有对应的channel,channel会占用内存,当channel并发比较多时,占用内存就比较多,因为DataX作为数据交换通道,在内存中会缓存较多的数据。例如Channel中会有一个Buffer,作为临时的数据交换的缓冲区,而在部分Reader和Writer的中,也会存在一些Buffer,为了防止OOM等错误,需调大JVM的堆内存。

建议将内存设置为4G或者8G,这个也可以根据实际情况来调整。

怎样调整?

调整JVM xms xmx参数的两种方式:一种是直接更改datax.py脚本;另一种是在启动的时候,加上对应的参数,如下:

python datax/bin/datax.py --jvm="-Xms8G -Xmx8G" /path/to/your/job.json

2.10 datax只在Hadoop02上配置了。 

 三、全量数据同步

3.1 数据通道

全量表数据由DataX从MySQL业务数据库直接同步到HDFS,具体数据流向,如下图所示。

  •  其中,在hdfs上,/origin_data 表示目录,/fast_food/表示不同的库,/db表示业务数据,/*full表示全量同步的某个表的名字,/2023-06-14表示哪天同步的。

 3.2 编写相关json脚本

这里已经在上边示例过了,不再过多解释。

{
  "job": {
    "content": [
      {
        "reader": {
          "name": "mysqlreader",
          "parameter": {
            "column": [
              "id",
              "create_time",
              "update_time",
              "name",
              "phone_number",
              "type",
              "region_id"
            ],
            "connection": [
              {
                "jdbcUrl": [
                  "jdbc:mysql://hadoop102:3306/fast_food?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8"
                ],
                "table": [
                  "shop"
                ]
              }
            ],
            "password": "000000",
            "splitPk": "",
            "username": "root"
          }
        },
        "writer": {
          "name": "hdfswriter",
          "parameter": {
            "column": [
              {
                "name": "id",
                "type": "bigint"
              },
              {
                "name": "create_time",
                "type": "string"
              },
              {
                "name": "update_time",
                "type": "string"
              },
              {
                "name": "name",
                "type": "string"
              },
              {
                "name": "phone_number",
                "type": "string"
              },
              {
                "name": "type",
                "type": "bigint"
              },
              {
                "name": "region_id",
                "type": "bigint"
              }
            ],
            "compress": "gzip",
            "defaultFS": "hdfs://hadoop102:8020",
            "fieldDelimiter": "\t",
            "fileName": "shop",
            "fileType": "text",
            "path": "${targetdir}",
            "writeMode": "truncate",
            "nullFormat": ""
          }
        }
      }
    ],
    "setting": {
      "speed": {
        "channel": 1
      }
    }
  }
}
  • vim  /job/test4.json 首先把上边内容创建为脚本。
  • hdfs dfs -mkdir  -p /datas/shop/2023-06-17  在hdfs上边创建目录,因为下一步要把mysql的数据导入到hdfs上的该目录下。
  • 查看hadoop102:9870发现确实有创建的目录。
  • 接下来开始导入数据:python bin/datax.py -p "-Dtargetdir=/datas/shop/2023-06-17"  job/test4.json

我们可以发现,在导不同表中的数据的时候,字段,条件、表名等都要对应相应的表进行更改,所以不同的表json文件不同,所以我们要为每张表编写一个DataX的json配置文件。 

 3.3 全量表json文件生成。

针对不同的表生成不同的json文件用于导入数据。(拿来就用)

  1. 创建/opt/module/gen_datax_config。
  2. 将生成器上传到服务器的/opt/module/gen_datax_config目录。
  3. 上传这两个包到该目录下。
  4. jar包是用来生成json文件的,那生成哪些json文件?在configuration.properties中配置。
  5. 配置好jar包需要的配置之后,使用java -jar 运行该jar包。
  6. 在/opt/module/datax/job/import/下会发现生成好了这些表的json文件。
  7. 随便运行一个可以成功。
  8. 感觉该jar包是用来生成json文件的,用java写的,该包用python写也可以。

3.4 全量表数据同步脚本

每个表每天都要全量同步,所以为了避免每天都得执行同步命令,所以封装一个全量同步脚本。(拿来就用)

#!bin/bash
#mysql_to_hdfs_full.sh/表名|日期
#1.判断参数是否传入。
if [ $# -lt 1]
then 
echo "必须传入参数"
fi

# 2、判断日期是否传入,如果日期传入,那么全量导该日期的数据,否则导前一天的数据。
["$2"] && datastr=$2 || datastr=$(date -d "-1 day" +%F)


# 这里写一个函数,供3使用
function import_data(){
       tableNames=$*
       for tablename in ${tableNames}
       do 
            #判断hdfs上边对应的目录是否存在,不存在则创建,“hdfs dfs -test -e 目录” 如果存在返回0,不存在返回1
            hdfs dfs -test -e /origin_data/fast_food/db/${tablename}_full/${datastr}
            if [ $? -eq 1 ]
            then  
                   hdfs dfs -mkdir -p  /origin_data/fast_food/db/${tablename}_full/${datastr}
            fi
            python /opt/module/datax/bin/datax.py -p"Dtargetdir=/origin_data/fast_food/db/${tablename}_full/${datastr}" /opt/module/datax/job/import/fast_food.${tablename}.json
        

       done


}

# 3 根据传进来的表名匹配数据
case $1 in 
"all")
import data "shop" "region" "promotion" "product_spu_attr" "product_spu_attr_value" "product_spu" "product_sku" "product_group" "product_category" "product_group_sku"
;;

"shop")
import_data $1
;;

"region")
import_data $1
;;

"promotion")
import_data $1
;;

"product_spu_attr")
import_data $1
;;

"product_spu_attr_value")
import_data $1
;;

"product_spu")
import_data $1
;;

"product_sku")
import_data $1
;;

"product_group")
import_data $1
;;

"product_group_sku")
import_data $1
;;

"product_category")
import_data $1
;;

*)
echo "表名输入错误"
  • 然后: vim /home/bigdata/bin/mysql_to_hdfs_full.sh 创建该bash文件。
  • chmod +x  /home/bigdata/bin/mysql_to_hdfs_full.sh
  • mysql_to_hdfs_full.sh all 2023-06-05

之后 全量数据 同步只需要每天执行该脚本即可。

四、增量数据同步

4.1 概述

增量数据这里使用maxwell导入的,maxwell不会直接把数据保存导hdfs,而是先把数据放在kafka上(以json的形式),然后flume把数据从kafka上提取出来,保存到hdfs。

Maxwell的原理:Maxwell的原理在该系列第一篇帖子里讲过,他会实时监控mysql的binlog日志,数据库的数据变更操作(增、删、改),将变更的操作以json的形式,发送给kafka的主题。这里启动mysql的binlog[mysql的binlog是默认关闭的],设置binlog的类型,设置启用binlog的数据库(都是在/etc/my.cnf 中配置,这是数据库的配置文件);把收集的数据发送给谁?发送给kafka的哪个主题?kafka集群在哪里?maxwell收集到的元数据放在那里?

4.2  flume配置

Flume需要将Kafka中topic_db主题的数据传输到HDFS,选用KafkaSource、HDFSSink以及FileChannel。 (从kafka读数据,保存到hdfs,数据是业务数据,不能丢,所以用filechannel[memory channel不用])

  • source将event写入channel之前,可以对event进行各种形式的拦截,根据 event 中 Header 的某个 key 的值,将不同的 event 发送到不同的 Channel中.(每个agent有多个channel?)
  • source和channel之间可以有多个拦截器
  • 不同的拦截器使用不同的规则处理event.

flume配置和拦截器:

首先写flume的配置文件,配置source,channel,sink。 

# 1.agent,source,sink,channel取名
a1.sources=r1
a1.channels=c1
a1.sinks=k1
# 这里a1表示这个agent的名字。


#2.描述source

a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
## kafka消费者组的名字
a1.sources.r1.kafka.consumer.group.id=g1 
#消费者topic的名称 
a1.sources.r1.kafka.topics = topic_db
# a1.sources.r1.kafka.topics = test1, test2
# 指定source的批次大小
a1.sources.r1.batchSize = 100
# 指定消费者组第一次消费topic的时候应该从那个位置开始消费,earliest表示从offset为0的位置开始消费。
a1.sources.r1.kafka.consumer.auto.offset.reset=earliest

# 2.1. 描述拦截器
#设置一个flume拦截器 这里是因为不同的数据要保存在不同的文件下(按照表名,日期等)
#这里的拦截器就是指把表名,日期等信息,从evet中取出来,加到event的header里,为了放在sink中使用
# 这里 event的header是一个map:event[header={"name":'data_info',"timestamp":'ts'}]

a1.sources.r1.interceptors=i1
a1.sources.r1.interceptors.i1.type=com.atguigu.interceptor.TableNameAndTimestampInterceptor$Builder



#3.描述channel

a1.channels.c1.type = file
# file channel里边有一片内存区域,里边保存的是还没有被sink拉走的event的指针,每个指针指向的是event的位置,但是内存的东西不安全
# 一旦flume挂掉,这个指针就消失了,所以指定一个指针保存的位置。
a1.channels.c1.checkpointDir =  /opt/module/flume/checkpoint
# file channel的数据是放在本地磁盘的,那么放在哪里?
a1.channels.c1.dataDirs = /opt/module/flume/datas
# channel的事物容量大小,要大于批次大小,事务容量1000,batchsize为100,放10个批次开始进入channel
a1.channels.c1.transactionCapacity=1000
# 指定channel容量大小,>=事务容量大小
a1.channels.c1.capacity=1000000

#4.描述sink

a1.sinks.k1.type = hdfs
# 数据保存到哪里
a1.sinks.k1.hdfs.path = /origin_data/fast_food/db/${tableName}_inc/%Y-%m-%d

# 保存到hdfs的文件名的前缀
a1.sinks.k1.hdfs.filePrefix = db_
# flume往hdfs写数据的时候,写多少秒就换一个文件写。一般一个小时
a1.sinks.k1.hdfs.rollInterval=30
# flume往hdfs写数据的时候写多大数据量的时候就换个文件
a1.sinks.k1.hdfs.rollSize = 131072000 # 单位是字节 125Mb*1024*1024
# 往文件里边写几个event就换个文件。设为0表示禁用,因为每个event表示一条数据,每条数据大小不一样。
a1.sinks.k1.hdfs.rollCount = 0
# 设置批次大小
a1.sinks.k1.hdfs.batchSize=100
# 指定保存的文件类型-->压缩和压缩格式
a1.sinks.k1.hdfs.fileType=CompressedStream
a1.sinks.k1.hdfs.codeC=gzip

#5.关联三者
a1.sinks.k1.channel = c1
a1.sources.r1.channels =c1

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值