[英]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.