Flink Stream Batch Integrated Computing (14): consulta SQL de PyFlink Tabel API

Por ejemplo

Consulta la tabla de origen y realiza cálculos al mismo tiempo

# 通过 Table API 创建一张表:
source_table = table_env.from_path("datagen")
# 或者通过 SQL 查询语句创建一张表:
source_table = table_env.sql_query("SELECT * FROM datagen")
result_table = source_table.select(source_table.id + 1, source_table.data)

Consulta de API de tabla

El objeto Table tiene muchos métodos que se pueden usar para realizar operaciones relacionales.

Estos métodos devuelven nuevos objetos de tabla que representan los resultados de aplicar operaciones relacionales a la tabla de entrada.

Estas operaciones relacionales pueden consistir en múltiples llamadas a métodos, como table.group_by(...).select(...).

La documentación de Table API describe todas las operaciones admitidas de Table API en secuencias y lotes.

El siguiente ejemplo muestra una consulta de agregación de Table API simple:

from pyflink.table import Environmentsettings, TableEnvironment
# 通过 batch table environment 来执行查询
env_settings = Environmentsettings.in_batch_mode()
table_env = TableEnvironment.create(env_settings)
orders = table_env.from_elements([('Jack', 'FRANCE', 10), ('Rose', 'ENGLAND', 30), ('Jack', 'FRANCE', 20)],['name', 'country', 'revenue'])
# 计算所有来自法国客户的收入
revenue = orders \
    .select(orders.name, orders.country, orders.revenue) \
    .where(orders.country == 'FRANCE') \
    .group_by(orders.name) \
    .select(orders.name, orders.revenue.sum.alias('rev_sum'))
revenue.to_pandas()

La API de tabla también es compatible con la API de operación de fila, estas operaciones de fila incluyen la operación de mapa, la operación FlatMap, la operación agregada y la operación FlatAggregate.

El siguiente ejemplo muestra una consulta simple basada en filas de Table API

from pyflink.table import Environmentsettings, TableEnvironment
from pyflink.table import DataTypes
from pyflink.table.udf import udf
import pandas as pd

# 通过 batch table environment 来执行查询
env_settings = Environmentsettings.in_batch_mode()
table_env = TableEnvironment.create(env_settings)
orders = table_env.from_elements([('Jack', 'FRANCE', 10), ('Rose', 'ENGLAND', 30), ('Jack', 'FRANCE', 20)], ['name', 'country', 'revenue'])
map_function = udf(lambda x: pd.concat([x.name, x.revenue * 10], axis=1),
    result_type=DataTypes.ROW(
        [DataTypes.FIELD("name", DataTypes.STRING()),
        DataTypes.FIELD("revenue", DataTypes.BIGINT())]),
    func_type="pandas")
orders.map(map_function).alias('name', 'revenue').to_pandas()

consulta SQL

El SQL de Flink se basa en Apache Calcite, que implementa SQL estándar. Las declaraciones de consulta SQL se expresan mediante cadenas. SQL es compatible con el procesamiento por lotes y convectivo de Flink.

El siguiente ejemplo muestra una consulta de agregación de SQL simple:

from pyflink.table import Environmentsettings, TableEnvironment

# 通过 stream table environment 来执行查询

env_settings = Environmentsettings.in_streaming_mode()

table_env = TableEnvironment.create(env_settings)

table_env.execute_sql("""

    CREATE TABLE random_source (

        id BIGINT,

        data TINYINT

    ) WITH (

        'connector' = 'datagen',

        'fields.id.kind'='sequence',

        'fields.id.start'='1',

        'fields.id.end'='8',

        'fields.data.kind'='sequence',

        'fields.data.start'='4',

        'fields.data.end'='11'

    )

""")

table_env.execute_sql("""

    CREATE TABLE print_sink (

        id BIGINT,

        data_sum TINYINT

    ) WITH (

        'connector' = 'print'

    )

""")

table_env.execute_sql("""

    INSERT INTO print_sink

        SELECT id, sum(data) as data_sum FROM

            (SELECT id / 2 as id, data FROM random_source)

        WHERE id > 1

        GROUP BY id

""").wait()

Mezclar tabla API y SQL

El objeto Table en Table API y Table en SQL se pueden convertir libremente entre sí.

El siguiente ejemplo muestra cómo usar el objeto Tabla en SQL:

create_temporary_view(view_path, table) Registra un objeto `Table` como una tabla temporal, similar a la tabla temporal de SQL.

# 创建一张 sink 表来接收结果数据
table_env.execute_sql("""
    CREATE TABLE table_sink (
        id BIGINT,
        data VARCHAR
    ) WITH (
        'connector' = 'print'
    )
""")
# 将 Table API 表转换成 SQL 中的视图
table = table_env.from_elements([(1, 'Hi'), (2, 'Hello')], ['id', 'data'])
table_env.create_temporary_view('table_api_table', table)
# 将 Table API 表的数据写入结果表
table_env.execute_sql("INSERT INTO table_sink SELECT * FROM table_api_table").wait()

El siguiente ejemplo muestra cómo usar tablas SQL en Table API:

sql_query(consulta) Ejecuta una consulta SQL y devuelve el resultado de la consulta como un objeto `Tabla`.

# 创建一张 SQL source 表
table_env.execute_sql("""
    CREATE TABLE sql_source (
        id BIGINT,
        data TINYINT
    ) WITH (
        'connector' = 'datagen',
        'fields.id.kind'='sequence',
        'fields.id.start'='1',
        'fields.id.end'='4',
        'fields.data.kind'='sequence',
        'fields.data.start'='4',
        'fields.data.end'='7'
    )
""")

# 将 SQL 表转换成 Table API 表
table = table_env.from_path("sql_source")
# 或者通过 SQL 查询语句创建表
table = table_env.sql_query("SELECT * FROM sql_source")
# 将表中的数据写出
table.to_pandas()

mejoramiento

sesgo de datos

Cuando los datos están sesgados (una cierta parte de los datos es particularmente grande), aunque no hay GC ( Gabage Collection , recolección de basura), el tiempo de ejecución de la tarea es muy inconsistente.

  • La clave debe rediseñarse para racionalizar el tamaño de la tarea con una clave de granularidad más pequeña.
  • Modificar el grado de paralelismo.
  • Llame a la operación de reequilibrio para igualar la partición de datos.

Configuración del tiempo de espera del búfer

Dado que los datos se intercambian a través de la red durante la ejecución de la tarea , el período de tiempo de espera del búfer para la transferencia de datos entre diferentes servidores se puede configurar a través de setBufferTimeout .

Cuando se configura "setBufferTimeout(-1)" , esperará a que el búfer esté lleno antes de actualizar, para que pueda alcanzar el rendimiento máximo; cuando se configura "setBufferTimeout(0)" , el retraso se puede minimizar y el los datos se actualizarán una vez que se reciban; cuando se configura "setBufferTimeout" mayor que 0 , el búfer expirará después de este tiempo y luego se actualizará.

Los ejemplos pueden referirse a lo siguiente:

env.setBufferTimeout(timeoutMillis);
env.generateSequence(1,10).map(new MyMapper()).setBufferTimeout(timeoutMillis);

Supongo que te gusta

Origin blog.csdn.net/victory0508/article/details/132358265
Recomendado
Clasificación