Tutorial: Shard-Daten auf Workerknoten in Azure Cosmos DB for PostgreSQL
GILT FÜR: Azure Cosmos DB for PostgreSQL (unterstützt von der Citus-Datenbankerweiterung auf PostgreSQL)
In diesem Tutorial verwenden Sie Azure Cosmos DB for PostgreSQL, um Folgendes zu lernen:
- Erstellen von Shards mit Hashverteilung
- Anzeigen der Platzierung von Tabellenshards
- Identifizieren einer uneinheitlichen Verteilung (Datenschiefe)
- Erstellen von Einschränkungen für verteilte Tabellen
- Ausführen von Abfragen für verteilte Daten
Voraussetzungen
Für dieses Tutorial ist die Ausführung eines Clusters mit zwei Workerknoten erforderlich. Wenn Sie keinen Cluster haben, der ausgeführt wird, arbeiten Sie das Tutorial Erstellen eines Clusters durch, und kehren Sie dann zu diesem Schritt zurück.
Daten mit Hashverteilung
Das Verteilen von Tabellenzeilen über mehrere PostgreSQL-Server ist ein wichtiges Verfahren für skalierbare Abfragen in Azure Cosmos DB for PostgreSQL. Im Zusammenspiel können mehrere Knoten mehr Daten als eine herkömmliche Datenbank enthalten. In vielen Fällen können Sie Worker-CPUs zudem parallel zum Ausführen von Abfragen verwenden. Das Konzept der Tabellen mit Hashverteilung ist auch bekannt als zeilenbasiertes Sharding.
Als Voraussetzung haben Sie einen Cluster mit zwei Workerknoten erstellt.
Mit den Metadatentabellen des Koordinatorknotens werden Workerknoten und verteilte Daten nachverfolgt. In der Tabelle pg_dist_node können Sie die aktiven Workerknoten überprüfen.
select nodeid, nodename from pg_dist_node where isactive;
nodeid | nodename
--------+-----------
1 | 10.0.0.21
2 | 10.0.0.23
Hinweis
Knotennamen in Azure Cosmos DB for PostgreSQL sind interne IP-Adressen in einem virtuellen Netzwerk. Die tatsächlichen Adressen, die angezeigt werden, lauten möglicherweise anders.
Zeilen, Shards und Platzierungen
Um die CPU- und Speicherressourcen von Workerknoten verwenden zu können, müssen Sie die Tabellendaten über den Cluster verteilen. Beim Verteilen einer Tabelle wird jede Zeile einer logischen Gruppe zugeordnet, die als Shard bezeichnet wird. Sie erstellen nun eine Tabelle und verteilen sie:
-- create a table on the coordinator
create table users ( email text primary key, bday date not null );
-- distribute it into shards on workers
select create_distributed_table('users', 'email');
Azure Cosmos DB for PostgreSQL weist anhand des Werts der Verteilungsspalte (in unserem Fall auf email
festgelegt) jede Zeile einem Shard zu. Jede Zeile befindet sich in genau einem Shard, und jeder Shard kann mehrere Zeilen enthalten.
Mit dem Befehl create_distributed_table()
werden standardmäßig 32 Shards erstellt, wie aus der Metadatentabelle pg_dist_shard hervorgeht:
select logicalrelid, count(shardid)
from pg_dist_shard
group by logicalrelid;
logicalrelid | count
--------------+-------
users | 32
Azure Cosmos DB for PostgreSQL verwendet die Tabelle pg_dist_shard
zum Zuweisen von Zeilen zu Shards, und zwar anhand eines Hashs des Werts in der Verteilungsspalte. Die Details der Hashfunktion sind in diesem Tutorial nicht wichtig. Wichtig ist jedoch, dass Sie mithilfe von Abfragen anzeigen können, welche Werte welchen Shard-IDs zugeordnet sind:
-- Where would a row containing hi@test.com be stored?
-- (The value doesn't have to actually be present in users, the mapping
-- is a mathematical operation consulting pg_dist_shard.)
select get_shard_id_for_distribution_column('users', 'hi@test.com');
get_shard_id_for_distribution_column
--------------------------------------
102008
Das Zuordnen von Zeilen zu Shards ist ein rein logischer Vorgang. Shards müssen zum Speichern bestimmten Workerknoten zugewiesen werden. Dies wird in Azure Cosmos DB for PostgreSQL als Shardplatzierung bezeichnet.
In der Tabelle pg_dist_placement können Sie die Shardplatzierung erkennen. In Verbindung mit den anderen Metadatentabellen, die Sie gesehen haben, ist erkennbar, wo sich jeder Shard befindet.
-- limit the output to the first five placements
select
shard.logicalrelid as table,
placement.shardid as shard,
node.nodename as host
from
pg_dist_placement placement,
pg_dist_node node,
pg_dist_shard shard
where placement.groupid = node.groupid
and shard.shardid = placement.shardid
order by shard
limit 5;
table | shard | host
-------+--------+------------
users | 102008 | 10.0.0.21
users | 102009 | 10.0.0.23
users | 102010 | 10.0.0.21
users | 102011 | 10.0.0.23
users | 102012 | 10.0.0.21
Datenschiefe
Ein Cluster wird am effizientesten ausgeführt, wenn Sie Daten gleichmäßig auf Workerknoten verteilen und verwandte Daten auf denselben Workerknoten platzieren. In diesem Abschnitt konzentrieren wir uns auf den ersten Teil, die Gleichmäßigkeit der Platzierung.
Um dies zu veranschaulichen, erstellen Sie Beispieldaten für die Tabelle users
:
-- load sample data
insert into users
select
md5(random()::text) || '@test.com',
date_trunc('day', now() - random()*'100 years'::interval)
from generate_series(1, 1000);
Zum Anzeigen der Shardgrößen können Sie für die Shards Funktionen zur Ermittlung der Tabellengröße ausführen.
-- sizes of the first five shards
select *
from
run_command_on_shards('users', $cmd$
select pg_size_pretty(pg_table_size('%1$s'));
$cmd$)
order by shardid
limit 5;
shardid | success | result
---------+---------+--------
102008 | t | 16 kB
102009 | t | 16 kB
102010 | t | 16 kB
102011 | t | 16 kB
102012 | t | 16 kB
Sie sehen, dass die Shards die gleiche Größe haben. Sie haben bereits festgestellt, dass die Platzierungen gleichmäßig auf die Workerknoten verteilt sind. Davon können Sie ableiten, dass die Workerknoten ungefähr gleich viele Zeilen enthalten.
Die Zeilen in der Beispieltabelle users
sind aufgrund der Eigenschaften der Verteilungsspalte (email
) gleichmäßig verteilt.
- Die Anzahl von E-Mail-Adressen war größer oder gleich der Anzahl von Shards.
- Die Anzahl von Zeilen pro E-Mail-Adresse war vergleichbar (in diesem Fall genau eine Zeile pro Adresse, da die E-Mail-Adresse als Schlüssel deklariert wurde).
Jede Auswahl von Tabelle und Verteilungsspalte, die bei einer Eigenschaft Fehler verursachen, hat eine uneinheitliche Datengröße auf den Workerknoten zur Folge, die sogenannte Datenschiefe.
Hinzufügen von Einschränkungen zu verteilten Daten
Bei Verwendung von Azure Cosmos DB for PostgreSQL profitieren Sie weiterhin von der Sicherheit einer relationalen Datenbank, einschließlich Datenbankeinschränkungen. Es gibt jedoch eine Beschränkung. Aufgrund des Aufbaus verteilter Systeme erstellt Azure Cosmos DB for PostgreSQL keine Querverweise für Eindeutigkeitseinschränkungen oder referentielle Integrität zwischen Workerknoten.
Betrachten Sie die Beispieltabelle users
zusammen mit einer verwandten Tabelle.
-- books that users own
create table books (
owner_email text references users (email),
isbn text not null,
title text not null
);
-- distribute it
select create_distributed_table('books', 'owner_email');
Aus Effizienzgründen verteilen Sie die Tabelle books
auf die gleiche Weise wie die Tabelle users
: anhand der E-Mail-Adresse des Besitzers. Die Verteilung anhand ähnlicher Spaltenwerte wird als Tabellenzusammenstellung oder auch Colocation bezeichnet.
Es gab kein Problem beim Verteilen der Tabelle „Books“ mit einem Fremdschlüssel an die Tabelle „Users“, da sich der Schlüssel in einer Verteilungsspalte befand. Es gäbe jedoch Probleme, wenn Sie isbn
als Schlüssel verwenden würden:
-- will not work
alter table books add constraint books_isbn unique (isbn);
ERROR: cannot create constraint on "books"
DETAIL: Distributed relations cannot have UNIQUE, EXCLUDE, or
PRIMARY KEY constraints that do not include the partition column
(with an equality operator if EXCLUDE).
In einer verteilten Tabelle ist es am besten, Spalten zum eindeutigen Modulo der Verteilungsspalte zu machen:
-- a weaker constraint is allowed
alter table books add constraint books_isbn unique (owner_email, isbn);
Aufgrund der oben genannten Beschränkung ist nur „isbn“ eindeutig pro Benutzer. Eine andere Möglichkeit besteht darin, „books“ als Referenztabelle und nicht als verteilte Tabelle zu definieren und eine separate verteilte Tabelle zu erstellen, die „books“ mit „users“ assoziiert.
Abfragen von verteilten Tabellen
In den vorherigen Abschnitten wurde erläutert, wie verteilte Tabellenzeilen in Shards auf Workerknoten platziert werden. In den meisten Fällen brauchen Sie nicht zu wissen, wie oder wo die Daten in einem Cluster gespeichert werden. Azure Cosmos DB for PostgreSQL verfügt über ein Ausführungsmodul für verteilte Abfragen, das reguläre SQL-Abfragen automatisch aufteilt. Die Abfragen werden parallel auf den Workerknoten in Datennähe ausgeführt.
Sie können beispielsweise eine Abfrage ausführen, um das Durchschnittsalter der Benutzer zu ermitteln. Dabei wird die verteilte Tabelle users
auf dem Koordinatorknoten wie eine normale Tabelle behandelt.
select avg(current_date - bday) as avg_days_old from users;
avg_days_old
--------------------
17926.348000000000
Im Hintergrund erstellt das Azure Cosmos DB for PostgreSQL-Ausführungsmodul eine separate Abfrage für jeden Shard, führt sie auf den Workerknoten aus und kombiniert die Ergebnisse. Diesen Vorgang können Sie mit dem PostgreSQL-Befehl „EXPLAIN“ anzeigen:
explain select avg(current_date - bday) from users;
QUERY PLAN
----------------------------------------------------------------------------------
Aggregate (cost=500.00..500.02 rows=1 width=32)
-> Custom Scan (Citus Adaptive) (cost=0.00..0.00 rows=100000 width=16)
Task Count: 32
Tasks Shown: One of 32
-> Task
Node: host=10.0.0.21 port=5432 dbname=citus
-> Aggregate (cost=41.75..41.76 rows=1 width=16)
-> Seq Scan on users_102040 users (cost=0.00..22.70 rows=1270 width=4)
Die Ausgabe enthält ein Beispiel für einen Ausführungsplan für ein Abfragefragment, das auf Shard 102040 ausgeführt wird (Tabelle users_102040
auf Worker 10.0.0.21). Die anderen Fragmente werden nicht angezeigt, da sie ähnlich sind. Sie sehen, dass der Workerknoten die Shardtabellen scannt und die Gesamtsumme anwendet. Der Koordinatorknoten kombiniert die Gesamtsummen und ermittelt so das Endergebnis.
Nächste Schritte
In diesem Tutorial haben Sie eine verteilte Tabelle erstellt und Informationen zu Shards und Platzierungen erhalten. Sie haben die Herausforderung bei der Verwendung von Beschränkungen im Zusammenhang mit Eindeutigkeit und Fremdschlüsseln kennengelernt und schließlich erfahren, wie verteilte Abfragen auf hoher Ebene funktionieren.
- Erfahren sie mehr über Tabellentypen von Azure Cosmos DB for PostgreSQL.
- Weitere Tipps finden Sie unter Auswählen einer Verteilungsspalte.
- Informieren Sie sich über die Vorteile der Tabellenzusammenstellung (Colocation).