【参赛作品95】DLI Flink SQL+kafka+(opengauss和mysql)进行电商实时业务数据分析

本文介绍了在ARM环境下部署docker版的Kafka和OpenGauss,包括部署步骤、创建Kafka主题、数据同步与处理,以及如何通过DLI进行数据可视化。重点展示了如何解决string类型数据在两者间转换的问题,并以MySQL作为中间桥梁。

作者:吴毅

电商实时业务数据分析案例,
测试环境:操作系统:EulerOS_2.8_ARM-20200308_20200308192159

硬件配置:4vCPUs | 16 GiB | kc1.xlarge.4 IP地址:192.168.0.2

在上一篇已经部署好docker和docker版的opengauss。

1 部署docker版的kafka,要找支持arm64的docker版kafka。

1.1 先部署支持arm64的zookeeper,命令如下:

docker pull pi4k8s/k8szk:v3.4.14 docker run -itd --name zookeeper -p 21810:2181 -e ZK_REPLICAS=1 -e ZK_HEAP_SIZE=512M --hostname=zk-1 -v /opt/moudles/zookeeper/data:/var/lib/zookeeper -v /opt/moudles/zookeeper/log:/var/log/zookeeper pi4k8s/k8szk:v3.4.14 /bin/bash -c "/usr/bin/zkGenConfig.sh && /usr/bin/zkServer.sh start-foreground"

1.2 部署支持arm64的kafka

docker pull iecedge/cp-kafka-arm64:5.0.1 docker run -d --name=kafka -p 1099:1099 -p 9092:9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT=192.168.0.2:21810 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.0.2:9092 -e KAFKA_JMX_PORT=1099 -e KAFKA_JMX_HOSTNAME=192.168.0.2 -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 -e KAFKA_HEAP_OPTS="-Xmx512M -Xms512M" -v /opt/moudles/kafka/data:/var/lib/kafka/data iecedge/cp-kafka-arm64:5.0.1

image.png
** 1.3 部署完后,下载kafka的源码包:**

cd /opt/softwares wget https://archive.apache.org/dist/kafka/2.3.0/kafka_2.12-2.3.0.tgz tar zxf /opt/softwares/kafka_2.12-2.3.0.tgz -C /opt/modules/ cd /opt/modules/kafka_2.12-2.3.0/bin

1.4 创建topic

./kafka-topics.sh --create --zookeeper 192.168.0.2:21810 --replication-factor 1 --partitions 1 --topic trade_order

1.5 查看创建topic的数目

./kafka-topics.sh --list --zookeeper 192.168.0.2:21810

1.6 kafka生产者

./kafka-console-producer.sh --broker-list 192.168.0.2:9092 --topic trade_order

1.7 kafka消费者

./kafka-console-consumer.sh --bootstrap-server 192.168.0.2:9092 --topic trade_order --from-beginning

特别注意要放开9092(Kafka连接端口)。
2. 连接opengauss和创建表
2.1 连接opengauss

gsql -d testdb -U wuyi -p 5432 –r

2.2 创建表trade_channel_collect

CREATE TABLE trade_channel_collect ( begin_time VARCHAR(32) NOT NULL, channel_code VARCHAR(32) NOT NULL, channel_name VARCHAR(32) NULL, cur_gmv BINARY_DOUBLE NULL, cur_order_user_count BIGINT NULL, cur_order_count BIGINT NULL, last_pay_time VARCHAR(32) NULL, flink_current_time VARCHAR(32) NULL, PRIMARY KEY (begin_time, channel_code) ); comment on table trade_channel_collect is'各渠道的销售总额实时统计';

image.png
3 创建 DLI 增强型跨源
3.1 在控制台单击“服务列表”,选择“数据湖探索”,单击进入DLI服务页面。
单击“队列管理”,在队列列表中您所创建的通用队列
image.png
3.2 单击“跨源连接” >“增强型跨源” >“创建”。
配置如下:
– 绑定队列:选择您所创建的通用队列。
– 虚拟私有云:选择 Kafka 与 opengauss 实例所在的VPC
– 子网:选择 Kafka 与 opengauss 实例所在的子网。
image.png
3.3 测试队列与kafka和opengauss实例连通性。
单击“队列管理”,选择您所使用的队列,单击“操作”列中的“更多” >“测试地址连通性”
image.png
image.png
3.4 创建并提交 Flink 作业
单击DLI控制台左侧“作业管理”,选择“Flink作业”。单击“创建作业”。
– 类型:选择作业类型为: Flink OpenSource SQL。
– 名称:自定义
image.png
代码:

--********************************************************************-- -- 数据源:trade_order_detail_info (订单详情宽表) --********************************************************************-- create table trade_order_detail ( order_id string, -- 订单ID order_channel string, -- 渠道 order_time string, -- 订单创建时间 pay_amount double, -- 订单金额 real_pay double, -- 实际付费金额 pay_time string, -- 付费时间 user_id string, -- 用户ID user_name string, -- 用户名 area_id string -- 地区ID ) with ( "connector.type" = "kafka", "connector.version" = "0.10", "connector.properties.bootstrap.servers" = "192.168.0.2:9092", -- Kafka连接地址 -- "connector.properties.group.id" = "kafka-test", -- Kafka groupID "connector.topic" = "test", -- Kafka topic "format.type" = "json", "connector.startup-mode" = "latest-offset" );


– 结果表:trade_channel_collect (各渠道的销售总额实时统计)
––
create table trade_channel_collect(
begin_time date, –统计数据的开始时间
channel_code varchar, – 渠道编号
channel_name varchar, – 渠道名
–cur_gmv INTEGER, – 当天GMV
cur_order_user_count bigint, – 当天付款人数
cur_order_count bigint, – 当天付款订单数
last_pay_time varchar, – 最近结算时间
flink_current_time varchar,
primary key (begin_time, channel_code) not enforced
) with (
“connector.type” = “jdbc”,
“connector.url” = “jdbc:postgresql://192.168.0.2:15432/testdb”, – opengauss连接地址,jdbc格式
“connector.table” = “trade_channel_collect”, – opengauss表名
“connector.driver” = “org.postgresql.Driver”,
“connector.username” = “wuyi”, – opengauss用户名
“connector.password” = “xxxxx”, – opengauss密码
“connector.write.flush.max-rows” = “1000”,
“connector.write.flush.interval” = “1s”
);


– 临时中间表
––
create view tmp_order_detail
as
select *
, case when t.order_channel not in (“webShop”, “appShop”, “miniAppShop”) then “other”
else t.order_channel end as channel_code –重新定义统计渠道 只有四个枚举值[webShop、appShop、miniAppShop、other]
, case when t.order_channel = “webShop” then _UTF8"网页商城"
when t.order_channel = “appShop” then _UTF8"app商城"
when t.order_channel = “miniAppShop” then _UTF8"小程序商城"
else _UTF8"其他" end as channel_name –渠道名称
from (
select *
, row_number() over(partition by order_id order by order_time desc ) as rn –去除重复订单数据
, concat(substr(“2021-03-25 12:03:00”, 1, 10), " 00:00:00") as begin_time
, concat(substr(“2021-03-25 12:03:00”, 1, 10), " 23:59:59") as end_time
from trade_order_detail
where pay_time >= concat(substr(“2021-03-25 12:03:00”, 1, 10), " 00:00:00") –取今天数据,为了方便运行,这里使用"2021-03-25 12:03:00"替代cast(LOCALTIMESTAMP as string)
and real_pay is not null
) t
where t.rn = 1;

– 按渠道统计各个指标
insert into trade_channel_collect
select
‘begin_time’ –统计数据的开始时间
, cast(channel_code as varchar) as channel_code
, cast(channel_name as varchar) as channel_name
, cast((COALESCE(sum(real_pay), 0) as integer) as cur_gmv) –当天GMV
, ((count(distinct user_id) as bigint) as cur_order_user_count –当天付款人数
, ((count(1) as bigint) as cur_order_count) –当天付款订单数
, cast((max(pay_time) as last_pay_time) as varchar) –最近结算时间
, cast((LOCALTIMESTAMP as flink_current_time) as varchar) –flink任务中的当前时间
from tmp_order_detail
where pay_time >= concat(substr(“2021-03-25 12:03:00”, 1, 10), " 00:00:00")
group by begin_time, channel_code, channel_name;

image.png
只要是kafka出来的数据是string类型,而opengauss不支持string。使用cast()函数也无法转换成功。下面使用mysql数据库来连接一下。Mysql数据类型兼容性好。
4. docker版mysql的部署
4.1 安装mysql

docker search biarms/mysql:5.7.30 docker pull biarms/mysql:5.7.30 docker run -d --name mysql57 --hostname= mysql57 -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 biarms/mysql:5.7.30

特别要注意,mysql5.7要mysql:5.7.30以上的版本才能支持arm64

docker exec -it mysql57 /bin/bash docker cp mysql57:/etc/mysql/my.cnf /root/ /etc/mysql/mysql.conf.d/mysqld.cnf docker cp mysql57:/etc/mysql/mysql.conf.d/mysqld.cnf /root/
vi /root/mysqld.cnf [mysqld] character_set_server=utf8 [client] default-character-set=utf8 docker cp /root/mysql.cnf ,mysql:/etc/mysql/mysql.conf.d/ docker restart mysql57
reate database dli_demo DEFAULT CHARACTER SET = utf8mb4; CREATE TABLE `dli_demo`.`trade_channel_collect` ( `begin_time` VARCHAR(32) NOT NULL, `channel_code` VARCHAR(32) NOT NULL, `channel_name` VARCHAR(32) NULL, `cur_gmv` DOUBLE UNSIGNED NULL, `cur_order_user_count` BIGINT UNSIGNED NULL, `cur_order_count` BIGINT UNSIGNED NULL, `last_pay_time` VARCHAR(32) NULL, `flink_current_time` VARCHAR(32) NULL, PRIMARY KEY (`begin_time`, `channel_code`) ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '各渠道的销售总额实时统计';

4.2 查看创建topic的数目

cd /opt/modules/kafka_2.12-2.3.0/bin ./kafka-topics.sh --list --zookeeper 192.168.0.2:21810 # # kafka生产者 ./kafka-console-producer.sh --broker-list 192.168.0.2:9092 --topic trade_order kafka消费者 ./kafka-console-consumer.sh --bootstrap-server 192.168.0.2:9092 --topic trade_order --from-beginning

image.png
获得的数据连接华为云DLV,可以大屏数据可视化
image.png
通过对opengauss和mysql的操作,可以很容易发现,mysql对数据类型兼容比较好。而且在创建表时,在数据库,表名和字段加上单引号或双引号都能成功建表,但是opengauss缺不行。Opengauss虽然有很多特性,但是在string的转换不是很好用,找了cast()函数还有其他方法都无法转换,也有可能是我水平不行,原本还想写关于opengauss的AI方面的特性,但是由于这个问题花了一段时间。只能等下次活动再写一下关于AI的特性。

<think>嗯,用户想用FlinkSQL实现当天数据的实时汇总输出,我需要先理解他们的需求。实时当天汇总通常是指按天窗口处理数据,并且需要实时输出结果。首先得确定时间窗口的类型,比如滚动窗口还是滑动窗口,这里应该用滚动窗口,按天划分。 然后要考虑时间属性,FlinkSQL处理时间或者事件时间。用户可能需要事件时间,这样能处理乱序事件。所以得在表中定义事件时间字段,并用WATERMARK来指定延迟策略。 接下来是聚合SQL的写法,使用TUMBLE窗口函数,按天分组,然后对需要的字段进行汇总,比如SUM、COUNT等。比如SELECT DATE_FORMAT(window_end, 'yyyy-MM-dd') as day, SUM(amount) FROM table GROUP BY TUMBLE(row_time, INTERVAL '1' DAY)。 还要注意输出结果的方式,可能需要将结果写入Kafka或者其他外部存储,比如创建Sink表,指定连接器。示例中用了Kafka作为Sink,用户需要根据实际情况调整连接信息。 另外,用户可能需要当天数据的实时更新,比如每来一条数据就更新当天的汇总结果。这时候可以考虑使用HOP窗口,虽然示例里用了TUMBLE,但HOP窗口可以设置滑动步长,比如1分钟,这样更实时。不过要注意性能问题,滑动窗口可能会增加计算量。 还有分区的问题,比如按天分区存储,可能在Sink表中指定dt字段作为分区,用DATE_FORMAT转换事件时间为分区值。这样数据按天存储,方便后续查询。 需要检查引用中的内容,比如引用[4]提到了创建DLI Flink作业的步骤,可能需要参考资源创建跨源连接。引用[3]提到Flink任务生成的算子,说明SQL会被翻译成具体的执行计划,确保窗口聚合操作正确。 用户可能遇到的问题包括时间处理不正确,比如时区问题,需要确认Flink的时区配置。另外,Watermark的设置是否正确,处理延迟数据是否足够。还有聚合结果的更新频率,是否需要设置allowLateness或者侧输出处理延迟数据。 总结下来,步骤应该是:定义源表(事件时间、Watermark),编写聚合查询(TUMBLE或HOP窗口),定义Sink表,写入结果。同时提供调优建议,比如状态TTL、并行度设置,以及可能涉及的Exactly-Once语义保障。</think>### Flink SQL实现当天数据实时汇总输出的分步说明 ### 一、核心实现步骤 1. **定义时间属性** 在源表中明确定义事件时间字段,并设置水位线策略处理乱序数据: ```sql CREATE TABLE source_table ( item_id STRING, amount DECIMAL(10,2), row_time TIMESTAMP(3), WATERMARK FOR row_time AS row_time - INTERVAL '5' SECOND ) WITH (...); ``` 2. **滚动窗口聚合** 使用`TUMBLE`窗口函数实现按天聚合: ```sql SELECT DATE_FORMAT(window_end, 'yyyy-MM-dd') as day, item_id, SUM(amount) as total_amount FROM TABLE( TUMBLE(TABLE source_table, DESCRIPTOR(row_time), INTERVAL '1' DAY)) GROUP BY window_start, window_end, item_id ``` 3. **结果输出配置** 创建Kafka Sink表实现秒级输出(需配置实际broker地址): ```sql CREATE TABLE sink_table ( day STRING, item_id STRING, total_amount DECIMAL(10,2) ) WITH ( 'connector' = 'kafka', 'topic' = 'daily_summary', 'properties.bootstrap.servers' = 'kafka:9092', 'format' = 'json' ); ``` ### 二、高阶优化方案 1. **增量计算结果更新** 采用`HOP`窗口实现分钟级滚动更新(示例每5分钟触发一次): ```sql SELECT DATE_FORMAT(window_end, 'yyyy-MM-dd HH:mm') as update_time, item_id, SUM(amount) FROM TABLE( HOP(TABLE source_table, DESCRIPTOR(row_time), INTERVAL '5' MINUTE, INTERVAL '1' DAY)) ``` 2. **状态管理优化** 添加状态存活时间参数避免OOM: ```sql SET 'table.exec.state.ttl' = '36h'; ``` 3. **精确一次保障** 启用checkpoint并配置两阶段提交: ```sql SET 'execution.checkpointing.interval' = '1min'; SET 'execution.checkpointing.mode' = 'EXACTLY_ONCE'; ``` ### 三、典型应用场景 1. **实时交易看板** 电商场景中实时统计各品类销售额,配合DLV实现数据大屏展示[^4] 2. **运维监控系统** 按天聚合服务器请求量,异常流量实时告警 3. **物联网数据处理** 设备传感器数据每小时/天维度汇总分析 ### 四、调试要点 1. 通过`EXPLAIN`命令查看执行计划[^3] 2. 使用`SHOW JOBS`监控任务运行状态 3. 在Flink Web UI观察窗口触发情况
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Gauss松鼠会

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

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

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

打赏作者

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

抵扣说明:

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

余额充值