May two DynamoDB scan segments contain the same hash key?

Viewed 599

I'm scanning a huge table (> 1B docs) so I'm using a parallel scan (using one segment per worker).

The table has a hash key and a sort key.

Intuitively a segment should contain a set of hash keys (including all their sort keys), so one hash key shouldn't appear in more than one segment, but I haven't found any documentation indicating this.

Does anyone know how does DynamoDB behave in this scenario?

Thanks

2 Answers

This is an interesting question. I thought it would be easy to find a document stating that each segment contains a disjoint range of hash keys, and the same hash key cannot appear in more than one segment - but I too failed to find any such document. I am curious if anyone else can find such a document. In the meantime, I can try to offer additional intuitions on why your conjecture is likely correct - but also might be wrong:

My first intuition would be that you are right:

DynamoDB uses the hash key, also known as a partition key to decide on which of the many storage nodes to store copy of this data. All of the items sharing the same partition key (with different sort key values) are stored together, in sort-key order, so they can be Queryed together in order. DynamoDB uses a hash function on the partition key to decide the placement of each item (hence the name "hash key").

Now, if DynamoDB needs to divide the task of scanning all the data into "segments", the most sensible thing for it to do is to divide the space of hash values (i.e., hash function of the hash keys) to different equal-sized pieces. This division is easy to do (just a numeric division by TotalSegments), it ensures roughly the same amount of items in each segment (assuming there are many different partitions), and it ensures that the scanning of each segment involves a different storage node, so the parallel scan can proceed faster than what a single storage node is capable of.

However, there is one indication that this might not be the entire story.

The DynamoDB documentation claims that

In general, there is no practical limit on the number of distinct sort key values per partition key value.

This means that in theory at least, your entire database, perhaps one petabyte of it, may be in a single partition with billions of different sort keys. Since Amazon's single storage node do have a size limit, it means DynamoDB must (unless the above statement is false) support splitting of a single huge partition into multiple storage nodes. This means that when GetItem is looking for a particular item, DynamoDB needs to know which sort key is on which storage node. It also means that a parallel scan might - possibly - divide this huge partition into pieces, all scanning the same partition but different sort-key ranges in it. I am not sure we can completely rule out this possibility. I am guessing it will never happen when you only have smallish partitions.

Every DynamoDB table has a "hashspace" and data is partitioned as per the hash value of the partition key. When a ParallelScan is intended and the TotalSegments and Segment values are provided, the table's complete hashspace is logically divided into these "Segments" such that TotalSegments cover the complete hash space, without overlapping. It is quite possible some segments here do not actually have any data corresponding to them, since there may not be any data in the hashspace allocated to the segment. This can be observed if the TotalSegments value chosen is very high for instance.

And for each Segment value passed in the Scan request (with TotalSegments value being constant), each Segment would return distinct items without any overlap.

FAQs

Q. Ideal Number for TotalSegments ?

-> You might need to experiment with values, find the sweet spot for your table, and the number of workers you use, until your application achieves its best performance.

Q. One or more segments do not return any records. Why?

-> This is possible if the hash range that is allocated as per the TotalSegments value does not have any items. In this case, the TotalSegments value can be decreased, for better performance.

Q. Scan for a segment failed midway. Can a Scan for that segment alone be retried now ?

-> As long as the TotalSegments value remains the same, a Scan for one of the segments can be re-run, since it would have the same hash range allocated at any given time.

Q. Can I perform a Scan for a single segment, without performing the Scan for other segments as per TotalSegments value?

-> Yes. Multiple Scan operations for different Segments are not linked/do not depend on previous/other Segment Scans.

Related