Oktatóanyag: Szegmensadatok feldolgozó csomópontokon az Azure Cosmos DB for PostgreSQL-ben
A KÖVETKEZŐKRE VONATKOZIK: Azure Cosmos DB for PostgreSQL (a Citus adatbázisbővítménye a PostgreSQL-re)
Ebben az oktatóanyagban az Azure Cosmos DB for PostgreSQL használatával megtudhatja, hogyan:
- Kivonatelosztott szegmensek létrehozása
- A táblaszegélyek helyének megtekintése
- Ferde eloszlás azonosítása
- Korlátozások létrehozása elosztott táblákon
- Lekérdezések futtatása elosztott adatokon
Előfeltételek
Ez az oktatóanyag egy futó fürtöt igényel két feldolgozó csomóponttal. Ha nincs futó fürtje, kövesse a fürt létrehozása oktatóanyagot, majd térjen vissza ehhez.
Kivonatolt adatok
A táblázatsorok több PostgreSQL-kiszolgálón való elosztása kulcsfontosságú módszer a méretezhető lekérdezésekhez az Azure Cosmos DB for PostgreSQL-ben. Egyszerre több csomópont is több adatot tárolhat, mint egy hagyományos adatbázis, és sok esetben párhuzamosan használhat feldolgozó PROCESSZORokat a lekérdezések végrehajtásához. A kivonatelosztott táblák fogalmát soralapú horizontális skálázásnak is nevezik.
Az előfeltételek szakaszban létrehoztunk egy fürtöt két feldolgozó csomóponttal.
A koordinátor csomópont metaadattáblái nyomon követik a feldolgozókat és az elosztott adatokat. A pg_dist_node táblában ellenőrizheti az aktív dolgozókat.
select nodeid, nodename from pg_dist_node where isactive;
nodeid | nodename
--------+-----------
1 | 10.0.0.21
2 | 10.0.0.23
Feljegyzés
Az Azure Cosmos DB for PostgreSQL csomópontnevei egy virtuális hálózat belső IP-címei, és a tényleges címek eltérhetnek.
Sorok, szegmensek és elhelyezések
A feldolgozó csomópontok processzor- és tárolási erőforrásainak használatához a táblaadatokat a fürtben kell elosztanunk. A táblák elosztása minden sort hozzárendel egy szegmens nevű logikai csoporthoz. Hozzunk létre egy táblát, és terjesszük el:
-- 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');
Az Azure Cosmos DB for PostgreSQL minden sort hozzárendel egy szegmenshez a terjesztési oszlop értéke alapján, amely esetünkben a következőnek van email
megadva. Minden sor pontosan egy szegmensben lesz, és minden szegmens több sort is tartalmazhat.
Alapértelmezés szerint create_distributed_table()
32 szegmenst hoz létre, amint azt a metaadattáblában pg_dist_shard:
select logicalrelid, count(shardid)
from pg_dist_shard
group by logicalrelid;
logicalrelid | count
--------------+-------
users | 32
Az Azure Cosmos DB for PostgreSQL a táblát használja a pg_dist_shard
sorok szegmensekhez való hozzárendelésére a terjesztési oszlopban lévő érték kivonata alapján. Az oktatóanyag kivonatolási részletei nem lényegesek. Az a fontos, hogy lekérdezhetjük, hogy mely értékek feleljenek meg a szegmensazonosítóknak:
-- 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
A sorok szegmensekre való leképezése tisztán logikus. A szegmenseket adott feldolgozó csomópontokhoz kell hozzárendelni a tároláshoz, az Azure Cosmos DB for PostgreSQL által a szegmensek elhelyezését hívva.
A szegmenselhelyezéseket a pg_dist_placement tekinthetjük meg. A többi metaadattáblával való összekapcsolás azt mutatja, hogy hol találhatók az egyes szegmensek.
-- 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
Egyenetlen adateloszlás
A fürt akkor fut a leghatékonyabban, ha egyenletesen helyezi el az adatokat a feldolgozó csomópontokon, és amikor a kapcsolódó adatokat ugyanazon a feldolgozón helyezi el. Ebben a szakaszban az első részre összpontosítunk, az elhelyezés egységességére.
A szemléltetéshez hozzunk létre mintaadatokat a táblánkhoz 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);
A szegmensméretek megtekintéséhez táblaméretfüggvényeket futtathatunk a szegmenseken.
-- 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
Láthatjuk, hogy a szegmensek egyenlő méretűek. Már láttuk, hogy az elhelyezések egyenletesen oszlanak el a dolgozók között, így arra következtethetünk, hogy a feldolgozó csomópontok nagyjából egyenlő számú sort tartanak.
A példában szereplő users
sorok egyenletesen oszlanak el, mert a terjesztési oszlop tulajdonságai. email
- Az e-mail-címek száma nagyobb vagy egyenlő volt a szegmensek számával.
- Az e-mail-címenkénti sorok száma hasonló volt (esetünkben címenként pontosan egy sor volt, mert kulcsként deklaráltuk az e-maileket).
Minden olyan tábla- és terjesztési oszlop, ahol bármelyik tulajdonság meghibásodik, egyenetlen adatméretet fog okozni a feldolgozókon, vagyis az adateltérésen.
Korlátozások hozzáadása elosztott adatokhoz
Az Azure Cosmos DB for PostgreSQL használatával továbbra is élvezheti a relációs adatbázisok biztonságát, beleértve az adatbázis-korlátozásokat is. Van azonban egy korlátozás. Az elosztott rendszerek természetéből adódóan az Azure Cosmos DB for PostgreSQL nem hivatkozik kereszthivatkozásokra az egyediségi korlátozásokra vagy a feldolgozó csomópontok közötti hivatkozási integritásra.
Tekintsük át users
a táblázat példáját egy kapcsolódó táblával.
-- 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');
A hatékonyság érdekében ugyanúgy terjesztjük books
a következőt, mint users
a tulajdonos e-mail-címe alapján. A hasonló oszlopértékek szerinti elosztást kolocationnak nevezzük.
Nem volt probléma a könyvek külföldi kulccsal való terjesztésével a felhasználók számára, mert a kulcs egy terjesztési oszlopban volt. Probléma merülne fel azonban a kulcsok létrehozásakor isbn
:
-- 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).
Az elosztott táblákban a legjobb, ha az oszlopokat egyedi modulová tesszük a terjesztési oszlopban:
-- a weaker constraint is allowed
alter table books add constraint books_isbn unique (owner_email, isbn);
A fenti korlátozás csupán egyedivé teszi az isbn felhasználónkénti számát. Egy másik lehetőség az, hogy a könyveket nem elosztott táblának, hanem referenciatáblának készíti, és külön elosztott táblát hoz létre, amely a felhasználókhoz társítja a könyveket.
Elosztott táblák lekérdezése
Az előző szakaszokban láthattuk, hogyan vannak elosztva az elosztott táblasorok szegmensekben a feldolgozó csomópontokon. A legtöbb esetben nem kell tudnia, hogyan és hol tárolják az adatokat egy fürtben. Az Azure Cosmos DB for PostgreSQL egy elosztott lekérdezés-végrehajtóval rendelkezik, amely automatikusan felosztja a rendszeres SQL-lekérdezéseket. Párhuzamosan futtatja őket az adatokhoz közeli feldolgozó csomópontokon.
Futtathatunk például egy lekérdezést, amely megkeresi a felhasználók átlagos életkorát, és úgy kezeli az elosztott táblát users
, mintha az egy normál táblázat lenne a koordinátoron.
select avg(current_date - bday) as avg_days_old from users;
avg_days_old
--------------------
17926.348000000000
A háttérben az Azure Cosmos DB for PostgreSQL-végrehajtó külön lekérdezést hoz létre az egyes szegmensekhez, futtatja őket a feldolgozókon, és egyesíti az eredményt. A PostgreSQL EXPLAIN parancs használata esetén a következő látható:
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)
A kimenet egy 102040 szegmensen futó lekérdezéstöredék végrehajtási tervét mutatja be (a 10.0.0.21 feldolgozó táblájausers_102040
). A többi töredék nem jelenik meg, mert hasonlóak. Láthatjuk, hogy a feldolgozó csomópont megvizsgálja a szegmenstáblákat, és alkalmazza az összesítést. A koordinátor csomópont összesíti a végeredmény összesítéseit.
Következő lépések
Ebben az oktatóanyagban létrehoztunk egy elosztott táblát, és megismerkedtünk a szegmenseivel és az elhelyezéseivel. Az egyediség és az idegenkulcs-korlátozások használatának kihívását láttuk, és végül láttuk, hogyan működnek az elosztott lekérdezések magas szinten.
- További információ az Azure Cosmos DB for PostgreSQL-táblatípusokról
- További tippek a terjesztési oszlop kiválasztásához
- A táblázatos elhelyezés előnyeinek megismerése