Changes between Initial Version and Version 1 of Monitoring


Ignore:
Timestamp:
05/04/26 21:45:27 (3 weeks ago)
Author:
213192
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Monitoring

    v1 v1  
     1=== Мониторинг
     2
     3== Query Latency Distribution
     4
     5Просечниот execution time не ја претставува реалната состојба во системот. На пример 990 прашалници имаат време на извршување 1мс, додека 10 имаат 5000мс. Просекот е 50мс, но може да видиме дека тие 10 прашалници се outliers. Токму овие 10 спори прашалници можат да го нарушат корисничкото искуство.
     6
     7Пример за брз прашалник:
     8{{{
     9SELECT * FROM players WHERE player_id = 10;
     10}}}
     11
     12Пример за спор прашалник:
     13{{{
     14SELECT
     15    p.player_name,
     16    COUNT(t.transfer_id),
     17    AVG(t.transfer_fee),
     18    SUM(m.attendance)
     19FROM players p
     20JOIN transfers t ON p.player_id = t.player_id
     21JOIN matches m ON m.home_team_id = p.club_id
     22              OR m.away_team_id = p.club_id
     23GROUP BY p.player_name;
     24}}}
     25
     26Исто така, имаме два типа на прашалници: еден што има 10000 повици на ден со време на извршување 2мс и друг со 50 повици на ден со 5 секунди време на извршување. Вториот прашалник претставува поголем проблем за нашиот систем бидејќи корисникот не сака да чека slow response.
     27
     28== Hot Data vs Cold Data Monitoring
     29
     30Како што веќе видовме, системот располага со повеќе табели. Некои од нив се користат повеќе од останатите и може да се каже дека во реален систем 20% од податоците генерираат 80% од оптоварувањето.
     31
     32Класичен пример може да најдеме во табелата players. Од сите играчи кои се во табелата, најинтересни се познатите играчи - топ играчи. Токму затоа овие играчи ќе се најдат во повеќе прашалници од останати играчи и ќе се создаде row-level contention. Мониторинг резултат од гореспоменатиот проблем е тоа што играчот со id 10 ќе има 1200 queries/min, додека тој со id 187 ќе има 5 queries/min. Истите сценарија можат да се најдат и во други табели.
     33
     34Од друга страна, имаме и cold data која ретко се користи, нема locks и contention.
     35
     36== Пример
     37
     38Во Transfermarkt системот, „deadline day“ претставува екстремен случај на оптоварување, при што во краток временски интервал се извршуваат илјадници трансфер операции. За разлика од нормалниот режим, каде системот е претежно read-oriented, во овој период се јавува нагло зголемување на write операции и конкурентни трансакции.
     39
     40Во наредните примери ќе видиме и зашто ова е едно од најпредизивикувачките сценарија во системот.
     41
     421. Complex Transfer Transaction
     43
     44Секој трансфер не е едноставен INSERT, туку составена трансакција:
     45{{{
     46BEGIN;
     47
     48INSERT INTO transfers(player_id, from_club_id, to_club_id, transfer_fee, season)
     49VALUES (25, 3, 8, 12000000, '2025');
     50
     51UPDATE players
     52SET market_value = market_value + 1500000,
     53    club_id = 8
     54WHERE player_id = 25;
     55
     56UPDATE clubs
     57SET budget = budget - 12000000
     58WHERE club_id = 8;
     59
     60UPDATE clubs
     61SET budget = budget + 12000000
     62WHERE club_id = 3;
     63
     64COMMIT;
     65}}}
     66
     67Може да видиме дека имаме 4 write операции во 3 различни табели и сето ова е само за еден играч, додека на deadline day имаме илјадници трансфери. Исто така, системот влегува во contention режим поради тоа што сите трансакции таргетираат исти ентитети (player_id = 25, club_id = 8) и latency и queries/sec се зголемуваат драстично. Уште еден проблем со кој се соочуваме е transaction queueing, а тоа се случува бидејќи трансакцијата која се извршува зад себе остава други трансакции кои чекаат ресурси. Овој проблем е чест и во нормални услови, но на deadline day е многу посериозен.
     68
     69== Спојување на две табели во една
     70
     71Во последниот пример ќе направиме денормализација на системот, односно табелите players и player_valuations ќе ги споиме во една и ќе споредиме што е подобро.
     72
     73{{{
     74SELECT
     75p.last_name,
     76pv.market_value_in_eur,
     77pv.date
     78FROM players p
     79JOIN player_valuations pv
     80ON p.player_id = pv.player_id
     81WHERE p.player_id = 10
     82ORDER BY pv.date DESC
     83LIMIT 1;
     84}}}
     85
     86Ова query има JOIN и ORDER BY + LIMIT.
     87
     88{{{
     89CREATE TABLE players_with_value AS
     90SELECT
     91p.player_id,
     92p.last_name,
     93p.current_club_id,
     94pv.market_value_in_eur,
     95pv.date
     96FROM players p
     97JOIN player_valuations pv
     98ON p.player_id = pv.player_id;
     99}}}
     100{{{
     101SELECT last_name, market_value_in_eur
     102FROM players_with_value
     103WHERE player_id = 10
     104ORDER BY date DESC
     105LIMIT 1;
     106}}}
     107
     108Користејќи ја новокреираната табела извршивме query кој не користи JOIN и има побрз пристап. Сепак, целосна денормализација не е најдоброто решение. За најдобри резултати во нашиот систем ќе искористиме partial denormalization, односно ќе направиме нова табела со моменталната/последната вредност на играчот:
     109{{{
     110CREATE TABLE players_current_value AS
     111SELECT DISTINCT ON (player_id)
     112player_id,
     113market_value,
     114date
     115FROM player_valuations
     116ORDER BY player_id, date DESC;
     117}}}
     118
     119Предности што ги добиваме со ова се тоа што нема непотребно скенирање на целата историја доколку корисникот не ја бара, помалку write операции и помал contention.