Sdílet prostřednictvím


Kurz: Horizontální dělení dat na pracovních uzlech ve službě Azure Cosmos DB for PostgreSQL

PLATÍ PRO: Azure Cosmos DB for PostgreSQL (využívající rozšíření databáze Citus do PostgreSQL)

V tomto kurzu se pomocí služby Azure Cosmos DB for PostgreSQL naučíte:

  • Vytváření horizontálních oddílů distribuovaných pomocí hodnot hash
  • Zobrazení umístění horizontálních oddílů tabulky
  • Identifikace nerovnoměrné distribuce
  • Vytváření omezení distribuovaných tabulek
  • Spouštění dotazů na distribuovaná data

Požadavky

Tento kurz vyžaduje spuštěný cluster se dvěma pracovními uzly. Pokud nemáte spuštěný cluster, postupujte podle kurzu vytvoření clusteru a vraťte se k tomuto clusteru .

Data distribuovaná pomocí hodnoty hash

Distribuce řádků tabulky mezi více serverů PostgreSQL je klíčovou technikou škálovatelných dotazů ve službě Azure Cosmos DB for PostgreSQL. Více uzlů může obsahovat více dat než tradiční databáze a v mnoha případech může paralelně používat pracovní procesory ke spouštění dotazů. Koncept tabulek distribuovaných pomocí hash se označuje také jako horizontální dělení na základě řádků.

V části Požadavky jsme vytvořili cluster se dvěma pracovními uzly.

koordinátor a dva pracovníci

Tabulky metadat koordinačního uzlu sledují pracovní procesy a distribuovaná data. Aktivní pracovní procesy můžeme zkontrolovat v tabulce pg_dist_node .

select nodeid, nodename from pg_dist_node where isactive;
 nodeid | nodename
--------+-----------
      1 | 10.0.0.21
      2 | 10.0.0.23

Poznámka:

Názvy uzlů ve službě Azure Cosmos DB for PostgreSQL jsou interní IP adresy ve virtuální síti a skutečné adresy, které vidíte, se mohou lišit.

Řádky, horizontální oddíly a umístění

Abychom mohli používat prostředky procesoru a úložiště pracovních uzlů, musíme distribuovat data tabulek v celém clusteru. Distribuce tabulky přiřadí každý řádek logické skupině označované jako horizontální oddíl. Vytvoříme tabulku a distribuujme ji:

-- 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 přiřadí každý řádek horizontálnímu oddílu na základě hodnoty distribučního sloupce, který jsme v našem případě určili, že má být email. Každý řádek bude v přesně jednom horizontálním oddílu a každý horizontální oddíl může obsahovat více řádků.

Tabulka users s řádky odkazujícími na horizontální oddíly

Ve výchozím nastavení create_distributed_table() činí 32 horizontálních oddílů, jak vidíme počítáním v tabulce metadat pg_dist_shard:

select logicalrelid, count(shardid)
  from pg_dist_shard
 group by logicalrelid;
 logicalrelid | count
--------------+-------
 users        |    32

Azure Cosmos DB for PostgreSQL používá pg_dist_shard tabulku k přiřazení řádků k horizontálním oddílům na základě hodnoty hash hodnoty v distribučním sloupci. Podrobnosti o hashování nejsou pro tento kurz důležité. Záleží na tom, abychom zjistili, které hodnoty se mapuje na id horizontálních oddílů:

-- 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

Mapování řádků na horizontální oddíly je čistě logické. Horizontální oddíly musí být přiřazeny konkrétním pracovním uzlům pro úložiště v tom, co Azure Cosmos DB for PostgreSQL volá umístění horizontálních oddílů.

horizontální oddíly přiřazené pracovníkům

Můžeme se podívat na umístění horizontálních oddílů v pg_dist_placement. Spojování s ostatními tabulkami metadat, které jsme viděli, ukazuje, kde každý horizontální oddíl žije.

-- 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

Nerovnoměrná distribuce dat

Cluster funguje nejefektivněji, když data umístíte rovnoměrně na pracovní uzly a když umístíte související data na stejné pracovní procesy. V této části se zaměříme na první část, jednotnost umístění.

Abychom si to ukázali, pojďme pro naši users tabulku vytvořit ukázková data:

-- 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);

Abychom viděli velikosti horizontálních oddílů, můžeme na horizontálních oddílech spouštět funkce velikostí tabulky.

-- 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

Vidíme, že horizontální oddíly mají stejnou velikost. Už jsme viděli, že umístění jsou rovnoměrně rozdělená mezi pracovníky, takže můžeme odvodit, že pracovní uzly mají zhruba stejný počet řádků.

Řádky v našem users příkladu se rovnoměrně distribuují, protože vlastnosti distribučního sloupce, email.

  1. Počet e-mailových adres byl větší nebo roven počtu horizontálních oddílů.
  2. Počet řádků na e-mailovou adresu byl podobný (v našem případě přesně jeden řádek na adresu, protože jsme deklarovali klíč e-mailu).

Jakákoli volba tabulky a distribučního sloupce, ve kterém selže některá vlastnost, skončí nerovnoměrnou velikostí dat u pracovních procesů, tj. nerovnoměrné distribuce dat.

Přidání omezení do distribuovaných dat

Použití služby Azure Cosmos DB for PostgreSQL umožňuje i nadále využívat bezpečnost relační databáze, včetně omezení databáze. Existuje však omezení. Vzhledem k povaze distribuovaných systémů azure Cosmos DB for PostgreSQL nebude mezi referenčními omezeními jedinečnosti ani referenční integritou mezi pracovními uzly.

Podívejme se na příklad tabulky users se související tabulkou.

-- 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');

Kvůli efektivitě distribuujeme books stejným způsobem jako users: e-mailovou adresou vlastníka. Distribuce podle podobných hodnot sloupců se nazývá kolokace.

Neměli jsme problém s distribucí knih s cizím klíčem pro uživatele, protože klíč byl v distribučním sloupci. Měli bychom ale potíže s vytvářením isbn klíče:

-- 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).

V distribuované tabulce je nejlepší, aby sloupce byly jedinečné modulo distribučního sloupce:

-- a weaker constraint is allowed
alter table books add constraint books_isbn unique (owner_email, isbn);

Výše uvedené omezení pouze činí jedinečné hodnoty pro jednotlivé uživatele. Další možností je vytvořit knihy jako referenční tabulku místo distribuované tabulky a vytvořit samostatnou distribuovanou tabulku asociující knihy s uživateli.

Dotazování distribuovaných tabulek

V předchozích částech jsme viděli, jak jsou řádky distribuované tabulky umístěné v horizontálních oddílech na pracovních uzlech. Většinou nepotřebujete vědět, jak nebo kde jsou data uložená v clusteru. Azure Cosmos DB for PostgreSQL má distribuovaný exekutor dotazů, který automaticky rozděluje běžné dotazy SQL. Spouští je paralelně na pracovních uzlech v blízkosti dat.

Můžeme například spustit dotaz, abychom našli průměrný věk uživatelů a zacházeli s distribuovanou users tabulkou jako s normální tabulkou v koordinátoru.

select avg(current_date - bday) as avg_days_old from users;
    avg_days_old
--------------------
 17926.348000000000

dotaz na horizontální oddíly prostřednictvím koordinátoru

Na pozadí vytvoří exekutor Azure Cosmos DB for PostgreSQL samostatný dotaz pro každý horizontální oddíl, spustí je na pracovních procesů a zkombinuje výsledek. Pokud použijete příkaz PostgreSQL EXPLAIN, uvidíte ho:

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)

Výstup ukazuje příklad plánu provádění fragmentu dotazu spuštěného na horizontálním oddílu 102040 (tabulka users_102040 pracovního procesu 10.0.0.21). Ostatní fragmenty se nezobrazují, protože jsou podobné. Vidíme, že pracovní uzel prohledá tabulky horizontálních oddílů a použije agregaci. Koordinační uzel kombinuje agregace pro konečný výsledek.

Další kroky

V tomto kurzu jsme vytvořili distribuovanou tabulku a dozvěděli jsme se o jejích horizontálních oddílech a umístěních. Viděli jsme výzvu k používání omezení jedinečnosti a cizího klíče a nakonec jsme viděli, jak distribuované dotazy fungují na vysoké úrovni.