naivedogger commented on code in PR #4498:
URL: https://github.com/apache/flink-cdc/pull/4498#discussion_r3892361201
##########
docs/content.zh/docs/connectors/pipeline-connectors/fluss.md:
##########
@@ -99,6 +99,13 @@ Pipeline Connector Options
<td>String</td>
<td>用于建立与 Fluss 集群初始连接的主机/端口对列表。 </td>
</tr>
+ <tr>
+ <td>sink.partitioning.strategy</td>
+ <td>optional</td>
+ <td style="word-wrap: break-word;">DEFAULT</td>
+ <td>String</td>
+ <td>DataChangeEvent 路由使用的分区策略。可选值为 <code>DEFAULT</code> 和
<code>FORWARD</code>。<code>DEFAULT</code> 对主键表按主键 hash,对 log 表采用
round-robin。<code>FORWARD</code> 将数据事件发送到与上游 subtask 索引相同的下游 subtask,用于 Fluss 到
Fluss 的数据同步。上游数据分布必须与 Fluss 表的分桶策略保持一致,否则可能出现数据正确性问题。</td>
Review Comment:
The docs and ConfigOption description say DEFAULT uses round-robin for log
tables, but the actual implementation in FlussHashFunction uses
ThreadLocalRandom.current().nextInt(), which is a random value, not
round-robin. Could we align the docs here?
##########
docs/content/docs/connectors/pipeline-connectors/fluss.md:
##########
@@ -100,6 +100,13 @@ Pipeline Connector Options
<td>String</td>
<td>The bootstrap servers for the Fluss sink connection. </td>
</tr>
+ <tr>
+ <td>sink.partitioning.strategy</td>
+ <td>optional</td>
+ <td style="word-wrap: break-word;">DEFAULT</td>
+ <td>String</td>
+ <td>The partitioning strategy for DataChangeEvent routing. Available
values are <code>DEFAULT</code> and <code>FORWARD</code>. <code>DEFAULT</code>
hashes primary key tables by primary keys and routes log tables in round-robin
mode. <code>FORWARD</code> routes data events to downstream subtasks with the
same indices as upstream and is intended for Fluss-to-Fluss data
synchronization. The upstream data distribution must match the Fluss table
bucket distribution; otherwise, data correctness issues may occur.</td>
Review Comment:
ditto
##########
flink-cdc-common/src/main/java/org/apache/flink/cdc/common/sink/ForwardHashFunctionProvider.java:
##########
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.cdc.common.sink;
+
+import org.apache.flink.cdc.common.annotation.Internal;
+import org.apache.flink.cdc.common.event.DataChangeEvent;
+import org.apache.flink.cdc.common.event.TableId;
+import org.apache.flink.cdc.common.function.HashFunction;
+import org.apache.flink.cdc.common.function.HashFunctionProvider;
+import org.apache.flink.cdc.common.schema.Schema;
+
+import javax.annotation.Nullable;
+
+/** A {@link HashFunctionProvider} that preserves the upstream subtask
distribution. */
+@Internal
+public class ForwardHashFunctionProvider implements
HashFunctionProvider<DataChangeEvent> {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public HashFunction<DataChangeEvent> getHashFunction(@Nullable TableId
tableId, Schema schema) {
+ return new ForwardHashFunction();
+ }
+
+ private static class ForwardHashFunction implements
HashFunction<DataChangeEvent> {
+
+ @Override
+ public int hashcode(DataChangeEvent event) {
+ return 0;
Review Comment:
I see that ForwardHashFunction overrides both hashcode(int sourceIndex,
DataChangeEvent event) and hashcode(DataChangeEvent event). The single-arg
version returns 0.
My understanding is that hashcode(int sourceIndex, T event) is a default
method on the interface, so the only reason to implement the single-arg version
is that it's the abstract contract. But this raises two questions:
1. Is the single-arg override actually needed? If every call site in the
pipeline now uses the two-arg overload, can we just leave the single-arg
version unimplemented (i.e., rely on the default)? Or does something in the
framework force us to provide it?
2. If we do need to implement it, shouldn't it throw rather than silently
return 0? Returning 0 means that if someone accidentally regresses a call site
back to hashcode(event), every record from every source subtask gets routed to
sink subtask 0.
##########
flink-cdc-connect/flink-cdc-pipeline-connectors/flink-cdc-pipeline-connector-fluss/src/main/java/org/apache/flink/cdc/connectors/fluss/sink/FlussDataSinkOptions.java:
##########
@@ -33,6 +33,17 @@ public class FlussDataSinkOptions {
.noDefaultValue()
.withDescription("The bootstrap servers for the Fluss sink
connection.");
+ public static final ConfigOption<SinkPartitioningStrategy>
SINK_PARTITIONING_STRATEGY =
+ ConfigOptions.key("sink.partitioning.strategy")
+ .enumType(SinkPartitioningStrategy.class)
+ .defaultValue(SinkPartitioningStrategy.DEFAULT)
+ .withDescription(
+ "Partitioning strategy for DataChangeEvent
routing. "
+ + "DEFAULT hashes primary key tables by
primary keys and routes log tables in round-robin mode. "
Review Comment:
ditto
##########
flink-cdc-common/src/main/java/org/apache/flink/cdc/common/function/HashFunction.java:
##########
@@ -28,4 +28,14 @@
public interface HashFunction<T> {
int hashcode(T event);
+
+ /**
+ * Calculates the hash code with the upstream source subtask index.
+ *
+ * <p>Implementations that do not depend on the source subtask index can
continue implementing
+ * {@link #hashcode(Object)} only.
+ */
+ default int hashcode(int sourceIndex, T event) {
Review Comment:
+1
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]