Skip to content

Commit c52d255

Browse files
authored
Merge pull request #195960 from jonels-msft/hsc-building-scalable
How to create scalable apps with Hyperscale (Citus)
2 parents 7c6cb4e + 96ddb54 commit c52d255

17 files changed

+540
-8
lines changed

articles/postgresql/TOC.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,20 @@
684684
href: hyperscale/concepts-columnar.md
685685
- name: How-to guides
686686
items:
687+
- name: Build scalable apps
688+
items:
689+
- name: Overview
690+
href: hyperscale/howto-build-scalable-apps-overview.md
691+
- name: Fundamental concepts
692+
href: hyperscale/howto-build-scalable-apps-concepts.md
693+
- name: Classify workload
694+
href: hyperscale/howto-build-scalable-apps-classify.md
695+
- name: Model multi-tenant apps
696+
href: hyperscale/howto-build-scalable-apps-model-multi-tenant.md
697+
- name: Model real-time apps
698+
href: hyperscale/howto-build-scalable-apps-model-real-time.md
699+
- name: Model high-throughput apps
700+
href: hyperscale/howto-build-scalable-apps-model-high-throughput.md
687701
- name: Server group size
688702
items:
689703
- name: Pick initial size
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
---
2+
title: Classify application workload - Hyperscale (Citus) - Azure Database for PostgreSQL
3+
description: Classify workload for scalable application
4+
ms.author: jonels
5+
author: jonels-msft
6+
ms.service: postgresql
7+
ms.subservice: hyperscale-citus
8+
ms.topic: how-to
9+
ms.date: 04/28/2022
10+
---
11+
12+
# Classify application workload
13+
14+
Here are common characteristics of the workloads that are the best fit for
15+
Hyperscale (Citus).
16+
17+
## Prerequisites
18+
19+
This article assumes you know the [fundamental concepts for
20+
scaling](howto-build-scalable-apps-concepts.md). If you haven't read about
21+
them, take a moment to do so.
22+
23+
## Characteristics of multi-tenant SaaS
24+
25+
* Tenants see their own data; they can't see other tenants' data.
26+
* Most B2B SaaS apps are multi-tenant. Examples include Salesforce or Shopify.
27+
* In most B2B SaaS apps, there are hundreds to tens of thousands of tenants, and
28+
more tenants keep joining.
29+
* Multi-tenant SaaS apps are primarily operational/transactional, with single
30+
digit millisecond latency requirements for their database queries.
31+
* These apps have a classic relational data model, and are built using ORMs –
32+
like RoR, Hibernate, Django etc.
33+
<br><br>
34+
> [!VIDEO https://www.youtube.com/embed/7gAW08du6kk]
35+
36+
## Characteristics of real-time operational analytics
37+
38+
* These apps have a customer/user facing interactive analytics dashboard, with
39+
a subsecond query latency requirement.
40+
* High concurrency required - at least 20 users.
41+
* Analyzes data that's fresh, within the last one second to few minutes.
42+
* Most have time series data such as events, logs, etc.
43+
* Common data models in these apps include:
44+
* Star Schema - few large/fact tables, the rest being small/dimension tables
45+
* Mostly fewer than 20 major tables
46+
<br><br>
47+
> [!VIDEO https://www.youtube.com/embed/xGWVVTva434]
48+
49+
## Characteristics of high-throughput transactional
50+
51+
* Run NoSQL/document style workloads, but require PostgreSQL features such as
52+
transactions, foreign/primary keys, triggers, extension like PostGIS, etc.
53+
* The workload is based on a single key. It has CRUD and lookups based on that
54+
key.
55+
* These apps have high throughput requirements: thousands to hundreds of thousands of
56+
TPS.
57+
* Query latency in single-digit milliseconds, with a high concurrency
58+
requirement.
59+
* Time series data, such as internet of things.
60+
<br><br>
61+
> [!VIDEO https://www.youtube.com/embed/A9q7w96yO_E]
62+
63+
## Next steps
64+
65+
Choose whichever fits your application the best:
66+
67+
> [!div class="nextstepaction"]
68+
> [Model multi-tenant SaaS app >](howto-build-scalable-apps-model-multi-tenant.md)
69+
70+
> [!div class="nextstepaction"]
71+
> [Model real-time analytics app](howto-build-scalable-apps-model-real-time.md)
72+
73+
> [!div class="nextstepaction"]
74+
> [Model high-throughput app](howto-build-scalable-apps-model-high-throughput.md)
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
---
2+
title: Fundamental concepts for scaling - Hyperscale (Citus) - Azure Database for PostgreSQL
3+
description: Ideas you need to know to build relational apps that scale
4+
ms.author: jonels
5+
author: jonels-msft
6+
ms.service: postgresql
7+
ms.subservice: hyperscale-citus
8+
ms.topic: how-to
9+
ms.date: 04/28/2022
10+
---
11+
12+
# Fundamental concepts for scaling
13+
14+
Before we investigate the steps of building a new app, it's helpful to see a
15+
quick overview of the terms and concepts involved.
16+
17+
## Architectural overview
18+
19+
Hyperscale (Citus) gives you the power to distribute tables across multiple
20+
machines in a server group and transparently query them the same you query
21+
plain PostgreSQL:
22+
23+
![Diagram of the coordinator node sharding a table onto worker nodes.](../media/howto-hyperscale-build-scalable-apps/architecture.png)
24+
25+
In the Hyperscale (Citus) architecture, there are multiple kinds of nodes:
26+
27+
* The **coordinator** node stores distributed table metadata and is responsible
28+
for distributed planning.
29+
* By contrast, the **worker** nodes store the actual data and do the computation.
30+
* Both the coordinator and workers are plain PostgreSQL databases, with the
31+
`citus` extension loaded.
32+
33+
To distribute a normal PostgreSQL table, like `campaigns` in the diagram above,
34+
run a command called `create_distributed_table()`. Once you run this
35+
command, Hyperscale (Citus) transparently creates shards for the table across
36+
worker nodes. In the diagram, shards are represented as blue boxes.
37+
38+
> [!NOTE]
39+
>
40+
> On the basic tier, shards of distributed tables are on the coordinator node,
41+
> not worker nodes.
42+
43+
Shards are plain (but specially named) PostgreSQL tables that hold slices of
44+
your data. In our example, because we distributed `campaigns` by `company_id`,
45+
the shards hold campaigns, where the campaigns of different companies are
46+
assigned to different shards.
47+
48+
## Distribution column (also known as shard key)
49+
50+
`create_distributed_table()` is the magic function that Hyperscale (Citus)
51+
provides to distribute tables and use resources across multiple machines.
52+
53+
```postgresql
54+
SELECT create_distributed_table(
55+
'table_name',
56+
'distribution_column');
57+
```
58+
59+
The second argument above picks a column from the table as a **distribution
60+
column**. It can be any column with a native PostgreSQL type (with integer and
61+
text being most common). The value of the distribution column determines which
62+
rows go into which shards, which is why the distribution column is also called
63+
the **shard key**.
64+
65+
Hyperscale (Citus) decides how to run queries based on their use of the shard
66+
key:
67+
68+
| Query involves | Where it runs |
69+
|----------------|---------------|
70+
| just one shard key | on the worker node that holds its shard |
71+
| multiple shard keys | parallelized across multiple nodes |
72+
73+
The choice of shard key dictates the performance and scalability of your
74+
applications.
75+
76+
* Uneven data distribution per shard keys (also known as *data skew*) isn't optimal
77+
for performance. For example, don’t choose a column for which a single value
78+
represents 50% of data.
79+
* Shard keys with low cardinality can affect scalability. You can use only as
80+
many shards as there are distinct key values. Choose a key with cardinality
81+
in the hundreds to thousands.
82+
* Joining two large tables with different shard keys can be slow. Choose a
83+
common shard key across large tables. Learn more in
84+
[colocation](#colocation).
85+
86+
## Colocation
87+
88+
Another concept closely related to shard key is *colocation*. Tables sharded by
89+
the same distribution column values are colocated - The shards of colocated
90+
tables are stored together on the same workers.
91+
92+
Below are two tables sharded by the same key, `site_id`. They're colocated.
93+
94+
![Diagram of tables http_request and http_request_1min colocated by site_id.](../media/howto-hyperscale-build-scalable-apps/colocation.png)
95+
96+
Hyperscale (Citus) ensures that rows with a matching `site_id` value in both
97+
tables are stored on the same worker node. You can see that, for both tables,
98+
rows with `site_id=1` are stored on worker 1. Similarly for other site IDs.
99+
100+
Colocation helps optimize JOINs across these tables. If you join the two tables
101+
on `site_id`, Hyperscale (Citus) can perform the join locally on worker nodes
102+
without shuffling data between nodes.
103+
104+
## Next steps
105+
106+
> [!div class="nextstepaction"]
107+
> [Classify application workload >](howto-build-scalable-apps-classify.md)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Model high throughput apps - Hyperscale (Citus) - Azure Database for PostgreSQL
3+
description: Techniques for scalable high-throughput transactional apps
4+
ms.author: jonels
5+
author: jonels-msft
6+
ms.service: postgresql
7+
ms.subservice: hyperscale-citus
8+
ms.topic: how-to
9+
ms.date: 04/28/2022
10+
---
11+
12+
# Model high-throughput transactional apps
13+
14+
## Common filter as shard key
15+
16+
To pick the shard key for a high-throughput transactional (HTAP) application,
17+
follow these guidelines:
18+
19+
* Choose a column that is used for point lookups and is present in most
20+
create, read, update, and delete operations.
21+
* Choose a column that is a natural dimension in the data, or a central piece
22+
of the application. For example:
23+
* In an IOT workload, `device_id` is a good distribution column.
24+
25+
The choice of a good shard key helps optimize network hops, while taking
26+
advantage of memory and compute to achieve millisecond latency.
27+
28+
## Optimal data model for high-throughput apps
29+
30+
Below is an example of a sample data-model for an IoT app that captures
31+
telemetry (time series data) from devices. There are two tables for capturing
32+
telemetry: `devices` and `events`. There could be other tables, but they're not
33+
covered in this example.
34+
35+
![Diagram of events and devices tables, and partitions of events.](../media/howto-hyperscale-build-scalable-apps/high-throughput-data-model.png)
36+
37+
When building a high-throughput app, keep some optimization in mind.
38+
39+
* Distribute large tables on a common column that is central piece of the app,
40+
and the column that your app mostly queries. In the above example of an IOT
41+
app, `device_id` is that column, and it co-locates the events and devices
42+
tables.
43+
* The rest of the small tables can be reference tables.
44+
* As IOT apps have a time dimension, partition your distributed tables based on
45+
time. You can use native Hyperscale (Citus) time series capabilities to
46+
create and maintain partitions.
47+
* Partitioning helps efficiently filter data for queries with time filters.
48+
* Expiring old data is also fast, using the DROP vs DELETE command.
49+
* The events table in our example is partitioned by month.
50+
* Use the JSONB datatype to store semi-structured data. Device telemetry
51+
data is typically not structured, every device has its own metrics.
52+
* In our example, the events table has a `detail` column, which is JSONB.
53+
* If your IoT app requires geospatial features, you can use the PostGIS
54+
extension, which Hyperscale (Citus) supports natively.
55+
56+
## Next steps
57+
58+
We've completed the how-to for building scalable apps.
59+
60+
* You may now want to know how to [scale a server group](howto-scale-grow.md)
61+
to give your app more nodes and hardware capacity.

0 commit comments

Comments
 (0)