Självstudie: Shard-data på arbetsnoder i Azure Cosmos DB för PostgreSQL
GÄLLER FÖR: Azure Cosmos DB for PostgreSQL (drivs av Citus-databastillägget till PostgreSQL)
I den här självstudien använder du Azure Cosmos DB for PostgreSQL för att lära dig hur du:
- Skapa hash-distribuerade shards
- Se var tabellshards placeras
- Identifiera skev fördelning
- Skapa begränsningar för distribuerade tabeller
- Köra frågor på distribuerade data
Förutsättningar
Den här självstudien kräver ett kluster som körs med två arbetsnoder. Om du inte har ett kluster som körs följer du självstudien skapa kluster och går sedan tillbaka till den här.
Hash-distribuerade data
Att distribuera tabellrader över flera PostgreSQL-servrar är en viktig teknik för skalbara frågor i Azure Cosmos DB för PostgreSQL. Tillsammans kan flera noder lagra mer data än en traditionell databas och kan i många fall använda arbets-PROCESSORer parallellt för att köra frågor. Begreppet hash-distribuerade tabeller kallas även radbaserad horisontell partitionering.
I avsnittet förutsättningar skapade vi ett kluster med två arbetsnoder.
Koordinatornodens metadatatabeller spårar arbetare och distribuerade data. Vi kan kontrollera aktiva arbetare i tabellen pg_dist_node .
select nodeid, nodename from pg_dist_node where isactive;
nodeid | nodename
--------+-----------
1 | 10.0.0.21
2 | 10.0.0.23
Kommentar
Nodenames i Azure Cosmos DB for PostgreSQL är interna IP-adresser i ett virtuellt nätverk, och de faktiska adresser som du ser kan skilja sig åt.
Rader, fragment och placeringar
För att kunna använda processor- och lagringsresurserna för arbetsnoder måste vi distribuera tabelldata i hela klustret. När du distribuerar en tabell tilldelas varje rad till en logisk grupp som kallas shard . Nu ska vi skapa en tabell och distribuera den:
-- 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 tilldelar varje rad till en shard baserat på värdet för distributionskolumnen, som vi i vårt fall angav som email
. Varje rad kommer att finnas i exakt en shard och varje shard kan innehålla flera rader.
Som standard create_distributed_table()
görs 32 shards, som vi kan se genom att räkna i metadatatabellen pg_dist_shard:
select logicalrelid, count(shardid)
from pg_dist_shard
group by logicalrelid;
logicalrelid | count
--------------+-------
users | 32
Azure Cosmos DB for PostgreSQL använder pg_dist_shard
tabellen för att tilldela rader till shards, baserat på en hash av värdet i distributionskolumnen. Hashinformationen är oviktig för den här självstudien. Det viktiga är att vi kan fråga för att se vilka värden som mappar till vilka shard-ID:ar:
-- 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
Mappningen av rader till shards är helt logisk. Shards måste tilldelas till specifika arbetsnoder för lagring, i vad Azure Cosmos DB for PostgreSQL anropar horisontell placering.
Vi kan titta på shardplaceringarna i pg_dist_placement. När vi går med i de andra metadatatabellerna som vi har sett visas var varje fragment finns.
-- 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
Skjuvade data
Ett kluster körs mest effektivt när du placerar data jämnt på arbetsnoder och när du placerar relaterade data tillsammans på samma arbetare. I det här avsnittet fokuserar vi på den första delen, placeringens enhetlighet.
För att demonstrera ska vi skapa exempeldata för vår users
tabell:
-- 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);
Om du vill se fragmentstorlekar kan vi köra tabellstorleksfunktioner på fragmenten.
-- 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
Vi kan se att fragmenten är lika stora. Vi har redan sett att placeringarna är jämnt fördelade mellan arbetare, så vi kan dra slutsatsen att arbetsnoderna har ungefär lika många rader.
Raderna i vårt users
exempel distribueras jämnt eftersom egenskaperna för distributionskolumnen, email
.
- Antalet e-postadresser var större än eller lika med antalet shards.
- Antalet rader per e-postadress var liknande (i vårt fall exakt en rad per adress eftersom vi deklarerade e-post som en nyckel).
Val av tabell- och distributionskolumn där någon av egenskaperna misslyckas får ojämn datastorlek för arbetare, dvs. datasnedställning.
Lägga till begränsningar i distribuerade data
Med Hjälp av Azure Cosmos DB för PostgreSQL kan du fortsätta att njuta av säkerheten för en relationsdatabas, inklusive databasbegränsningar. Det finns dock en begränsning. På grund av de distribuerade systemens natur korsreferenser inte unika begränsningar eller referensintegritet mellan arbetsnoder i Azure Cosmos DB for PostgreSQL.
Nu ska vi överväga vårt users
tabellexempel med en relaterad tabell.
-- 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');
För effektivitets skull distribuerar books
vi på samma sätt som users
: via ägarens e-postadress. Distribution med liknande kolumnvärden kallas colocation.
Vi hade inga problem med att distribuera böcker med en sekundärnyckel till användare, eftersom nyckeln fanns i en distributionskolumn. Vi skulle dock ha problem med att göra isbn
en nyckel:
-- 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).
I en distribuerad tabell är det bästa vi kan göra kolumner unika modulo distributionskolumnen:
-- a weaker constraint is allowed
alter table books add constraint books_isbn unique (owner_email, isbn);
Ovanstående villkor gör bara isbn unikt per användare. Ett annat alternativ är att göra böcker till en referenstabell i stället för en distribuerad tabell och skapa en separat distribuerad tabell som associerar böcker med användare.
Fråga distribuerade tabeller
I föregående avsnitt såg vi hur distribuerade tabellrader placeras i shards på arbetsnoder. För det mesta behöver du inte veta hur eller var data lagras i ett kluster. Azure Cosmos DB for PostgreSQL har en distribuerad frågeexekutor som automatiskt delar upp vanliga SQL-frågor. De körs parallellt på arbetsnoder nära data.
Vi kan till exempel köra en fråga för att hitta användarnas genomsnittliga ålder och behandla den distribuerade users
tabellen som om den vore en normal tabell i koordinatorn.
select avg(current_date - bday) as avg_days_old from users;
avg_days_old
--------------------
17926.348000000000
I bakgrunden skapar Azure Cosmos DB for PostgreSQL-kören en separat fråga för varje shard, kör dem på arbetarna och kombinerar resultatet. Du kan se om du använder kommandot PostgreSQL EXPLAIN:
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)
Utdata visar ett exempel på en körningsplan för ett frågefragment som körs på shard 102040 (tabellen users_102040
på worker 10.0.0.21). De andra fragmenten visas inte eftersom de liknar varandra. Vi kan se att arbetsnoden söker igenom shardtabellerna och tillämpar aggregeringen. Koordinatornoden kombinerar aggregeringar för slutresultatet.
Nästa steg
I den här självstudien skapade vi en distribuerad tabell och lärde oss om dess shards och placeringar. Vi såg en utmaning med att använda unika och sekundärnyckelbegränsningar och såg slutligen hur distribuerade frågor fungerar på en hög nivå.
- Läs mer om tabelltyper för Azure Cosmos DB for PostgreSQL
- Få fler tips om hur du väljer en distributionskolumn
- Lär dig fördelarna med tabellsamlokalisering