Jump to content

PoolCounter

From mediawiki.org
This page is a translated version of the page PoolCounter and the translation is 100% complete.

PoolCounter je služba pro správu zámků napsaná v jazyce C. PoolCounter poskytuje funkce podobné mutexům s omezenou délkou čekací fronty. Pokud se příliš mnoho serverů pokouší provést stejnou věc současně, fronta čekání je "plná" a klientská aplikace může místo toho provést záložní akci, například vrátit zastaralý záznam mezipaměti nebo zobrazit chybovou zprávu.

PoolCounter byl vytvořen pro MediaWiki, aby se zabránilo výpadkům webu v důsledku masivního plýtvání CPU po zneplatnění mezipaměti populárního článku ("Problém Michaela Jacksona"). Signalizační sémantika PoolCounteru umožňuje MediaWiki omezit počet webových serverů, které po úpravě souběžně analyzují stejnou novou revizi článku. PoolCounter se od té doby používá i k jiným účelům, například k omezení rychlosti požadavků na změnu velikosti miniatur.

Instalace

Server

apt install poolcounter.

Podívejte se na packages.debian.org a packages.ubuntu.com. Alternativně můžete server zkompilovat ze zdrojového kódu v repozitáři mediawiki/services/poolcounter, nebo můžete místo toho použít standardní Redis server.

Klient

MediaWiki používá PoolCounter prostřednictvím klienta napsaného v PHP, konfigurovaného pomocí $wgPoolCounterConf , který v současné době podporuje dva druhy backendů:

  • PoolCounter_Client – zajištěno serverem poolcounter (používaným Wikipedií).
  • PoolCounterRedis – podpořené serverem Redis.

Zdrojový kód PHP klienta se nachází v adresáři /includes/PoolCounter v jádru MediaWiki.

Pro server poolcounter existuje také experimentální klient Pythonu, který používá Thumbor.

Konfigurace

Chcete-li povolit klienta PoolCounter, povolte ho pomocí parametru $wgPoolCounterConf a poté zadejte adresu serveru pomocí parametru $wgPoolCountClientConf .

Klient MediaWiki může dynamicky specifikovat velikost poolu a časové limity čekání, které bude server PoolCounter používat. Samotný server PoolCounter nevyžaduje konfiguraci.

Architektura

Server je jednovláknový program v jazyce C založený na libeventu. Nepoužívá autoconf, má pouze makefile, který je vhodný pro běžné linuxové prostředí. Momentálně nemá kód pro démonizaci, takže je poháněn systemd.

V MediaWiki musí být klient podtřídou třídy PoolCounter a třída obsahující logiku specifickou pro aplikaci musí být podtřídou třídy PoolCounterWork. Podrobnosti viz Příručka:$wgPoolCounterConf#Použití.

Protokol

Síťový protokol je řádkový, s parametry oddělenými mezerami (mezery v parametrech jsou kódovány procentuálně). Klient otevře připojení, odešle příkaz pro získání zámku, provede práci, odešle příkaz pro uvolnění zámku a poté připojení ukončí.

Příkazy

Jsou definovány následující příkazy:

ACQ4ANY <key> <active worker limit> <total worker limit> <timeout>
Získejte zámek pro klienta, který potřebuje vykonat nějakou práci a je schopen číst položku mezipaměti zapsanou jiným procesem. Pokud je překročen limit aktivních pracovníků fondu, server pozastaví připojení a zpozdí svou odpověď na tento příkaz. Když klient, který obdržel odpověď LOCKED, dokončí svou práci a odešle příkaz RELEASE, všechny procesy čekající s příkazem ACQ4ANY budou okamžitě probuzeny odpovědí DONE a mohou si přečíst dokončenou práci z nového záznamu v mezipaměti.
ACQ4ME <key> <active worker limit> <total worker limit> <timeout>
Získejte zámek pro případy, kdy sdílení výsledků práce prostřednictvím mezipaměti není možné nebo není relevantní, například když požadavek na vykreslení článku zahrnuje nestandardní hodnotu stub threshold . Když je uvolněn zámek tohoto typu, probudí se pouze jeden čekající proces, aby se zachovala stejná populace pracovníků.
RELEASE
Uvolněte zámek, který klient naposledy získal.
STATS [FULL|UPTIME]
Tisk statistik.

Odpovědi

Možné odpovědi pro ACQ4ANY/ACQ4ME:

LOCKED
úspěšně získal zámek. Od klienta se očekává, že práci provede a poté odešle RELEASE.
DONE
odesláno k probuzení čekajícího klienta
QUEUE_FULL
je více pracovníků než <celkový limit pracovníků>
TIMEOUT
počet pracovníků je vyšší než <limit aktivních pracovníků>. Po <timeout> sekundách se neuvolnil žádný slot.
LOCK_HELD
snaha získat zámek, když je jeden již držen

Pro RELEASE:

NOT_LOCKED
klient momentálně nedrží žádné zámky
RELEASED
zámek úspěšně uvolněn

Pro libovolný příkaz:

ERROR <message>

Testování

$ echo 'STATS FULL' | nc -w1 localhost 7531 
uptime: 633 days, 15209h 42m 26s
total processing time: 85809 days 2059430h 0m 24.000000s
average processing time: 0.957994s
gained time: 1867 days 44820h 50m 24.000000s
waiting time: 390 days 9365h 18m 24.000000s
waiting time for me: 389 days 9343h 3m 28.000000s
waiting time for anyone: 22h 14m 53.898438s
waiting time for good: 520 days 12503h 48m 24.000000s
wasted timeout time: 473 days 11375h 2m 44.000000s
total_acquired: 7739031655
total_releases: 7736374042
hashtable_entries: 119
processing_workers: 119
waiting_workers: 216
connect_errors: 0
failed_sends: 1
full_queues: 10294544
lock_mismatch: 227
release_mismatch: 0
processed_count: 7739031536

Požadavek na trasování v produkčním prostředí

Rychlá kontrola provozu v produkčním prostředí

Na aplikačním serveru Mediawiki můžete provádět tyto akce:

sudo tcpdump -A 'port 7531 and tcp[tcpflags] & tcp-push != 0'

Obyčejná podpora protokolu Wireshark

Následující Lua skript je obyčejný 'preparátor' pro Wireshark, který jednoduše rozebírá datové části síťových paketů Poolcounter, takže je pak můžete přidat jako sloupec zobrazený v uživatelském rozhraní Wiresharku:

--[[
Obyčejný preparátor protokolu drátu Poolcounter.
Jednoduše vykreslí datovou část jako řetězcové pole, které lze poté povolit jako sloupec.

Copyright © 2020 Chris Danis & the Wikimedia Foundation

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
--]]

poolcounter_protocol = Proto("PoolCounter", "PoolCounter wire protocol")

pc_command_str = ProtoField.string("poolcounter.cmd")

poolcounter_protocol.fields = {pc_command_str}

function poolcounter_protocol.dissector(buffer, pinfo, tree)
    length = buffer:len()
    if length == 0 then return end
    pinfo.cols.protocol = poolcounter_protocol.name
    local subtree = tree:add(poolcounter_protocol, buffer(), "PoolCounter protocol data")
    subtree:add(pc_command_str, buffer(0,length-1))
end

local tcp_port = DissectorTable.get("tcp.port")
tcp_port:add(7531, poolcounter_protocol)

Na moderních linuxových systémech byste měli být schopni uložit toto jako ~/.local/lib/wireshark/plugins/poolcounter.lua a poté to bude automaticky fungovat jako wireshark or tshark.

Sledování provádění určitých typů požadavků

Představte si, že by vám záleželo na sledování celého konverzačního 'průběhu“' mezi PoolCounterem a jeho klienty pro určitou část klíčového prostoru – v našem příkladu použijeme enwiki:SpecialContributions:a:127.0.0.1.

Protože odpovědi serveru PoolCounter (např. LOCKED) neobsahují klíč, o kterém mluví, není to jednoduché.

Začněte se zachycením paketů z časového úseku, který vás zajímá.

Toto můžete vygenerovat na hostiteli poolcounteru (nebo na hostiteli aplikačního serveru, který používáte pro testování) např.:

sudo tcpdump tcp port 7531 -c 500000 -w poolcounter.pcap

Pak požádáme Wireshark, aby extrahoval seznam svých interních ID TCP streamů pro všechny požadavky, které odpovídají danému klíčovému prostoru:

tshark -r poolcounter.pcap -Y 'poolcounter.cmd contains "enwiki:SpecialContributions:a:127.0.0.1"' -T fields -e tcp.stream | sort | uniq > ids.txt

Jakmile budeme mít tento seznam ID, převedeme ho do filtru zobrazení Wiresharku:

FILTER=$(sed -e 's/^/tcp.stream eq /' -e :a -e 'N;s/\n/ or tcp.stream eq /;ta' ids.txt)

a poté pomocí tohoto filtru vyberte veškerý provoz protokolu PoolCounter pouze z těchto streamů v původním zachycení paketů:

tshark -r poolcounter.pcap -Y "poolcounter and ($FILTER)" -e frame.time_relative -e frame.time -e ip.src -e tcp.stream -e poolcounter.cmd -Tfields

Správce kódu

Související odkazy