Saturday, May 18, 2024
No menu items!
HomeDatabase ManagementTune replication performance with AWS DMS for an Amazon Kinesis Data Streams...

Tune replication performance with AWS DMS for an Amazon Kinesis Data Streams target endpoint – Part 2

In Part 1 of this series, we discussed the architecture of multi-threaded full load and change data capture (CDC) settings, and considerations and best practices for configuring various parameters when replicating data using AWS Database Migration Service (AWS DMS) from a relational database system to Amazon Kinesis Data Streams. In this post, we demonstrate the effect of changing various parameters on the throughput for the full load and CDC phases. The main parameters we considered are the AWS DMS settings for the parallel load and parallel apply and the number of shards in Kinesis Data Streams.

Test environment configuration

To demonstrate the behaviors outlined in Part 1, we assembled several different configurations for parallel load and apply settings, custom table mapping rules to define partition keys, and target Kinesis Data Streams shards. We chose Amazon Relational Database (Amazon RDS) for PostgreSQL as the source database engine, using PostgreSQL 13.7 running on an r5.xlarge instance using the pglogical plugin. We used AWS DMS for data migration, using engine version 3.4.7 running on an dms.r5.xlarge instance.

We created a table named large_test with the following table definition:

CREATE TABLE IF NOT EXISTS public.large_test
(
pk integer NOT NULL DEFAULT nextval(‘large_test_pk_seq’::regclass),
num2 double precision,
num3 double precision,
CONSTRAINT large_test_pkey PRIMARY KEY (pk)
);

CREATE SEQUENCE IF NOT EXISTS public.large_test_pk_seq
INCREMENT 1
START 1
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;

We then loaded the data (approximately 1 million records) into the table large_test for all the test scenarios for full load and tested the throughput for the replication performance. For the full load, the throughput is measured in terms of Fullloadthroughputrowstarget (count/second) and Networktransmithroughput (bytes/second). For CDC, we created a procedure to produce a high volume of changes against the table large_test at a given time and tested the replication performance. The CDC throughput is measured in terms of CDClatencytarget (seconds) and Networktransmithroughput (bytes/second). We discuss the scenarios and results in the following sections.

Scenario 1: Full load with no parallel load settings and no custom table mappings

We created an AWS DMS task for full load with large_test as the source and Kinesis Data Streams with provisioned mode as the target. Within the AWS DMS task, for benchmarking purposes, we did not use parallel load settings or custom table mapping rules.

We choose four shards in Kinesis Data Streams for this test case and the following settings:

“ParallelLoadQueuesPerThread”: 0,
“ParallelLoadThreads”: 0,
“ParallelLoadBufferSize”: 0

With these settings, we were able to baseline at around 115 records per second ingested into the Kinesis data stream. The following figure shows the corresponding row throughput.

The following figure shows the corresponding network throughput at around 350 KB/s.

We also baselined this configuration against Kinesis Data Streams with eight provisioned shards with the rest of parallel load settings or custom table mapping rules the same as the previous scenario (1a). The test showed a moderate increase to the records per second at 125, as shown in the following figures.

The following figure shows the corresponding network throughput at around 360 KB/s.

Scenario 2: Full load with no parallel load settings and with custom table mapping

In this scenario, with the parallel load settings remaining the same as earlier, we adjusted the AWS DMS task to use the custom table mapping as follows:

{
“rules”:
[
{
“rule-type”: “selection”,
“rule-id”: “967609532”,
“rule-name”: “967609532”,
“object-locator”:
{
“schema-name”: “public”,
“table-name”: “large_test”
},
“rule-action”: “include”,
“filters”:
[]
},
{
“rule-type”: “object-mapping”,
“rule-id”: “23”,
“rule-name”: “TransformToKinesis”,
“rule-action”: “map-record-to-record”,
“target-table-name”: “large_test”,
“object-locator”:
{
“schema-name”: “public”,
“table-name”: “large_test”
},
“mapping-parameters”:
{
“partition-key-type”: “attribute-name”,
“partition-key-name”: “pk”,
“attribute-mappings”:
[
{
“target-attribute-name”: “pk”,
“attribute-type”: “scalar”,
“attribute-sub-type”: “number”,
“value”: “${pk}”
},
{
“target-attribute-name”: “num_2”,
“attribute-type”: “scalar”,
“attribute-sub-type”: “number”,
“value”: “${num2}”
},
{
“target-attribute-name”: “num_3”,
“attribute-type”: “scalar”,
“attribute-sub-type”: “number”,
“value”: “${num3}”
}
]
}
}
]
}

When using the default settings (with no custom table mapping defined), AWS DMS sets the AWS DMS object mapping parameter partition-key-type to the primary key of the table. You can choose to set partition-key-type to schema-table, meaning the same table in the same schema of the source database will be loaded to the same shard in Kinesis Data Streams.

By setting partition-key-type to the primary key, you can force AWS DMS to use the Kinesis PutRecords API, and distribute the records across all of the target shards per the partition key.

With these custom table mapping rules, we achieved 108 records per second for a four-shard target, as shown in the following figures.

The following figure shows the corresponding network throughput at around 350 KB/s.

Using these custom table mapping rules, we achieved 116 records per second for an eight-shard target, as shown in the following figures. The use of custom table mapping did not change the throughput much, but you can control how the data is distributed among shards and avoid any potential hot shards.

The following figure shows the corresponding network throughput at around 375 KB/s.

Scenario 3: Parallel load settings with no custom table mappings

We altered the AWS DMS task to use the parallel load settings and removed the custom table mappings. The settings and results are as follows for four and eight Kinesis shards.

For a four-shard target, we used the following settings and achieved 700 records per second:

“ParallelLoadQueuesPerThread”: 1,
“ParallelLoadThreads”: 4,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 1.5 MB/s.

For a four-shard target, we use the following settings and achieved 1,440 records per second:

“ParallelLoadQueuesPerThread”: 2,
“ParallelLoadThreads”: 4
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 1.25 KB/s.

For a four-shard target, we used the following settings and achieved 2,733 records per second:

“ParallelLoadQueuesPerThread”: 4,
“ParallelLoadThreads”: 8,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 2.5 MB/s.

For an eight-shard target, we used the following settings and achieved 1,450 records per second:

“ParallelLoadQueuesPerThread”: 1,
“ParallelLoadThreads”: 4,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 1.25 MB/s.

For an eight-shard target, we used the following settings and achieved 1,430 records per second:

“ParallelLoadQueuesPerThread”: 2,
“ParallelLoadThreads”: 4,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 1.25 MB/s.

For an eight-shard target, we used the following settings and achieved 1,433 records per second:

“ParallelLoadQueuesPerThread”: 1,
“ParallelLoadThreads”: 8,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 2.75 MB/s.

For an eight-shard target, we used the following settings and achieved 2,880 records per second:

“ParallelLoadQueuesPerThread”: 2,
“ParallelLoadThreads”: 8,
“ParallelLoadBufferSize”: 100

The following figure shows the corresponding network throughput at around 2.75 MB/s.

As you can observe in these examples, the throughput increases as we increase the number of shards and the number of threads in the parallel load settings. As discussed in Part 1 and as a general rule, the number of parallel load threads can be set equal to the number of Kinesis shards for optimal performance. A shard supports up to 1 MB/s as throughput; for more information, refer to Amazon Kinesis Data Streams FAQs.

Scenario 4: Parallel load settings with custom table mappings

In this post, we haven’t demonstrated parallel load settings with custom table mappings. The results were similar to the previous scenarios with the parallel load settings because we choose the partition key as the primary key of the table.

Summary of full load tests

The following table summarizes the full load tests with four shards.

.
Default Task Mapping
Custom Task Mapping

Parallel Load Threads
0
0
4
4
8

Parallel Load Queues per Thread
0
0
1
2
4

Parallel Load Buffer Size
0
0
100
100
100

Records per Second
115
108
700
1440
2733

Average Network Transmit Throughput (Bytes/Sec)
350,000
350,000
1500,000
1,250,000
2,500,000

The following table summarizes the full load tests with eight shards.

.
Default Table Mapping
Custom Table Mapping

Parallel Load Threads
0
0
4
4
8
8

Parallel Load Queues per Thread
0
0
1
2
1
2

Parallel Load Buffer Size
0
0
100
100
100
100

Records per Second
125
116
1450
1430
1433
2880

Average Network Transmit Throughput (Bytes/Sec)
360,000
375,000
1,250,000
1,250,000
2,750,000
2,750,000

Scenario 5: CDC with no parallel apply

In this scenario, we tested the CDC performance by setting up a procedure to issue a high volume of CDC records against the source. We measure the CDC latency target defined as the gap, in seconds, between the first event timestamp waiting to commit on the target and the current timestamp of the AWS DMS instance. Target latency is the difference between the replication instance server time and the oldest unconfirmed event ID forwarded to a target component. For more details on CDC monitoring, refer to MonitoringAWS DMS tasks.

The function code is as follows:

DO
$do$
BEGIN
FOR i IN 1..1000 LOOP
BEGIN

INSERT INTO large_test (num2, num3)
SELECT random(), random()*142
FROM generate_series(1, 500) s(i);
end;
END LOOP;
END;
$do$;

The preceding function generally ran in seconds against the source table large_test.

To gain some good benchmarking, we configured a CDC-only task with no parallel apply settings or custom table mappings and used the same methodology to test with four and eight shards.

For a four-shard target and with no parallel apply settings, we achieved 35 records per second.

“ParallelApplyThreads”: 0,
“ParallelApplyBufferSize”: 0,
“ParallelApplyQueuesPerThread”: 0

The following figure shows the corresponding network throughput at around 400 KB/s.

Next, we applied parallel apply settings and tested with a four-shard target and eight-shard target.

For a four shard-target with the following settings, we achieved 240 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 1

The following figure shows the corresponding network throughput at around 1.45 MB/s.

For a four-shard target with the following settings, we achieved 280 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 2

The following figure shows the corresponding network throughput at around 1.45 MB/s.

For a four-shard target with the following settings, we achieved 1,282 records per second:

“ParallelApplyQueuesPerThread”: 4,
“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100

The following figure shows the corresponding network throughput at around 1.4 MB/s.

For a four-shard target with the following settings, we achieved 1,388 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 1000,
“ParallelApplyQueuesPerThread”: 4

The following figure shows the corresponding network throughput at around 1.45 MB/s.

For a four-shard target with the following settings, we achieved 2,380 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 16

The following figure shows the corresponding network throughput at around 3.0 MB/s.

For a four-shard target with the following settings, we achieved 2,777 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 1000,
“ParallelApplyQueuesPerThread”: 16

The following figure shows the corresponding network throughput at around 3.0 MB/s.

For a four-shard target with the following settings, we achieved 2,777 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 4

The following figure shows the corresponding network throughput at around 3.0 MB/s.

In the following scenarios, we use the same testing methodology but with an eight-shard Kinesis target.

For an eight-shard target without any parallel apply settings, we achieved 35 records per second:

“ParallelApplyThreads”: 0,
“ParallelApplyBufferSize”: 0,
“ParallelApplyQueuesPerThread”: 0

The following figure shows the corresponding network throughput at around 400 KB/s.

For an eight-shard target with the following parallel apply settings, we achieved 240 records per second

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 1

The following figure shows the corresponding network throughput at around 1.45 MB/s.

For an eight-shard target with the following parallel apply settings, we achieved 280 records per second:

“ParallelApplyThreads”: 4,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 2

The following figure shows the corresponding network throughput at around 1.45 MB/s.

For an eight-shard target with the following parallel apply settings, we achieved 333 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 1

The following figure shows the corresponding network throughput at around 2.6 MB/s.

For an eight-shard target with the following parallel apply settings, we achieved 555 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 2

The following figure shows the corresponding network throughput at around 2.75 MB/s.

For an eight-shard target with the following parallel apply settings, we achieved 2,777 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 4

The following figure shows the corresponding network throughput at around 3.25 MB/s.

For an eight-shard target with the following parallel apply settings, we achieved 2,777 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 1000,
“ParallelApplyQueuesPerThread”: 4

The following figure shows the corresponding network throughput at around 3.3 MB/s.

For an eight-shard target with the following settings, we achieved 4,166 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 100,
“ParallelApplyQueuesPerThread”: 16

The following figure shows the corresponding network throughput at around 5.25 MB/s.

For an eight-shard target with the following settings, we achieved 4,166 records per second:

“ParallelApplyThreads”: 8,
“ParallelApplyBufferSize”: 1000,
“ParallelApplyQueuesPerThread”: 16

The following figure shows the corresponding network throughput at around 5.25 MB/s.

Summary of CDC tests

The following table summarizes the CDC tests with four shards.

Parallel Apply Threads
0
4
4
4
4
4
4
8

Parallel Apply Queues per Thread
0
1
2
4
4
16
16
4

Parallel Apply Buffer Size
0
100
100
100
1000
100
1000
100

Records per Second
35
240
280
1282
1388
2380
2777
2777

Average Network Transmit Throughput (Bytes/Sec)
400,000
1,450,000
1,450,000
14,000,000
14,500,000
3,000,000
3,000,000
3000000

The following table summarizes the CDC tests with eight shards.

Parallel Apply Threads
0
4
4
8
8
8
8
8
8

Parallel Apply Queues per Thread
0
1
2
1
2
4
4
16
16

Parallel Apply Buffer Size
0
100
100
100
100
100
1000
100
1000

Records per Second
35
240
280
333
555
2777
2777
4166
4166

Average Network Transmit Throughput (Bytes/Sec)
400,000
1,450,000
1,450,000
2,600,000
2,750,000
3,250,000
3,300,000
5,250,000
5,250,000

Conclusion

In this post, we demonstrated the effect of changing various parameters on the throughput for full load and CDC phases when using AWS DMS to replicate data from a relational database system to a Kinesis data stream. In Part 3 of this series, we share some other considerations and best practices for using Kinesis Data Streams as a target.

If you have any questions or suggestions, leave them in the comments section.

About the Authors

Siva Thang is a Senior Solutions Architect, Partners with AWS. His specialty is in databases and analytics, and he also holds a master’s degree in Engineering. Siva is deeply passionate about helping customers build a modern data platform in the cloud that includes migrating to modern relational databases and building data lakes and data pipelines at scale for analytics and machine learning. Siva also likes to present in various conferences and summits on the topic of modern databases and analytics.

Suchindranath Hegde is a Data Migration Specialist Solutions Architect at Amazon Web Services. He works with our customers to provide guidance and technical assistance on data migration into the AWS Cloud using AWS DMS.

Wanchen Zhao is a Senior Database Specialist Solutions Architect at AWS. Wanchen specializes in Amazon RDS and Amazon Aurora, and is a subject matter expert for AWS DMS. Wanchen works with SI and ISV partners to design and implement database migration and modernization strategies and provides assistance to customers for building scalable, secure, performant, and robust database architectures in the AWS Cloud.

Michael Newlin is a Cloud Support DBE with Amazon Web Services and Subject Matter Expert for AWS DMS. At AWS, he works with customers and internal teams to ensure smooth and fast transitions of database workloads to AWS.

Jay Chen is a Software Development Manager at AWS DMS, where he oversees the development of DMS endpoints, including S3, Kinesis, Kafka, Opensearch, Timestream, and others. Jay is widely recognized for his significant contributions to the database field. He co-authored the Star Schema Benchmark, which is a standard benchmark based on the TPC-H benchmark for OLAP databases. Moreover, he has contributed as a co-author to C-STORE: A COLUMN-ORIENTED DBMS.

Read MoreAWS Database Blog

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments