DataLakeAnalysis: 使用DataX同步Kafka数据到OSS进行分析

简介:

平常业务开发中我们经常有流式数据保存在Kafka里面,这部分数据很多场景也是需要分析的,今天给大家介绍下如果使用DataX把数据从Kafka同步到OSS,保存成对分析友好的Parquet格式,然后利用DLA进行分析的全流程。
为了后续叙述的方便,我们假设Kafka里面保存的是订单的数据,它包含如下字段:

  • id, int类型
  • name, string类型
  • gmt_create, bigint类型, 时间戳字段
  • map_col: MAP 类型
  • array_col: ARRAY 类型
  • struct_col: STRUCT 类型

我们最终希望把Kafka上的这个数据最终保存到OSS上,并且映射到DLA里面的一个分区表,表结构如下:

CREATE EXTERNAL TABLE orders_p (
    id int,
    name string,
    gmt_create timestamp,
    map_col MAP<string, string>,
    array_col ARRAY<string>,
    struct_col STRUCT<id:bigint,name:string>
)
PARTITIONED BY (dt string)
STORED AS PARQUET 
LOCATION 'oss://test-bucket/datasets/oss_demo/orders_p/';

注意我们最终表结构里面有一个分区字段 dt, 因为分析场景下数据量都很大,进行分区才能提高分析的效率。而这个分区字段在原始数据里面是没有直接对应的。
因为从DataX过来的数据无法自动根据目录分区,因此我们建议从Kafka过来的数据放到中间表 orders 里面去, 在数据进入orders之后我们再跟一个任务做一个“数据拆分”的工作,把数据拆分到具体的分区里面去。总结一下:要把Kafka的数据正确的落到DLA里面的 orders_p 需要经过如下步骤:

  • kafka -> oss: DataX定时把数据同步到中间表: orders。
  • orders -> orders_p: DLA任务定时把数据从中间表orders同步到orders_p

这两个任务串行执行,第二个任务依赖第一个任务,每5分钟调度一次。这样就可以Kafka里面的数据以5分钟延时的粒度不断地写入到OSS里面去,然后使用DLA进行高效的分析。

kafka -> oss: DataX定时把数据同步到中间表: orders

因为Kafka上的数据量很大,在DLA中一般会进行分区处理以获得更好的分析性能,但是DataX目前还无法支持直接把数据写入到分区表,因此我们要搞一个中间表: orders 过度一下,它的表结构跟最终表orders_p几乎一样,只是没有分区

CREATE EXTERNAL TABLE orders (
    id int,
    name string,
    gmt_create timestamp,
    map_col MAP<string, string>,
    array_col ARRAY<string>,
    struct_col STRUCT<id:bigint,name:string>
)
STORED AS PARQUET 
LOCATION 'oss://test-bucket/datasets/oss_demo/orders/';

那么我们第一步要做的事情就是要通过DataX把数据写到这个 orders 表对应的LOCATION: oss://test-bucket/datasets/oss_demo/orders/。
整个DataX的任务的JSON配置蛮复杂的,我们直接贴在这里:

{
    "job": {
        "setting": {
            "speed": {
                "channel": 3
            },
            "errorLimit": {
                "record": 5
            }
        },
        "content": [
            {
                "reader": {
                    "name": "kafkareader",
                    "parameter": {
                        "server": "127.0.0.2:9093",
                        "column": [
                            "id",
                            "name",
                            "gmt_create",
                            "map_col",
                            "array_col",
                            "struct_col"
                        ],
                        "kafkaConfig": {
                            "group.id": "demo_test",
                            "java.security.auth.login.config": "/the-path/kafka/kafka_client_jaas.conf",
                            "ssl.truststore.location": "/the-path/kafka.client.truststore.jks",
                            "ssl.truststore.password": "KafkaOnsClient",
                            "security.protocol": "SASL_SSL",
                            "sasl.mechanism": "PLAIN",
                            "ssl.endpoint.identification.algorithm": ""
                        },
                        "topic": "yucha",
                        "waitTime": "10",
                        "partition_": "0",
                        "keyType": "ByteArray",
                        "valueType": "ByteArray",
                        "seekToBeginning_": "true",
                        "seekToLast_": "true",
                        "beginDateTime": "20190501010000",
                        "endDateTime":   "20190501010500"
                    }
                },
                "writer": {
                    "name": "hdfswriter",
                    "parameter": {
                        "defaultFS": "oss://test-bucket",
                        "fileType": "parquet",
                        "path": "/datasets/oss_demo/kpt",
                        "fileName": "test",
                        "writeMode": "truncate",
                        "compress":"SNAPPY",
                        "encoding":"UTF-8",
                        "hadoopConfig": {
                            "fs.oss.accessKeyId": "the-access-id",
                            "fs.oss.accessKeySecret": "the-access-key",
                            "fs.oss.endpoint": "oss-cn-hangzhou.aliyuncs.com"
                        },
                        "parquetSchema": "message test {\n    required int64 id;\n    optional binary name (UTF8);\n    optional int64 gmt_create;\n    required group map_col (MAP) {\n        repeated group key_value {\n            required binary key (UTF8);\n            required binary value (UTF8);\n        }\n    }\n    required group array_col (LIST) {\n        repeated group list {\n            required binary element (UTF8);\n        }\n    }\n    required group struct_col {\n        required int64 id;\n        required binary name (UTF8);\n    }    \n}",
                        "dataxParquetMode": "fields"
                    }
                }
            }
        ]
    }
}

这个配置分为两段: kafkareader 和 hdfswriter, 分别负责读写数据。我们分别详细介绍一下。
kafkareader 里面大多数参数都比较好理解,比较重要的参数是 beginDateTime, endDateTime, 指定这个任务要消费的kafka数据的范围,比如我们任务每5分钟跑一次,那么这里指定的可能就是当前时间往前推5分钟的时间范围,比如我们示例代码里面的是 20190501010000 到 20190501010500, 时间精确到秒。关于KafkaReader更详细的信息可以参考KafkaReader文档。
hdfswriter, 这里我们使用hdfswriter来写oss数据是因为OSS实现了Hadoop File System的接口,我们可以通过HDFS Writer来向OSS导数据,因为倒过来的数据后面要通过DLA来分析,推荐使用Parquet这种列存格式来保存,目前HDFS Writer支持PARQUET的绝大部分类型,包括基本类型以及复杂类型如array, map, struct, 要以Parquet格式同步数据,我们首先要描述一下这个Parquet的格式, 我们示例数据对应的Parquet的Schema如下:

message test {
    required int64 id;
    optional binary name (UTF8);
    optional int64 gmt_create;
    required group map_col (MAP) {
        repeated group key_value {
            required binary key (UTF8);
            required binary value (UTF8);
        }
    }
    required group array_col (LIST) {
        repeated group list {
            required binary element (UTF8);
        }
    }
    required group struct_col {
        required int64 id;
        required binary name (UTF8);
    }    
}

上面DataX任务描述文件里面的parquetSchema字段里面的内容就是上面这段,只不过缩成了一行以保证整个DataX描述文件符合JSON格式。 关于Parquet Schema更多的信息可以查看Parquet Logical Type Definitions。
另外一个注意的配置点是 writeMode, 在我们的这个方案里面,我们推荐使用 truncate, 因为这个任务是每5分钟调度一次,下一次执行的时候需要把前一次执行的数据清空掉(truncate)。

orders -> orders_p: DLA任务定时把数据从中间表orders同步到orders_p

拆分的SQL每个具体的业务会不一样,我们这个示例里面比较简单,主要干了两件事:
把原始的 bigint 类型的 gmt_create转成了timestamp类型。
从gmt_create里面生成新的dt字段。

INSERT INTO orders_p
SELECT 
id, 
name, 
from_unixtime(gmt_create),  -- bigint -> timestamp
map_col, array_col, struct_col, 
cast(date(from_unixtime(gmt_create)) as string) -- 添加分区字段 
FROM orders

这两个任务的串行操作可以通过任务调度服务比如阿里云上DataWorks来进行串联,在 kafka -> oss 的任务完成后,运行这个 数据拆分 的任务。

总结

这篇文章介绍了如何把Kafka里面的数据实时地流入OSS,利用DLA进行高效的数据分析。借助于DataX对于Parquet复杂类型的支持,我们已经可以帮助用户把各种复杂数据搬进OSS,希望对有类似场景的客户有所帮助。

欢迎关注数据湖技术社区

数据湖开发者社区由 阿里云开发者社区 与 阿里云Data Lake Analytics团队 共同发起,致力于推广数据湖相关技术,包括hudi、delta、spark、presto、oss、元数据、存储加速、格式发现等,学习如何构建数据湖分析系统,打造适合业务的数据架构。

x

目录
相关文章
|
16天前
|
消息中间件 存储 Kafka
实时计算 Flink版产品使用问题之通过flink同步kafka数据进到doris,decimal数值类型的在kafka是正常显示数值,但是同步到doris表之后数据就变成了整数,该如何处理
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
2天前
|
数据采集 DataWorks 安全
DataWorks产品使用合集之将按日分区的表同步数据到OSS数据源,该如何配置
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
15 1
|
2天前
|
DataWorks Java 调度
DataWorks产品使用合集之进行离线同步时,如何使用DataX的Reader插件来实现源端过滤
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
22 0
DataWorks产品使用合集之进行离线同步时,如何使用DataX的Reader插件来实现源端过滤
|
9天前
|
机器学习/深度学习 分布式计算 大数据
MaxCompute产品使用问题之如何直接加载oss中的parque数据,无需指定列和分区
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
|
17天前
|
消息中间件 SQL Kafka
实时计算 Flink版产品使用问题之如何实现OSS数据到Kafka的实时同步
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
22天前
|
分布式计算 DataWorks 关系型数据库
DataWorks操作报错合集之数据源同步时,使用脚本模式采集mysql数据到odps中,使用querySql方式采集数据,在脚本中删除了Reader中的column,但是datax还是报错OriginalConfPretreatmentUtil - 您的配置有误。如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
5天前
|
JSON 运维 Serverless
函数计算产品使用问题之如何实现数据的读取和修改,而不需要每次都从OSS下载完整的数据
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
8天前
|
消息中间件 存储 Java
后端开发Spring框架之消息介绍 同步异步 JMS AMQP MQTT Kafka介绍
后端开发Spring框架之消息介绍 同步异步 JMS AMQP MQTT Kafka介绍
10 0
|
16天前
|
消息中间件 存储 SQL
实时计算 Flink版产品使用问题之kafka2hive同步数据时,如何回溯历史数据
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
21天前
|
分布式计算 DataWorks API
DataWorks操作报错合集之数据集成同步到本地数据库时,出现报错,如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。