大数据下一代变革之必研究数据湖技术Hudi原理实战双管齐下-后续


目录
  • https://github.com/ververica/flink-cdc-connectors

    flink-sql-connector-kafka-1.15.1.jar直接在maven仓库下

    image-20221202093350817

    flink读取mysql binlog写入kafka

    • 创建mysql表
    CREATE TABLE student_binlog (
     id INT NOT NULL,
     name STRING,
     age INT,
     class STRING,
     PRIMARY KEY (`id`) NOT ENFORCED
    ) WITH (
     'connector' = 'mysql-cdc',
     'hostname' = 'mysqlserver',
     'port' = '3308',
     'username' = 'root',
     'password' = '123456',
     'database-name' = 'test',
     'table-name' = 'student'
    );
    
    • 创建kafka表
    create table student_binlog_sink_kafka(
     id INT NOT NULL,
     name STRING,
     age INT,
     class STRING,
     PRIMARY KEY (`id`) NOT ENFORCED
    ) with (
      'connector'='upsert-kafka',
      'topic'='data_test',
      'properties.bootstrap.servers' = 'kafka1:9092',
      'properties.group.id' = 'testGroup',
      'key.format'='json',
      'value.format'='json'
    );
    

    image-20221202112915486

    • 将mysql binlog日志写入kafka
    insert into student_binlog_sink_kafka select * from student_binlog;
    

    image-20221202093022660

    查看Flink的Web UI,可以看到刚才提交的job

    image-20221202091513257

    开启tableau方式查询表

    set 'sql-client.execution.result-mode' = 'tableau';select * from student_binlog_sink_kafka;
    

    往mysql的student表插入和更新数据测试下

    INSERT INTO student VALUES(1,'张三',16,'高一3班');
    COMMIT;
    INSERT INTO student VALUES(2,'李四',18,'高三3班');
    COMMIT;
    UPDATE student SET NAME='李四四' WHERE id = 2;
    COMMIT;
    

    image-20221202092737840

    flink读取kafka数据并写入hudi数据湖

    • 创建Kafka源表
    CREATE TABLE student_binlog_source_kafka (
     id INT NOT NULL,
     name STRING,
     age INT,
     class STRING
    )
    WITH(
        'connector' = 'kafka',
        'topic'='data_test',
        'properties.bootstrap.servers' = 'kafka1:9092',
        'properties.group.id' = 'testGroup',
        'scan.startup.mode' = 'earliest-offset',
        'format' = 'json'
    );
    
    • 创建hudi目标表
    CREATE TABLE student_binlog_sink_hudi (
     id INT NOT NULL,
     name STRING,
     age INT,
     class STRING,
     PRIMARY KEY (`id`) NOT ENFORCED
    )
    PARTITIONED BY (`class`)
    WITH (
      'connector' = 'hudi',
      'path' = 'hdfs://hadoop1:9000/tmp/hudi_flink/student_binlog_sink_hudi',
      'table.type' = 'MERGE_ON_READ',
      'write.option' = 'insert',
      'write.precombine.field' = 'class'
    );
    
    • 将kafka数据写入hudi表
    insert into student_binlog_sink_hudi select * from student_binlog_source_kafka;
    

    mysql中student表新增加2条数据

    INSERT INTO student VALUES(3,'韩梅梅',16,'高二2班');
    INSERT INTO student VALUES(4,'李雷',16,'高二2班');
    COMMIT;
    

    查看HDFS中已经有相应的分区和数据了

    image-20221202113439161

    调优

    Memory

    参数名称 描述 默认值 备注
    write.task.max.size 每个write task使用的最大内存,超过则对数据进行flush 1024MB write buffer使用的内存 = write.task.max.size - compaction.max_memory,当write buffer总共使用的内存超过限制,则将最大的buffer进行flush
    write.batch.size 数据写入batch的大小 64MB 推荐使用默认配置
    write.log_block.size Hudi的log writer将数据进行缓存,等达到该参数限制,才将数据flush到disk形成LogBlock 128MB 推荐使用默认配置
    write.merge.max_memory COW类型的表,进行incremental data和data file能使用的最大heap size 100MB 推荐使用默认配置
    compaction.max_memory 每个write task进行compaction能使用的最大heap size 100MB 如果是online compaction,且资源充足,可以调大该值,如1024MB

    Parallelism

    参数名称 描述 默认值 备注
    write.tasks write task的并行度,每一个write task写入1~N个顺序buckets 4 增加该值,对小文件的数据没有影响
    write.bucket_assign.tasks bucket assigner operators的并行度 Flink的parallelism.default参数 增加该值,会增加bucket的数量,所以也会增加小文件的数量
    write.index_boostrap.tasks index bootstrap的并行度 Flink的parallelism.default参数
    read.tasks read operators的并行度 4
    compaction.tasks online compaction的并行度 4 推荐使用offline compaction

    Compaction

    只适用于online compaction

    参数名称 描述 默认值 备注
    compaction.schedule.enabled 是否定期生成compaction plan true 即使compaction.async.enabled = false,也推荐开启该值
    compaction.async.enabled MOR类型表默认开启Async Compaction true false表示关闭online compaction
    compaction.trigger.strategy 触发compaction的Strategy num_commits 可选参数值:1. num_commits:delta commits数量达到多少;2. time_elapsed:上次compaction过后多少秒;3. num_and_time:同时满足num_commits和time_elapsed;4. num_or_time:满足num_commits或time_elapsed
    compaction.delta_commits 5
    compaction.delta_seconds 3600
    compaction.target_io 每个compaction读写合计的目标IO,默认500GB 512000

    集成Hive

    hudi源表对应一份hdfs数据,可以通过spark,flink 组件或者hudi客户端将hudi表的数据映射为hive外部表,基于该外部表, hive可以方便的进行实时视图,读优化视图以及增量视图的查询。

    集成步骤

    这里以hive3.1.3(关于hive可以详细查看前面的文章)、 hudi 0.12.1为例, 其他版本类似

    将hudi-hadoop-mr-bundle-0.9.0xxx.jar , hudi-hive-sync-bundle-0.9.0xx.jar 放到hiveserver 节点的lib目录下

    cd /home/commons/apache-hive-3.1.3-bin
    cp -rf /home/commons/hudi-release-0.12.1/packaging/hudi-hadoop-mr-bundle/target/hudi-hadoop-mr-bundle-0.12.1.jar lib/
    cp -rf /home/commons/hudi-release-0.12.1/packaging/hudi-hive-sync-bundle/target/hudi-hive-sync-bundle-0.12.1.jar lib/
    

    按照需求选择合适的方式并重启hive

    nohup hive --service metastore &
    nohup hive --service hiveserver2 &
    

    image-20221202140239157

    连接jdbc hive2测试,显示所有数据库

    image-20221202140441756

    Flink同步Hive

    Flink hive sync 现在支持两种 hive sync mode, 分别是 hms 和 jdbc 模式。 其中 hms 只需要配置 metastore uris;而 jdbc 模式需要同时配置 jdbc 属性 和 metastore uris,具体配置示例如下

    CREATE TABLE t7(
      id int,
      num int,
      ts int,
      primary key (id) not enforced
    )
    PARTITIONED BY (num)
    with(
      'connector'='hudi',
      'path' = 'hdfs://hadoop1:9000/tmp/hudi_flink/t7',
      'table.type'='COPY_ON_WRITE', 
      'hive_sync.enable'='true', 
      'hive_sync.table'='h7', 
      'hive_sync.db'='default', 
      'hive_sync.mode' = 'hms',
      'hive_sync.metastore.uris' = 'thrift://hadoop2:9083'
    );
    insert into t7 values(1,1,1);
    

    Hive Catalog

    Flink官网的找到对应文档版本找到connector-hive,下载flink-sql-connector-hive-3.1.2_2.12-1.15.1.jar,上传到flink的lib目录下,建表示例

    CREATE CATALOG hive_catalog WITH (
        'type' = 'hive',
        'default-database' = 'default',
        'hive-conf-dir' = '/home/commons/apache-hive-3.1.3-bin/conf/'
    );
    
    use catalog hive_catalog;
    CREATE TABLE t8(
      id int,
      num int,
      ts int,
      primary key (id) not enforced
    )
    PARTITIONED BY (num)
    with(
      'connector'='hudi',
      'path' = 'hdfs://hadoop1:9000/tmp/hudi_flink/t8',
      'table.type'='COPY_ON_WRITE', 
      'hive_sync.enable'='true', 
      'hive_sync.table'='h8', 
      'hive_sync.db'='default', 
      'hive_sync.mode' = 'hms',
      'hive_sync.metastore.uris' = 'thrift://hadoop2:9083'
    );
    

    本人博客网站IT小神 www.itxiaoshen.com