繁体   English   中英

使用kafka+java流式处理数据

[英]Streaming data and processing with kafka+java

我在编程方面相对较新(你可以在我的代码中看到它),但我目前正在学习更多关于 kafka 和 java 的数据处理。 对于主题中的数据,我需要与一些表进行连接以检查数据是否存在并获取其他数据,因此我对数据库进行了一些请求(要检索的字段太多,我需要单独的查询以使其可读)。对于每条记录从主题中检索到我对数据库进行了一些连接,然后(在处理数据之后)更新表(我对表进行批处理,只是这样很快)。
我的问题是时间。 我用二十万个寄存器做测试…… 半小时六千,太慢了。 我的代码类似于

public class TestKafka {  
    public static Connection conexion = null;  
    public static void main(){  
        conexion = C3P0DataSource.getInstance().getConnection();  
        runConsumer();  
    }  
    .  
    ..  
    public static void runConsumer(){  
    try // ( Connection conexion C3P0DataSource.getInstance().getConnection();)
    {  
        conexion.setAutoCommit(false);  
        while (true) {  // with kafka connector - I try to simulate data streaming
            final ConsumerRecords<String, String> consumerRecords = consumer.poll(Long.MAX_VALUE);  
            List<Map<String, String>> recordData = new ArrayList<Map<String, String>>();  
            ObjectMapper mapper = new ObjectMapper();  
            for (ConsumerRecord<String, String> record : consumerRecords) {  
                Map<String, String> map = new HashMap<String, String>();  
                DataStructure_Topic config = mapper.readValue(record.value(), DataStructure_Topic.class);  
                map.put("row_id_1", config.getCodent());  
                map.put("row_id_2", config.getCentalta());  
                map.put("row_id_3", config.getCuenta());  
                datosAComprobar.add(map);  
                recordData = firstConsult(recordData, conexion);  
                if (recordData.size() > 0) {  
                    recordData = SecondConsult(recordData, conexion);  
                    // few petitions to the database  
                    if (recordData.size() > 0) {  
                        // ..data processing.. and update
                    }  
                }  
                datosAComprobar.clear();  
            }  
            consumer.commitSync();  
            Thread.sleep(100);  
        }  
    } catch(){...}  
}  

对数据库的请求(每个查询的结构相同):

public static List<Map<String, String>> FirstConsult(List<Map<String, String>> MyList, Connection conn) {  
    PreparedStatement stmt = null;  
    ResultSet rs = null;  
    List<Map<String, String>> list = new ArrayList<Map<String, String>>();  
    String query = "";  
    int contador = 1;  
    for (Map<String, String> val : MyList) {  
    query += "select " + val.get("row1") + " as r1, " + val.get("row2") + " as row2,"+val.get("cuenta")+"from table_a inner join table_b...."  
        if (contador < MyList.size()) {  
            query += "\r\nunion\r\n";  
        }  
        contador += 1;  
    }  
    try {  
        stmt = conn.prepareStatement(query);  
        rs = stmt.executeQuery();  
        ResultSetMetaData rsmd = rs.getMetaData();  
        int columnsNumber = rsmd.getColumnCount();  
        if (rs.next()) {  
            do {  
                Map<String, String> map = new HashMap<String, String>();  
                for (int i = 1; i <= columnsNumber; i++) {  
                    String columnValue = rs.getString(i);  
                    String columnName = rsmd.getColumnName(i);  
                    map.put(columnName, columnValue);  
                }  
                if (!map.isEmpty()) {  
                    list.add(map);  
                }  
            } while (rs.next());  
        }  
    } catch(e){...} finally {  
            try {  
                if(rs != null) rs.close();  
                if (stmt != null) stmt.close();  
            } catch (SQLException e) {...}  
    }  
    return list;  
}  

如何改进我的代码或至少与数据库的连接以获得更好的时间......? 当我加载更多记录时,它会变慢。 我需要关闭我的连接吗? 我关闭所有语句和结果集...

正如您所确定的,这不是一种有效的做事方式。 一种常见的模式是不查找数据库,而是将数据库带入 Kafka 并在那里完成工作。

您可以使用 CDC 将数据库表摄取到 Kafka 主题中,然后使用 stream 处理技术(例如 Kafka Streams 或 ksqlDB)将原始 Kafka 主题与从数据库填充的新 Kafka 主题中的必要数据连接起来。 这个谈话在这里展示了它的作用。

在您的情况下,您正在从不同的表中从数据库中获取数据,并且在再次更新回数据库表之后。

Kafka是分布式消息系统,可以由分区和消费者并行化。 意味着如果你有 N 个分区和 N 个消费者,我们可以将进程并行化到 N 个。

因此,如果您打算使用 Kafka,则意味着您应该并行化进程,这将跨进程共享负载并减少整体性能时间。

但请记住,在这种情况下,您将在 DB 端处理并行事务处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM