Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,13 @@ public DataNodeConfig setTableQueryDeviceEntryBatchSizeInBytes(long batchSizeInB
setProperty("table_query_device_entry_batch_size_in_bytes", String.valueOf(batchSizeInBytes));
return this;
}

@Override
public DataNodeConfig setMppDataExchangeMaxPayloadSizeInBytes(
int mppDataExchangeMaxPayloadSizeInBytes) {
setProperty(
"mpp_data_exchange_max_payload_size_in_bytes",
String.valueOf(mppDataExchangeMaxPayloadSizeInBytes));
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,10 @@ public DataNodeConfig setDnMultiDirStrategy(String multiDirStrategy) {
public DataNodeConfig setTableQueryDeviceEntryBatchSizeInBytes(long batchSizeInBytes) {
return this;
}

@Override
public DataNodeConfig setMppDataExchangeMaxPayloadSizeInBytes(
int mppDataExchangeMaxPayloadSizeInBytes) {
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,6 @@ DataNodeConfig setLoadActiveListeningCheckIntervalSeconds(
DataNodeConfig setDnMultiDirStrategy(String multiDirStrategy);

DataNodeConfig setTableQueryDeviceEntryBatchSizeInBytes(long batchSizeInBytes);

DataNodeConfig setMppDataExchangeMaxPayloadSizeInBytes(int mppDataExchangeMaxPayloadSizeInBytes);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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.iotdb.relational.it.query.recent;

import org.apache.iotdb.isession.ITableSession;
import org.apache.iotdb.it.env.EnvFactory;

import org.apache.tsfile.enums.ColumnCategory;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.utils.Binary;
import org.apache.tsfile.write.record.Tablet;
import org.apache.tsfile.write.schema.IMeasurementSchema;
import org.apache.tsfile.write.schema.MeasurementSchema;
import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public abstract class AbstractIoTDBMPPDataExchangeLargeTsBlockIT {

protected static final String DATABASE_NAME = "large_tsblock";
protected static final int PAYLOAD_SIZE_IN_BYTES = 128 * 1024;
private static final int BLOB_SIZE_IN_BYTES = 2 * PAYLOAD_SIZE_IN_BYTES + 1;
private static final byte[] EXPECTED_BLOB = createBlob();

protected static void prepareData() throws Exception {
try (Connection connection = EnvFactory.getEnv().getTableConnection();
Statement statement = connection.createStatement()) {
statement.execute("CREATE DATABASE " + DATABASE_NAME);
statement.execute("USE " + DATABASE_NAME);
statement.execute("CREATE TABLE large_blob(payload BLOB FIELD)");
}

List<IMeasurementSchema> schemas = List.of(new MeasurementSchema("payload", TSDataType.BLOB));
Tablet tablet =
new Tablet(
"large_blob",
IMeasurementSchema.getMeasurementNameList(schemas),
IMeasurementSchema.getDataTypeList(schemas),
List.of(ColumnCategory.FIELD),
1);
tablet.addTimestamp(0, 1);
tablet.addValue("payload", 0, new Binary(EXPECTED_BLOB));

try (ITableSession session =
EnvFactory.getEnv().getTableSessionConnectionWithDB(DATABASE_NAME)) {
session.insert(tablet);
}
}

@Test
public void testLargeBlobTransferredInFragments() throws Exception {
assertTrue(EXPECTED_BLOB.length > PAYLOAD_SIZE_IN_BYTES);

try (Connection connection = EnvFactory.getEnv().getTableConnection();
Statement statement = connection.createStatement()) {
statement.execute("USE " + DATABASE_NAME);
try (ResultSet resultSet = statement.executeQuery("SELECT time, payload FROM large_blob")) {
assertTrue(resultSet.next());
assertEquals(1, resultSet.getLong("time"));
assertArrayEquals(EXPECTED_BLOB, resultSet.getBytes("payload"));
assertFalse(resultSet.next());
}
}
}

private static byte[] createBlob() {
byte[] blob = new byte[BLOB_SIZE_IN_BYTES];
for (int i = 0; i < blob.length; i++) {
blob[i] = (byte) (i * 31 + 7);
}
return blob;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* 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.iotdb.relational.it.query.recent;

import org.apache.iotdb.it.env.EnvFactory;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.TableClusterIT;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

@RunWith(IoTDBTestRunner.class)
@Category({TableClusterIT.class})
public class IoTDBMPPDataExchangeLargeTsBlock128KIT
extends AbstractIoTDBMPPDataExchangeLargeTsBlockIT {

@BeforeClass
public static void setUp() throws Exception {
EnvFactory.getEnv()
.getConfig()
.getDataNodeConfig()
.setMppDataExchangeMaxPayloadSizeInBytes(PAYLOAD_SIZE_IN_BYTES);
EnvFactory.getEnv().getConfig().getCommonConfig().setDataReplicationFactor(1);
EnvFactory.getEnv().initClusterEnvironment();
prepareData();
}

@AfterClass
public static void tearDown() {
EnvFactory.getEnv().cleanClusterEnvironment();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1488,5 +1488,14 @@ private DataNodeMiscMessages() {}
public static final String
LOG_TABLE_QUERY_DEVICE_ENTRY_BATCH_SIZE_IN_BYTES_ARG_EXCEEDS_DN_THRIFT_MAX_FRAME_SIZE_ARG_USING_ARG_AS_THE_EFFECTIVE_VALUE_2AE1BEDA =
"table_query_device_entry_batch_size_in_bytes (%d) exceeds the maximum RPC payload (dn_thrift_max_frame_size %d minus 1024 bytes); using %d as the effective value";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_NOT_POSITIVE_USING_DEFAULT_VALUE_ARG_1AA821B2 =
"mpp_data_exchange_max_payload_size_in_bytes (%d) is not positive, using default value %d";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_EXCEEDS_MAXIMUM_ALLOWED_VALUE_ARG_USING_ARG_D9BF0BBC =
"mpp_data_exchange_max_payload_size_in_bytes (%d) exceeds the maximum allowed value %d, using %d";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_BELOW_MINIMUM_ALLOWED_VALUE_ARG_USING_ARG_794ABC76 =
"mpp_data_exchange_max_payload_size_in_bytes (%d) is below the minimum allowed value %d, using %d";

}
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,26 @@ public final class DataNodeQueryMessages {
"failed to get data block [{}, {}), attempt times: {}";
public static final String EXCEPTION_UNEXPECTED_DATA_BLOCK_RESPONSE_SIZE_A7DD7E33 =
"Unexpected data block response size.";
public static final String
EXCEPTION_INVALID_SERIALIZED_TSBLOCK_FRAGMENT_OFFSET_ARG_FOR_BLOCK_SIZE_ARG_53BC0284 =
"Invalid serialized TsBlock fragment offset %s for block size %s.";
public static final String
EXCEPTION_ACCUMULATED_TSBLOCK_FRAGMENT_LENGTH_ARG_DOES_NOT_MATCH_TOTALLENGTH_ARG_1B784303 =
"Accumulated TsBlock fragment length %s does not match totalLength %s.";
public static final String
EXCEPTION_THE_FIRST_FRAGMENTED_DATA_BLOCK_RESPONSE_MUST_INCLUDE_TOTALLENGTH_C5C79BC2 =
"The first fragmented data block response must include totalLength.";
public static final String
EXCEPTION_NEXT_SEQUENCE_ID_ARG_EXCEEDS_REQUESTED_END_SEQUENCE_ID_ARG_30B1726E =
"Next sequence ID %s exceeds requested end sequence ID %s.";
public static final String
EXCEPTION_A_COMPLETED_DATA_BLOCK_RESPONSE_RANGE_MUST_NOT_RETAIN_A_PARTIAL_TSBLOCK_85E5C287 =
"A completed data block response range must not retain a partial TsBlock.";
public static final String EXCEPTION_TSBLOCK_FRAGMENT_MUST_NOT_BE_EMPTY_C7D19863 =
"TsBlock fragment must not be empty.";
public static final String
EXCEPTION_NEXT_FRAGMENT_OFFSET_ARG_MUST_BE_GREATER_THAN_CURRENT_OFFSET_ARG_AND_MATCH_ACCUMULATED_FRAGMENT_LENGTH_ARG_ECC31047 =
"Next fragment offset %s must be greater than current offset %s and match accumulated fragment length %s.";
public static final String FAILED_TO_SEND_ACK_DATA_BLOCK_EVENT =
"failed to send ack data block event [{}, {}), attempt times: {}";
public static final String SEND_CLOSE_SINK_CHANNEL_EVENT_FAILED =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1468,5 +1468,14 @@ private DataNodeMiscMessages() {}
public static final String
LOG_TABLE_QUERY_DEVICE_ENTRY_BATCH_SIZE_IN_BYTES_ARG_EXCEEDS_DN_THRIFT_MAX_FRAME_SIZE_ARG_USING_ARG_AS_THE_EFFECTIVE_VALUE_2AE1BEDA =
"table_query_device_entry_batch_size_in_bytes(%d)超过最大 RPC payload(dn_thrift_max_frame_size %d 减去 1024 字节),将使用 %d 作为生效值";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_NOT_POSITIVE_USING_DEFAULT_VALUE_ARG_1AA821B2 =
"mpp_data_exchange_max_payload_size_in_bytes(%d)不是正数,将使用默认值 %d";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_EXCEEDS_MAXIMUM_ALLOWED_VALUE_ARG_USING_ARG_D9BF0BBC =
"mpp_data_exchange_max_payload_size_in_bytes(%d)超过允许的最大值 %d,将使用 %d";
public static final String
LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_BELOW_MINIMUM_ALLOWED_VALUE_ARG_USING_ARG_794ABC76 =
"mpp_data_exchange_max_payload_size_in_bytes(%d)低于允许的最小值 %d,将使用 %d";

}
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,26 @@ public final class DataNodeQueryMessages {
"获取数据块 [{}, {}) 失败,尝试次数:{}";
public static final String EXCEPTION_UNEXPECTED_DATA_BLOCK_RESPONSE_SIZE_A7DD7E33 =
"数据块响应数量异常。";
public static final String
EXCEPTION_INVALID_SERIALIZED_TSBLOCK_FRAGMENT_OFFSET_ARG_FOR_BLOCK_SIZE_ARG_53BC0284 =
"序列化 TsBlock 分片偏移量 %s 无效,块大小为 %s。";
public static final String
EXCEPTION_ACCUMULATED_TSBLOCK_FRAGMENT_LENGTH_ARG_DOES_NOT_MATCH_TOTALLENGTH_ARG_1B784303 =
"TsBlock 分片累计长度 %s 与 totalLength %s 不一致。";
public static final String
EXCEPTION_THE_FIRST_FRAGMENTED_DATA_BLOCK_RESPONSE_MUST_INCLUDE_TOTALLENGTH_C5C79BC2 =
"首个分片数据块响应必须包含 totalLength。";
public static final String
EXCEPTION_NEXT_SEQUENCE_ID_ARG_EXCEEDS_REQUESTED_END_SEQUENCE_ID_ARG_30B1726E =
"下一个 sequence ID %s 超过请求的结束 sequence ID %s。";
public static final String
EXCEPTION_A_COMPLETED_DATA_BLOCK_RESPONSE_RANGE_MUST_NOT_RETAIN_A_PARTIAL_TSBLOCK_85E5C287 =
"已完成的数据块响应区间不能保留未完成的 TsBlock。";
public static final String EXCEPTION_TSBLOCK_FRAGMENT_MUST_NOT_BE_EMPTY_C7D19863 =
"TsBlock 分片不能为空。";
public static final String
EXCEPTION_NEXT_FRAGMENT_OFFSET_ARG_MUST_BE_GREATER_THAN_CURRENT_OFFSET_ARG_AND_MATCH_ACCUMULATED_FRAGMENT_LENGTH_ARG_ECC31047 =
"下一分片偏移量 %s 必须大于当前偏移量 %s,并且等于分片累计长度 %s。";
public static final String FAILED_TO_SEND_ACK_DATA_BLOCK_EVENT =
"发送数据块确认事件 [{}, {}) 失败,尝试次数:{}";
public static final String SEND_CLOSE_SINK_CHANNEL_EVENT_FAILED =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,8 @@ public class IoTDBConfig {
/** Core pool size of mpp data exchange. */
private int mppDataExchangeCorePoolSize = 10;

private int mppDataExchangeMaxPayloadSizeInBytes = 4 * 1024 * 1024;

/** Max pool size of mpp data exchange. */
private int mppDataExchangeMaxPoolSize = 10;

Expand Down Expand Up @@ -3417,6 +3419,14 @@ public void setMppDataExchangeKeepAliveTimeInMs(int mppDataExchangeKeepAliveTime
this.mppDataExchangeKeepAliveTimeInMs = mppDataExchangeKeepAliveTimeInMs;
}

public int getMppDataExchangeMaxPayloadSizeInBytes() {
return mppDataExchangeMaxPayloadSizeInBytes;
}

public void setMppDataExchangeMaxPayloadSizeInBytes(int mppDataExchangeMaxPayloadSizeInBytes) {
this.mppDataExchangeMaxPayloadSizeInBytes = mppDataExchangeMaxPayloadSizeInBytes;
}

public int getConnectionTimeoutInMS() {
return connectionTimeoutInMS;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ public class IoTDBDescriptor {

private static final double MIN_DIR_USE_PROPORTION = 0.5;

private static final int DEFAULT_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES = 4 * 1024 * 1024;

private static final int MIN_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES = 128 * 1024;

private static final String[] DEFAULT_WAL_THRESHOLD_NAME = {
"iot_consensus_throttle_threshold_in_byte", "wal_throttle_threshold_in_byte"
};
Expand Down Expand Up @@ -2277,6 +2281,8 @@ public synchronized void loadHotModifiedProps(TrimProperties properties)
memoryConfig.loadTableQueryDeviceEntryBatchSize(
properties, conf.getThriftMaxFrameSize(), LOGGER);

loadMppDataExchangeMaxPayloadSize(properties);

// update wal config
long prevDeleteWalFilesPeriodInMs = conf.getDeleteWalFilesPeriodInMs();
loadWALHotModifiedProps(properties);
Expand Down Expand Up @@ -2454,6 +2460,9 @@ private void overlayEffectiveConfigurationValues() {
ConfigurationFileUtils.updateAppliedProperties(
"table_query_device_entry_batch_size_in_bytes",
Long.toString(memoryConfig.getTableQueryDeviceEntryBatchSizeInBytes()));
ConfigurationFileUtils.updateAppliedProperties(
"mpp_data_exchange_max_payload_size_in_bytes",
Integer.toString(conf.getMppDataExchangeMaxPayloadSizeInBytes()));
ConfigurationFileUtils.updateAppliedProperties(
DEFAULT_WAL_THRESHOLD_NAME[1], Long.toString(conf.getThrottleThreshold()));
}
Expand Down Expand Up @@ -3076,6 +3085,8 @@ public void loadShuffleProps(TrimProperties properties) {
"mpp_data_exchange_keep_alive_time_in_ms",
Integer.toString(conf.getMppDataExchangeKeepAliveTimeInMs()))));

loadMppDataExchangeMaxPayloadSize(properties);

conf.setPartitionCacheSize(
Integer.parseInt(
properties.getProperty(
Expand All @@ -3088,6 +3099,44 @@ public void loadShuffleProps(TrimProperties properties) {
Integer.toString(commonConfig.getDriverTaskExecutionTimeSliceInMs()))));
}

private void loadMppDataExchangeMaxPayloadSize(TrimProperties properties) {
int configuredSize =
Integer.parseInt(
properties.getProperty(
"mpp_data_exchange_max_payload_size_in_bytes",
Integer.toString(conf.getMppDataExchangeMaxPayloadSizeInBytes())));
if (configuredSize <= 0) {
LOGGER.warn(
String.format(
DataNodeMiscMessages
.LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_NOT_POSITIVE_USING_DEFAULT_VALUE_ARG_1AA821B2,
configuredSize,
DEFAULT_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES));
configuredSize = DEFAULT_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES;
} else if (configuredSize < MIN_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES) {
LOGGER.warn(
String.format(
DataNodeMiscMessages
.LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_IS_BELOW_MINIMUM_ALLOWED_VALUE_ARG_USING_ARG_794ABC76,
configuredSize,
MIN_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES,
MIN_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES));
configuredSize = MIN_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_IN_BYTES;
}
int maxAllowedSize = conf.getThriftMaxFrameSize() - 1024;
if (configuredSize > maxAllowedSize) {
LOGGER.warn(
String.format(
DataNodeMiscMessages
.LOG_MPP_DATA_EXCHANGE_MAX_PAYLOAD_SIZE_ARG_EXCEEDS_MAXIMUM_ALLOWED_VALUE_ARG_USING_ARG_D9BF0BBC,
configuredSize,
maxAllowedSize,
maxAllowedSize));
configuredSize = maxAllowedSize;
}
conf.setMppDataExchangeMaxPayloadSizeInBytes(configuredSize);
}

/** Get default encode algorithm by data type */
public TSEncoding getDefaultEncodingByType(TSDataType dataType) {
switch (dataType) {
Expand Down
Loading
Loading