Inicio rápido con flink

Flink se usa para procesar la computación de transmisión con estado. Necesita procesar los datos en el lado de la fuente y luego escribirlos en el lado del receptor. La siguiente figura muestra el proceso de datos en Flink. Hoy, lo compartiré con ustedes de acuerdo con esto imagen Abajo.

Comience rápidamente

1. Agregar dependencias

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <flink.version>1.12.2</flink.version>
        <target.java.version>1.8</target.java.version>
        <scala.binary.version>2.12</scala.binary.version>
    </properties>


        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.3</version>
        </dependency>
        <!-- This dependency is provided, because it should not be packaged into the JAR file. -->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
            <version>${flink.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.flink/flink-clients -->
        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-clients_2.12</artifactId>
            <version>1.12.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-kafka_2.11</artifactId>
            <version>1.12.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-connector-jdbc_2.11</artifactId>
            <version>1.12.7</version>
        </dependency>

        <dependency>
            <groupId>ru.yandex.clickhouse</groupId>
            <artifactId>clickhouse-jdbc</artifactId>
            <version>0.3.2</version>
        </dependency>

2. Leer datos kafka

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStream<String> transactions = env
                .addSource(new FlinkKafkaConsumer<>(topicName, new SimpleStringSchema(), properties));
        transactions.print();
        env.execute();

01 Medio Ambiente

Todos los programas de Flink parten de este paso, solo cuando se crea el entorno de ejecución se puede escribir el siguiente paso. Puede utilizar los siguientes métodos para obtener el entorno operativo:

(1) obtener entorno de ejecución

Crear un entorno de ejecución, que representa el contexto del programa en ejecución actual

Si el programa se invocó de forma independiente, este método devuelve el entorno de ejecución local

Si el programa se invocó desde un cliente de línea de comandos para enviarlo a un clúster, este método devuelve el entorno de ejecución de este clúster.

Determinará qué tipo de entorno de ejecución devolver en función de cómo se ejecute la consulta

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

02 fuente y sumidero

Source es la fuente de datos en Flink, y Sink es el terminal de salida de datos. Flink está conectado al sistema de almacenamiento externo a través del Flink Streaming Connector. Flink completa principalmente el intercambio de datos de cuatro maneras:

Fuente y sumidero predefinidos de Flink

Conectores combinados proporcionados dentro de Flink

Conectores en proyectos Apache Bahir de terceros

Modo de E/S asíncrono

A continuación, se presenta principalmente el contenido predefinido y los conectores enlazados. Para obtener más contenido, consulte

(1) Fuente y sumidero predefinidos

Primero echemos un vistazo a la fuente incorporada proporcionada por Flink.Estos métodos se encuentran en la clase StreamExecutionEnvironment.

El sumidero incorporado en Flink se muestra en la siguiente figura, todos ubicados en la clase DataStream.

Origen y sumidero basados ​​en archivos

  1. leer datos del archivo de texto

env.readTextFile(path)
  1. Escriba los resultados del formato de texto o csv en un archivo

dataStream.writeAsText(path) ;
dataStream.writeAsCsv(path);

(2) Conector incorporado

En el sitio web oficial, se proporcionan los siguientes conectores:

Apache Kafka (fuente/sumidero)

    JDBC (fregadero)

Apache Cassandra (sink)

Amazon Kinesis Streams (source/sink)

Elasticsearch (sink)

FileSystem (sink)

RabbitMQ (source/sink)

Google PubSub (source/sink)

Hybrid Source (source)

Apache NiFi (source/sink)

Apache Pulsar (source)

Twitter Streaming API (source)

在使用过程中,提交 Job 的时候需要注意, job 代码 jar 包中一定要将相应的 connetor 相关类打包进去,否则在提交作业时就会失败,提示找不到相应的类,或初始化某些类异常

(3) 自定义Source&Sink

除了上述的Source与Sink外,Flink还支持自定义Source与Sink。

自定义Source

  • 实现SourceFunction类

  • 重写run方法和cancel方法

  • 在主函数中通过addSource调用

public class MySource implements SourceFunction<String> {
    // 定义一个运行标志位,表示数据源是否运行
    Boolean flag = true;
    @Override
    public void run(SourceContext<String> sourceContext) throws Exception {
        while (flag){
            sourceContext.collect("当前时间为:" + System.currentTimeMillis());
            Thread.sleep(100);
        }
    }

    @Override
    public void cancel() {
        flag = false;
    }
}

自定义Sink

  • 继承SinkFunction

  • 重写invoke方法

下面给出了自定义JDBC Sink的案例,可以参考

public class MyJdbcSink extends RichSinkFunction<String> {
    
    // 定义连接
    Connection conn;
    
    // 创建连接
    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");
    }

    // 关闭连接
    @Override
    public void close() throws Exception {
        super.close();
        conn.close();
    }

    // 调用连接执行SQL
    @Override
    public void invoke(String value, Context context) throws Exception {
        PreparedStatement preparedStatement = conn.prepareStatement(value);
        preparedStatement.execute();
        preparedStatement.close();
    }
}

env.addSink(newMyJdbcSink());

        rongHeStream.addSink(JdbcSink.sink(
                "INSERT INTO ronghe_log VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                (preparedStatement, rongHeLog) -> {
                    preparedStatement.setObject(1, rongHeLog.getId());
                    preparedStatement.setObject(2, rongHeLog.getDeviceNum());
                    preparedStatement.setObject(3, rongHeLog.getSrcIp());
                    preparedStatement.setObject(4, rongHeLog.getSrcPort());
                    preparedStatement.setObject(5, rongHeLog.getDstIp());
                    preparedStatement.setObject(6, rongHeLog.getDstPort());
                    preparedStatement.setObject(7, rongHeLog.getProtocol());
                    preparedStatement.setObject(8, new Timestamp(rongHeLog.getLastOccurTime()));

                    //SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    //Date date = new Date(rongHeLog.getLastOccurTime());
                    //String dateStr = simpleDateFormat.format(date);

                    preparedStatement.setObject(9, rongHeLog.getCount());

                    try {
                        String idListJson = objectMapper.writeValueAsString(rongHeLog.getSourceLogIds());
                        preparedStatement.setObject(10, idListJson);
                    } catch (JsonProcessingException e) {
                        throw new RuntimeException(e);
                    }

                },
                JdbcExecutionOptions.builder()
                        .withBatchSize(10)
                        .build(),
                new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
                        .withDriverName("com.mysql.cj.jdbc.Driver")
                        .withUrl("jdbc:mysql://81.70.199.213:3306/flink21?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false")
                        .withUsername("root")
                        .withPassword("lJPWRbm06NbToDL03Ecj")
                        .build()

        ));

Supongo que te gusta

Origin blog.csdn.net/2301_76154806/article/details/128693440
Recomendado
Clasificación