0% found this document useful (0 votes)
21 views15 pages

Data Partitioning Techniques Explained

The document discusses data partitioning, or sharding, as a method to manage increasing data loads and query rates by distributing data across multiple nodes. It outlines different partitioning strategies, including vertical and horizontal sharding, and their respective advantages and disadvantages. Additionally, it addresses challenges related to load balancing and rebalancing partitions, as well as the implications of using secondary indexes in partitioned databases.

Uploaded by

avnish
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views15 pages

Data Partitioning Techniques Explained

The document discusses data partitioning, or sharding, as a method to manage increasing data loads and query rates by distributing data across multiple nodes. It outlines different partitioning strategies, including vertical and horizontal sharding, and their respective advantages and disadvantages. Additionally, it addresses challenges related to load balancing and rebalancing partitions, as well as the implications of using secondary indexes in partitioned databases.

Uploaded by

avnish
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

03/03/2025, 00:19 Data Partitioning

Grokking the Modern System Design Interview / ... / Data Partitioning

Data Partitioning
Learn about data partitioning models along with their pros and cons.

Why do we partition data?


Data is an asset for any organization. Increasing data and concurrent read/write
traffic to the data puts scalability pressure on traditional databases. As a result,
the latency and throughput are affected. Traditional databases are attractive
due to their properties such as range queries, secondary indices, and
transactions with the ACID properties.

At some point, a single node-based database isn’t enough to tackle the load.
We might need to distribute the data over many nodes but still export all the
nice properties of relational databases. In practice, it has proved challenging to
provide single-node database-like properties over a distributed database.

One solution is to move data to a NoSQL-like system. However, the historical


codebase and its close cohesion with traditional databases make it an
expensive problem to tackle.

Organizations might scale traditional databases by using a third-party solution.


But often, integrating a third-party solution has its complexities. More
importantly, there are abundant opportunities to optimize for the specific
problem at hand and get much better performance than a general-purpose
solution.

Data partitioning (or sharding) enables us to use multiple nodes where each
node manages some part of the whole data. To handle increasing query rates

[Link] 1/15
03/03/2025, 00:19 Data Partitioning

and data amounts, we strive for balanced partitions and balanced read/write
load.

We’ll discuss different ways to partition data, related challenges, and their
solutions in this lesson.

Partition 0

User Server Database

Partition 1

A database with two partitions to distribute the data and associated read/write load

Sharding
To divide load among multiple nodes, we need to partition the data by a
phenomenon known as partitioning or sharding. In this approach, we split a
large dataset into smaller chunks of data stored at different nodes on our
network.

The partitioning must be balanced so that each partition receives about the
same amount of data. If partitioning is unbalanced, the majority of queries will
fall into a few partitions. Partitions that are heavily loaded will create a system
bottleneck. The efficacy of partitioning will be harmed because a significant
portion of data retrieval queries will be sent to the nodes that carry the highly
congested partitions. Such partitions are known as hotspots. Generally, we use
the following two ways to shard the data:

Vertical sharding
Horizontal sharding

Vertical sharding

[Link] 2/15
03/03/2025, 00:19 Data Partitioning

We can put different tables in various database instances, which might be


running on a different physical server. We might break a table into multiple
tables so that some columns are in one table while the rest are in the other. We
should be careful if there are joins between multiple tables. We may like to keep
such tables together on one shard.

Often, vertical sharding is used to increase the speed of data retrieval from a
table consisting of columns with very wide text or a binary large object (blob).
In this case, the column with large text or a blob is split into a different table.

As shown in the figure a couple paragraphs below, the Employee table is


divided into two tables: a reduced Employee table and an EmployeePicture
table. The EmployeePicture table has just two columns, EmployeeID and
Picture, separated from the original table. Moreover, the primary key
EmployeeID of the Employee table is added in both partitioned tables. This

makes the data read and write easier, and the reconstruction of the table is
performed efficiently.

Vertical sharding has its intricacies and is more amenable to manual


partitioning, where stakeholders carefully decide how to partition data. In
comparison, horizontal sharding is suitable to automate even under dynamic
conditions.

Employee

Employee EmployeeID

EmployeeID Name

Name

Picture EmployeePicture

EmployeeID

Picture

Vertical partitioning

Note: Creating shards by moving specific tables of a database around


is also a form of vertical sharding. Usually, those tables are put in the
same shard because they often appear together in queries, for
[Link] 3/15
03/03/2025, 00:19 Data Partitioning

example, for joins. We will see an example of such a use-case ahead in


the course.

Horizontal sharding
At times, some tables in the databases become too big and affect read/write
latency. Horizontal sharding or partitioning is used to divide a table into
multiple tables by splitting data row-wise, as shown in the figure in the next
section. Each partition of the original table distributed over database servers is
called a shard. Usually, there are two strategies available:

Key-range based sharding


Hash based sharding

Key-range based sharding

In the key-range based sharding, each partition is assigned a continuous


range of keys.

In the following figure, horizontal partitioning on the Invoice table is performed


using the key-range based sharding with Customer_Id as the partition key. The
two different colored tables represent the partitions.

[Link] 4/15
03/03/2025, 00:19 Data Partitioning

Sometimes, a database consists of multiple tables bound by foreign key


relationships. In such a case, the horizontal partition is performed using the
same partition key on all tables in a relation. Tables (or subtables) that belong
to the same partition key are distributed to one database shard. The following
figure shows that several tables with the same partition key are placed in a
single database shard:

[Link] 5/15
03/03/2025, 00:19 Data Partitioning

The basic design techniques used in multi-table sharding are as follows:

There’s a partition key in the Customer mapping table. This table resides
on each shard and stores the partition keys used in the shard.
Applications create a mapping logic between the partition keys and
database shards by reading this table from all shards to make the
mapping efficient. Sometimes, applications use advanced algorithms to
determine the location of a partition key belonging to a specific shard.

The partition key column, Customer_Id, is replicated in all other tables as


a data isolation point. It has a trade-off between an impact on increased
storage and locating the desired shards efficiently. Apart from this, it’s
helpful for data and workload distribution to different database shards.
The data routing logic uses the partition key at the application tier to map
queries specified for a database shard.

Primary keys are unique across all database shards to avoid key collision
during data migration among shards and the merging of data in the online
analytical processing (OLAP) environment.
The column Creation_date serves as the data consistency point, with an
assumption that the clocks of all nodes are synchronized. This column is
[Link] 6/15
03/03/2025, 00:19 Data Partitioning

used as a criterion for merging data from all database shards into the
global view when essential.

Advantages

Using key-range-based sharding method, the range-query-based scheme


is easy to implement. We precisely know where (which node, which shard)
to look for a specific range of keys.
Range queries can be performed using the partitioning keys, and those
can be kept in partitions in sorted order. How exactly such a sorting
happens over time as new data comes in is implementation specific.

Disadvantages

Range queries can’t be performed using keys other than the partitioning
key.
If keys aren’t selected properly, some nodes may have to store more data
due to an uneven distribution of the traffic.

Hash-based sharding

Hash-based sharding uses a hash function on an attribute. This hash function


produces a hash value that is used to perform partitioning. The main concept is
to use a hash function on the key to get a hash value and then mod by the
number of partitions. Once we’ve found an appropriate hash function for keys,
we may give each partition a range of hashes (rather than a range of keys). Any
key whose hash occurs inside that range will be kept in that partition.

In the illustration below, we use a hash function of Value mod n. The n is the
number of nodes, which is four. We allocate keys to nodes by checking the
mod for each key. Keys with a mod value of 2 are allocated to node 2. Keys
with a mod value of 1 are allocated to node 1. Keys with a mod value of 3 are
allocated to node 3. Because there’s no key with a mod value of 0, node 0 is
left vacant.

[Link] 7/15
03/03/2025, 00:19 Data Partitioning

Advantages

Keys are uniformly distributed across the nodes.

Disadvantages

We can’t perform range queries with this technique. Keys will be spread
over all partitions.

Why do you need databases? Why can’t you just use files?

Write your answer in the widget below.

Want to know the correct answer?

Why do you need to use databases?

Provide your answer here!

Note: How many shards per database?

Empirically, we can determine how much each node can serve with
acceptable performance. It can help us find out the maximum amount
of data that we would like to keep on any one node. For example, if we
[Link] 8/15
03/03/2025, 00:19 Data Partitioning

find out that we can put a maximum of 50 GB of data on one node, we


have the following:

Database size = 10 TB

Size of a single shard = 50 GB

Number of shards the database should be distributed in = 10 TB/50


GB = 200 shards

Consistent hashing

Consistent hashing assigns each server or item in a distributed hash table a


place on an abstract circle, called a ring, irrespective of the number of servers
in the table. This permits servers and objects to scale without compromising
the system’s overall performance.

Advantages of consistent hashing

It’s easy to scale horizontally.


It increases the throughput and improves the latency of the application.

Disadvantages of consistent hashing

Randomly assigning nodes in the ring may cause non-uniform distribution.

Rebalance the partitions


Query load can be imbalanced across the nodes due to many reasons,
including the following:

The distribution of the data isn’t equal.


There’s too much load on a single partition.
There’s an increase in the query traffic, and we need to add more nodes to
keep up.

We can apply the following strategies to rebalance partitions.

Avoid hash mod n

[Link] 9/15
03/03/2025, 00:19 Data Partitioning

Usually, we avoid the hash of a key for partitioning (we used such a scheme to
explain the concept of hashing in simple terms earlier). The problem with the
addition or removal of nodes in the case of hashmodn is that every node’s
partition number changes and a lot of data moves. For example, assume we
have hash(key) = 1235. If we have five nodes at the start, the key will start
on node 1 (1235 mod 5 = 0). Now, if a new node is added, the key would
have to be moved to node 6 (1235 mod 6 = 5), and so on. This moving of
keys from one node to another makes rebalancing costly.

Fixed number of partitions

In this approach, the number of partitions to be created is fixed at the time


when we set our database up. We create a higher number of partitions than the
nodes and assign these partitions to nodes. So, when a new node is added to
the system, it can take a few partitions from the existing nodes until the
partitions are equally divided.

There’s a downside to this approach. The size of each partition grows with the
total amount of data in the cluster since all the partitions contain a small part of
the total data. If a partition is very small, it will result in too much overhead
because we may have to make a large number of small-sized partitions, each
costing us some overhead. If the partition is very large, rebalancing the nodes
and recovering from node failures will be expensive. It’s very important to
choose the right number of partitions. A fixed number of partitions is used in
Elasticsearch, Riak, and many more.

Dynamic partitioning

In this approach, when the size of a partition reaches the threshold, it’s split
equally into two partitions. One of the two split partitions is assigned to one
node and the other one to another node. In this way, the load is divided equally.
The number of partitions adapts to the overall data amount, which is an
advantage of dynamic partitioning.

[Link] 10/15
03/03/2025, 00:19 Data Partitioning

However, there’s a downside to this approach. It’s difficult to apply dynamic


rebalancing while serving the reads and writes. Dynamic rebalancing during
reads and writes is challenging because it involves moving data between
nodes, causing latency and potential conflicts. Ensuring data consistency (as
data is simultaneously moved and accessed) and availability (potentially
requiring pauses in reads/writes during rebalancing) introduces complexities
that can impact system performance and reliability. This approach is used in
HBase and MongoDB.

Partition proportionally to nodes

In this approach, the number of partitions is proportionate to the number of


nodes, which means every node has fixed partitions. In earlier approaches, the
number of partitions was dependent on the size of the dataset. That isn’t the
case here. While the number of nodes remains constant, the size of each
partition rises according to the dataset size. However, as the number of nodes
increases, the partitions shrink. When a new node enters the network, it splits a
certain number of current partitions at random, then takes one half of the split
and leaves the other half alone. This can result in an unfair split. This approach
is used by Cassandra and Ketama.

Point to Ponder

1. Who performs the rebalancing? Is it automatic or manual?

Show Answer

Q1 / Q1

Did you find this helpful?

Partitioning and secondary indexes


We’ve discussed key-value data model partitioning schemes in which the
records are retrieved with primary keys. But what if we have to access the
[Link] 11/15
03/03/2025, 00:19 Data Partitioning

records through secondary indexes? Secondary indexes are the records that
aren’t identified by primary keys but are just a way of searching for some value.
For example, the above illustration of horizontal partitioning contains the
customer table, searching for all customers with the same creation year.

We can partition with secondary indexes in the following ways.

Partition secondary indexes by document

Each partition is fully independent in this indexing approach. Each partition has
its secondary indexes covering just the documents in that partition. It’s
unconcerned with the data held in other partitions. If we want to write anything
to our database, we need to handle that partition only containing the document
ID we’re writing. It’s also known as the local index. In the illustration below,
there are three partitions, each having its own identity and data. If we want to
get all the customer IDs with the name John, we have to request from all
partitions.

However, this type of querying on secondary indexes can be expensive. As a


result of being restricted by the latency of a poor-performing partition, read
query latencies may increase.

Partitioning secondary indexes by document

[Link] 12/15
03/03/2025, 00:19 Data Partitioning

Partition secondary indexes by the term

Instead of creating a secondary index for each partition (a local index), we can
make a global index for secondary terms that encompasses data from all
partitions.

In the illustration below, we create indexes on names (the term on which we’re
partitioning) and store all the indexes for names on separated nodes. To get the
cust_id of all the customers named John, we must determine where our term
index is located. The index 0 contains all the customers with names starting
with “A” to “M.” The index 1 includes all the customers with names beginning
with “N” to “Z.” Because John lies in index 0, we fetch a list of cust_id with
the name John from index 0.

Partitioning secondary indexes by the term is more read-efficient than


partitioning secondary indexes by the document. This is because it only
accesses the partition that contains the term. However, a single write in this
approach affects multiple partitions, making the method write-intensive and
complex.

Partitioning secondary indexed by the term

[Link] 13/15
03/03/2025, 00:19 Data Partitioning

Request routing
We’ve learned how to partition our data. However, one question arises here:
How does a client know which node to connect to while making a request? The
allocation of partitions to nodes varies after rebalancing. If we want to read a
specific key, how do we know which IP address we need to connect to read?

This problem is also known as service discovery. Following are a few


approaches to this problem:

Allow the clients to request any node in the network. If that node doesn’t
contain the requested data, it forwards that request to the node that does
contain the related data.

The second approach contains a routing tier. All the requests are first
forwarded to the routing tier, and it determines which node to connect to
fulfill the request.

The clients already have the information related to partitioning and which
partition is connected to which node. So, they can directly contact the
node that contains the data they need.

In all of these approaches, the main challenge is to determine how these


components know about updates in the partitioning of the nodes.

ZooKeeper
To track changes in the cluster, many distributed data systems need a separate
management server like ZooKeeper. Zookeeper keeps track of all the
mappings in the network, and each node connects to ZooKeeper for the
information. Whenever there’s a change in the partitioning, or a node is added
or removed, ZooKeeper gets updated and notifies the routing tier about the
change. HBase, Kafka and SolrCloud use ZooKeeper.

Let’s assess our understanding of what’s described in this lesson


with the following question:
[Link] 14/15
03/03/2025, 00:19 Data Partitioning

Imagine you’re a database architect for a rapidly expanding e-


commerce platform with a global user base. The platform
experiences varying user activity levels across different regions, as
illustrated below. The existing monolithic database struggles to
handle the increasing load. Users in different regions have distinct
sets of preferences and tend to interact more within their regions.

[Link] 15/15

You might also like