数据治理平台

  • 数据治理平台

    • 建设背景

    • 现有架构

    • 难点刨析

    • 处理方案

  • DEMO介绍

  • 扩展内容

  1. 建设背景:构建跨业务数据治理平台,获取各烟囱业务基本数据,构建统一化的业务数据治理平台。

  2. 现有架构:在这里插入图片描述

  3. 难点刨析:

难点说明
资源瓶颈前置机;核心数据库都存有大量应用,不能基于该服务器开发数据治理服务,但是数据只有这2类服务器上有
治理逻辑传统SQL一个语句块对应一个质检,增加重复人力,检验问题分散。
可插拔新增服务器1台(8核32G+500)用于数据治理服务,随着治理要求要强,能够快速的应对软硬建的插拔,快速集成
数据血缘治理发现的问题来源关联查询,对应指标的错误来源左关联表还是右关联表?
    • 处理方案
  • 构建计算引擎,将算子从数据库层面分离,计算引擎能够使用SQL,并且能结合开发语言(python,JAVA等)进行UDF的开发。(资源瓶颈)
  • 自生分布式,通过修改配置文件即可完成硬件的快速扩容,负载均衡。通过UDF函数实现软件的快速融合。(可插拔)
  • 基于Calcite解析列级数据血缘(数据血缘)
  • 使用侧边流的方式实现数据的多路校验。(治理逻辑)在这里插入图片描述

DEMO介绍

我这边使用的是Flink1.16.1+pyflink1.16相关环境已经进行docker封装

链接:https://pan.baidu.com/s/1pvvPAwo4gY515laI1G-YFA?pwd=5oct 
提取码:5oct

docker-compose  up -d
docker-compose exec  flink bash

test.py---->ff/init-data目录下
*.csv--->ff/init-data/examples目录下

方式1:python

/*test.py*/
!/usr/bin/env python
from pyflink.table import EnvironmentSettings, TableEnvironment,DataTypes
from pyflink.table.udf import ScalarFunction, udf
from pyflink.table.expressions import call, col

# 1. 创建 TableEnvironment
env_settings = EnvironmentSettings.in_streaming_mode()
table_env = TableEnvironment.create(env_settings)


# 创建一个udf函数用于校验XXMDJ*MXXMSL是否等于MXXMJE
@udf(result_type=DataTypes.STRING())
def rule_1(MXXMDJ, MXXMSL,MXXMJE):
    if MXXMDJ*MXXMSL!=MXXMJE:
        return "校验:XXMDJ*MXXMSL!=MXXMJE"
    else:
        return None

#def rule_1(MXXMDJ, MXXMSL, MXXMJE):
#    assert MXXMDJ * MXXMSL == MXXMJE, "校验:XXMDJ*MXXMSL!=MXXMJE"


# 2. 创建 source 表
table_env.execute_sql("""
CREATE TABLE TB_HIS_MZ_FEE_DETAIL(
    KH 	VARCHAR,
    KLX VARCHAR, 
    MXXMMC VARCHAR, 
    MXXMDW VARCHAR, 
    MXXMDJ float,
    MXXMSL float, 
    MXXMJE float
) WITH ( 
    'connector' = 'filesystem',
    'path' = '/usr/local/app/examples/20230305TB_HIS_MZ_FEE_DETAIL.csv',
    'format' = 'csv'
);

""")



table_env.execute_sql("""
CREATE TABLE TB_DIC_MATERIALS(
    YBMLBM 	VARCHAR,
    XMMC VARCHAR
) WITH ( 
    'connector' = 'filesystem',
    'path' = '/usr/local/app/examples/20230306tb_dic_materials.csv',
    'format' = 'csv'
);

""")

# 3. 创建 sink 表
table_env.execute_sql("""
    CREATE TABLE print (
    KH 	VARCHAR,
    KLX VARCHAR, 
    MXXMMC VARCHAR, 
    MXXMDW VARCHAR, 
    MXXMDJ float,
    MXXMSL float, 
    MXXMJE float,
    ERR_MSg VARCHAR
    ) WITH (
        'connector' = 'print'
    )
""")

# 4. 查询 source 表,同时执行计算
# 通过 Table API 创建一张表:
# source_table = table_env.from_path("TB_HIS_MZ_FEE_DETAIL")
# 或者通过 SQL 查询语句创建一张表:
source_table = table_env.sql_query("SELECT T1.* FROM TB_HIS_MZ_FEE_DETAIL T1 join TB_DIC_MATERIALS T2 on T1.MXXMMC=T2.XMMC")

result_table = source_table.select( source_table.KH,
                                    source_table.KLX,
                                    source_table.MXXMMC,
                                    source_table.MXXMDW,
                                    source_table.MXXMDJ,
                                    source_table.MXXMSL,
                                    source_table.MXXMJE,
                                    rule_1(source_table.MXXMDJ,source_table.MXXMSL,source_table.MXXMJE)
                                   )

# 5. 将计算结果写入给 sink 表
# 将 Table API 结果表数据写入 sink 表:
result_table.execute_insert("print").wait()
# 或者通过 SQL 查询语句来写入 sink 表:
# table_env.execute_sql("INSERT INTO print SELECT * FROM TB_HIS_MZ_FEE_DETAIL").wait()

数据血缘

PyFlink 中可以通过 Table 类的 explain() 方法来展示 SQL 执行计划,并且在执行计划中包含了数据流经过的算子、输入输出源等信息,可以通过解析执行计划来获取数据血缘信息。
具体步骤如下:
1.使用 TableEnvironment 类的 explain() 方法来获取 SQL 执行计划:

from pyflink.table import EnvironmentSettings, BatchTableEnvironment

# 创建 TableEnvironment
t_env = BatchTableEnvironment.create(
    environment_settings=EnvironmentSettings.new_instance().in_batch_mode().use_blink_planner().build())

# 解析 SQL 并获取执行计划
sql = "SELECT T1.MXXMMC,T1.KH,T2.YBMLBM FROM TB_HIS_MZ_FEE_DETAIL T1 join TB_DIC_MATERIALS T2 on T1.MXXMMC=T2.XMMC"
exec_plan = t_env.explain_sql(sql)

2.解析执行计划中的算子信息,将算子信息存储为有向图,使用深度优先遍历(DFS)算法获取数据血缘信息。

# 定义一个有向图类
class Graph:
    def __init__(self, vertices):
        self.V = vertices
        self.adj = [[] for i in range(self.V)]

    def addEdge(self, u, v):
        self.adj[u].append(v)

    # DFS 递归函数
    def DFS(self, v, visited, table_list):
        visited[v] = True
        table_list.append(v)
        for i in self.adj[v]:
            if not visited[i]:
                self.DFS(i, visited, table_list)

    # 获取有向图的数据血缘信息
    def get_data_lineage(self, start_node):
        visited = [False] * self.V
        table_list = []
        # 对起点进行 DFS 遍历,获取所有节点
        self.DFS(start_node, visited, table_list)
        # 返回所有节点列表
        return table_list

# 定义算子信息的类
class OpNode:
    def __init__(self, op_id, op_type, input_list, output_list):
        self.op_id = op_id
        self.op_type = op_type
        self.input_list = input_list
        self.output_list = output_list

# 解析 SQL 执行计划并获取算子信息
plan_str = exec_plan.get_execution_plan()
op_list = []
for line in plan_str.split("\n"):
    if line.startswith("#") or line == "":
        continue
    op_info = line.split(" ")
    op_id, op_type, input_list, output_list = op_info[0], op_info[1], op_info[3].split(","), op_info[4].split(",")
    op_node = OpNode(op_id, op_type, input_list, output_list)
    op_list.append(op_node)

# 构建有向图并获取数据血缘
graph = Graph(len(op_list))
for op in op_list:
    output_node_id = int(op.op_id.split("_")[0])
    for input_id in op.input_list:
        input_node_id = int(input_id.split("_")[0])
        graph.addEdge(input_node_id, output_node_id)
data_lineage = graph.get_data_lineage(start_node=0)

通过上述代码,就可以获取到 SQL 执行计划中所有数据流经过的算子节点,并且整理成有向图的形式,使用深度优先遍历算法获取数据血缘信息,返回的是一个列表,列表中的节点按照数据的流动顺序排列。

服务端执行

[root@f1eb2c863bd8 app]# python test.py 

Flink样例

方式2:Flink-sql

./bin/sql-client.sh

CREATE TABLE TB_HIS_MZ_FEE_DETAIL(
    KH 	VARCHAR,
    KLX VARCHAR, 
    MXXMMC VARCHAR, 
    MXXMDW VARCHAR, 
    MXXMDJ float,
    MXXMSL float, 
    MXXMJE float
) WITH ( 
    'connector' = 'filesystem',
    'path' = '/usr/local/app/examples/20230305TB_HIS_MZ_FEE_DETAIL.csv',
    'format' = 'csv'
);

CREATE TABLE TB_DIC_MATERIALS(
    YBMLBM 	VARCHAR,
    XMMC VARCHAR
) WITH ( 
    'connector' = 'filesystem',
    'path' = '/usr/local/app/examples/20230306tb_dic_materials.csv',
    'format' = 'csv'
);

SELECT T1.* FROM TB_HIS_MZ_FEE_DETAIL T1 join TB_DIC_MATERIALS T2 on T1.MXXMMC=T2.XMMC

FLink-SQL

查看数据血缘

EXPLAIN PLAN FOR
SELECT T1.MXXMMC,T1.KH,T2.YBMLBM FROM TB_HIS_MZ_FEE_DETAIL T1 join TB_DIC_MATERIALS T2 on T1.MXXMMC=T2.XMMC;

在这里插入图片描述

扩展内容

FLink-SQL中使用Java,Python,Scala UDF,详见:

https://github.com/appleyuchi/Flink_SQL_Client_UDF

FLink链接数据库,详见:https://nightlies.apache.org/flink/flink-docs-release-1.16/zh/docs/connectors/table/jdbc/(也可以看下我之前得CSDN)
注意:下载对应得Jar包

如果使用第三方 JAR,则可以在 Python 表 API 中指定 JAR

环境:
PyFlink版本是1.16.0,所以需要下载 :flink-connector-jdbc-1.16.0.jar
flink-connector-jdbc-1.16.0.jar下载地址

Mysql版本是8.0.30,所以需要下载:mysql-connector-java-8.0.30.jar
mysql-connector-java-8.0.30.jar下载地址

flinkcdc链接数据库的文档
flink-cdc-connectors
https://github.com/ververica/flink-cdc-connectors

使用JDBC

-- 在 Flink SQL 中注册一张 MySQL 表 'users'
CREATE TABLE MyUserTable (
  id BIGINT,
  name STRING,
  age INT,
  status BOOLEAN,
  PRIMARY KEY (id) NOT ENFORCED
) WITH (
   'connector' = 'jdbc',
   'url' = 'jdbc:mysql://localhost:3306/mydatabase',
   'table-name' = 'users'
);

-- 从另一张表 "T" 将数据写入到 JDBC 表中
INSERT INTO MyUserTable
SELECT id, name, age, status FROM T;

-- 查看 JDBC 表中的数据
SELECT id, name, age, status FROM MyUserTable;

-- JDBC 表在时态表关联中作为维表
SELECT * FROM myTopic
LEFT JOIN MyUserTable FOR SYSTEM_TIME AS OF myTopic.proctime
ON myTopic.key = MyUserTable.id;

使用flink-cdc-connectors,详细见:https://gitee.com/mario1oreo/flink-cdc-connectors

-- creates a mysql cdc table source
CREATE TABLE mysql_binlog (
 id INT NOT NULL,
 name STRING,
 description STRING,
 weight DECIMAL(10,3)
) WITH (
 'connector' = 'mysql-cdc',
 'hostname' = 'localhost',
 'port' = '3306',
 'username' = 'flinkuser',
 'password' = 'flinkpw',
 'database-name' = 'inventory',
 'table-name' = 'products'
);

-- read snapshot and binlog data from mysql, and do some transformation, and show on the client
SELECT id, UPPER(name), description, weight FROM mysql_binlog;

FLink-SQL中血缘关系得扩展:FlinkSQL字段血缘解决方案及源码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值