Táblázatos elhelyezés 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)
A közös elhelyezés azt jelenti, hogy a kapcsolódó információkat ugyanazon csomópontokon tárolja együtt. A lekérdezések gyorsak lehetnek, ha az összes szükséges adat elérhető hálózati forgalom nélkül. A kapcsolódó adatok különböző csomópontokon való áthelyezése lehetővé teszi, hogy a lekérdezések hatékonyan fussanak párhuzamosan az egyes csomópontokon.
Adatelosztó táblák adateloszlása
Az Azure Cosmos DB for PostgreSQL-ben egy sor akkor tárolódik egy szegmensben, ha a terjesztési oszlopban lévő érték kivonata a szegmens kivonattartományába esik. Az azonos kivonattartományú szegmensek mindig ugyanazon a csomóponton vannak elhelyezve. Az egyenlő eloszlási oszlopértékekkel rendelkező sorok mindig ugyanazon a csomóponton találhatók a táblák között. A kivonatelosztott táblák fogalmát soralapú horizontális skálázásnak is nevezik. Sémaalapú horizontális skálázás esetén az elosztott sémán belüli táblák mindig együtt vannak helyezve.
Gyakorlati példa a közös elhelyezésre
Vegye figyelembe a következő táblázatokat, amelyek egy több-bérlős webelemzési SaaS részét képezhetik:
CREATE TABLE event (
tenant_id int,
event_id bigint,
page_id int,
payload jsonb,
primary key (tenant_id, event_id)
);
CREATE TABLE page (
tenant_id int,
page_id int,
path text,
primary key (tenant_id, page_id)
);
Most olyan lekérdezéseket szeretnénk megválaszolni, amelyeket egy ügyféloldali irányítópult adhat ki. Egy példa lekérdezés: "Az elmúlt hét látogatásainak számát adja vissza a hatos bérlőben a "/blog" kezdetű összes oldal esetében."
Ha az adataink egyetlen PostgreSQL-kiszolgálón találhatóak, egyszerűen kifejezhetjük a lekérdezésünket az SQL által kínált relációs műveletek gazdag készletével:
SELECT page_id, count(event_id)
FROM
page
LEFT JOIN (
SELECT * FROM event
WHERE (payload->>'time')::timestamptz >= now() - interval '1 week'
) recent
USING (tenant_id, page_id)
WHERE tenant_id = 6 AND path LIKE '/blog%'
GROUP BY page_id;
Mindaddig, amíg a lekérdezés munkakészlete elfér a memóriában, egy egykiszolgálós tábla megfelelő megoldás. Tekintsük át az adatmodell és az Azure Cosmos DB for PostgreSQL skálázásának lehetőségeit.
Táblák elosztása azonosító szerint
Az egykiszolgálós lekérdezések a bérlők számának növekedésével és az egyes bérlők számára tárolt adatok növekedésével kezdenek lelassulni. A munkakészlet nem illeszkedik a memóriába, és a CPU szűk keresztmetszetté válik.
Ebben az esetben több csomóponton is skálázhatjuk az adatokat az Azure Cosmos DB for PostgreSQL használatával. A szegmensek kiválasztásakor az első és legfontosabb döntés a terjesztési oszlop. Kezdjük egy naiv választással, amely az eseménytáblához és page_id
a page
táblához használhatóevent_id
:
-- naively use event_id and page_id as distribution columns
SELECT create_distributed_table('event', 'event_id');
SELECT create_distributed_table('page', 'page_id');
Ha az adatok különböző feldolgozók között oszlanak el, nem tudunk olyan illesztéseket végrehajtani, mint egy PostgreSQL-csomóponton. Ehelyett két lekérdezést kell kiadnunk:
-- (Q1) get the relevant page_ids
SELECT page_id FROM page WHERE path LIKE '/blog%' AND tenant_id = 6;
-- (Q2) get the counts
SELECT page_id, count(*) AS count
FROM event
WHERE page_id IN (/*…page IDs from first query…*/)
AND tenant_id = 6
AND (payload->>'time')::date >= now() - interval '1 week'
GROUP BY page_id ORDER BY count DESC LIMIT 10;
Ezt követően az alkalmazásnak össze kell kapcsolnia a két lépés eredményeit.
A lekérdezések futtatásának a csomópontok között szétszórt szegmensekben lévő adatokkal kell konzultálnia.
Ebben az esetben az adatterjesztés jelentős hátrányokat okoz:
- Az egyes szegmensek lekérdezésének és több lekérdezés futtatásának többletterhelése.
- Az 1. negyedév többletterhelése, amely sok sort ad vissza az ügyfélnek.
- A 2. negyedév nagy lesz.
- A lekérdezések több lépésben történő írásához az alkalmazás módosításaira van szükség.
Az adatok eloszlanak, így a lekérdezések párhuzamosak lehetnek. Ez csak akkor előnyös, ha a lekérdezés által végzett munka mennyisége lényegesen nagyobb, mint a számos szegmens lekérdezésének többletterhelése.
Táblák elosztása bérlő szerint
Az Azure Cosmos DB for PostgreSQL-ben az azonos terjesztési oszlopértékkel rendelkező sorok garantáltan ugyanazon a csomóponton találhatók. Az újrakezdéstől kezdve létrehozhatjuk a táblákat tenant_id
terjesztési oszlopként.
-- co-locate tables by using a common distribution column
SELECT create_distributed_table('event', 'tenant_id');
SELECT create_distributed_table('page', 'tenant_id', colocate_with => 'event');
Az Azure Cosmos DB for PostgreSQL mostantól módosítás nélkül megválaszolhatja az eredeti egykiszolgálós lekérdezést (1. negyedév):
SELECT page_id, count(event_id)
FROM
page
LEFT JOIN (
SELECT * FROM event
WHERE (payload->>'time')::timestamptz >= now() - interval '1 week'
) recent
USING (tenant_id, page_id)
WHERE tenant_id = 6 AND path LIKE '/blog%'
GROUP BY page_id;
A tenant_id szűrése és csatlakoztatása miatt az Azure Cosmos DB for PostgreSQL tudja, hogy a teljes lekérdezés megválaszolható az adott bérlő adatait tartalmazó megosztott szegmensek készletével. Egyetlen PostgreSQL-csomópont egyetlen lépésben válaszolhat a lekérdezésre.
Bizonyos esetekben a lekérdezéseket és a táblasémákat úgy kell módosítani, hogy a bérlőazonosító egyedi korlátozásokban és csatlakozási feltételekben szerepeljenek. Ez a változás általában egyszerű.