Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel

In l'ecosistema PHP sò attualmente dui connettori per travaglià cù u servitore Tarantool - questu hè l'estensione PECL ufficiale tarantool/tarantool-php, scrittu in C, è tarantool-php/client, scrittu in PHP. Sò l'autore di l'ultime.

In questu articulu, mi piacerebbe sparte i risultati di e teste di rendiment di e duie biblioteche è dimustrà cumu, cù cambiamenti minimi à u codice, pudete ottene un aumentu di rendiment 3-5 (nantu à i testi sintetici!).

Chì avemu da pruvà ?

Pruvaremu quelli citati sopra sincronu connettori chì funzionanu in modu asincronu, in parallelu è in modu asincronu-parallelu. 🙂 Ùn vulemu ancu tuccà u codice di i connettori stessi. Ci sò attualmente parechje estensioni dispunibili per ottene ciò chì vulete:

  • Swoole ― un framework asincronu d'altu rendiment per PHP. Adupratu da tali giganti Internet cum'è Alibaba è Baidu. Dapoi a versione 4.1.0 un metudu magicu hè apparsu SwooleRuntime::enableCoroutine(), chì permette di "cunvertisce biblioteche di rete PHP sincrone in asincrone cù una linea di codice".
  • Async era finu à pocu tempu una estensione assai promettente per u travagliu asincronu in PHP. Perchè finu à pocu tempu? Sfurtunatamente, per una ragione scunnisciuta per mè, l'autore sguassate u repository è u futuru destinu di u prugettu ùn hè micca chjaru. Aghju da aduprà unu da i forchetti. Cum'è Swoole, sta estensione vi permette di accende facilmente i vostri pantaloni cun un colpu di u polsu per attivà l'asincronia rimpiazzendu l'implementazione standard di i flussi TCP è TLS cù e so versioni asincrone. Questu hè fattu attraversu l'opzione "async.tcp = 1".
  • Parallel ― una estensione abbastanza nova da u famosu Joe Watkins, autore di biblioteche cum'è phpdbg, apcu, pthreads, pcov, uopz. L'estensione furnisce una API per multithreading in PHP è hè posizionata cum'è un sustitutu di pthreads. Una limitazione significativa di a biblioteca hè chì funziona solu cù a versione ZTS (Zend Thread Safe) di PHP.

Cumu testemu ?

Lancemu una istanza di Tarantool cù a scrittura in anticipu disattivata (wal_mode = nimu) è un buffer di rete aumentatu (lettura = 1 * 1024 * 1024). A prima opzione eliminà u travagliu cù u discu, a seconda permetterà di leghje più richieste da u buffer di u sistema upirativu è minimizzà cusì u numeru di chjamate di u sistema.

Per i benchmarks chì travaglianu cù dati (inserzione, eliminazione, lettura, etc.), prima di inizià u benchmark, un spaziu memtx serà (ri) creatu, in quale i valori di l'indice primariu sò creati da un generatore di valori interi ordinati. (sequenza).
U spaziu DDL s'assumiglia cusì:

space = box.schema.space.create(config.space_name, {id = config.space_id, temporary = true})
space:create_index('primary', {type = 'tree', parts = {1, 'unsigned'}, sequence = true})
space:format({{name = 'id', type = 'unsigned'}, {name = 'name', type = 'string', is_nullable = false}})

In casu di necessariu, prima di eseguisce u benchmark, u spaziu hè pienu di 10,000 XNUMX tuples di a forma.

{id, "tuplе_<id>"}

Tuples sò accede cù un valore chjave aleatoriu.

U benchmark stessu hè una sola dumanda à u servitore, chì hè eseguitu 10,000 5 volte (rivuluzioni), chì, à u turnu, sò eseguiti in iterazioni. L'iterazioni sò ripetuti finu à chì tutte e deviazioni di u tempu trà 3 iterazioni sò in un errore accettabile di 1% *. Dopu questu, u risultatu mediu hè pigliatu. Ci hè una pausa di XNUMX secunna trà iterazioni per impediscenu à u processatore di throttling. U cullettivu di basura di Lua hè disattivatu prima di ogni iterazione è hè furzatu à inizià dopu a fine. U prucessu PHP hè lanciatu solu cù l'estensioni necessarii per u benchmark, cù u buffering di output attivatu è u cullettore di basura disattivatu.

* U numeru di rivoluzioni, iterazioni è u sogliu di errore pò esse cambiatu in i paràmetri di benchmark.

Ambiente di prova

I risultati publicati sottu sò stati fatti nantu à un MacBookPro (2015), sistema upirativu - Fedora 30 (versione kernel 5.3.8-200.fc30.x86_64). Tarantool hè stata lanciata in docker cù u paràmetru "--network host".

Versioni di pacchettu:

Tarantool: 2.3.0-115-g5ba5ed37e
Docker: 19.03.3, custruisce a872fc2f86
PHP: 7.3.11 (cli) (custruitu: 22 ottobre 2019 08:11:04)
tarantool/client: 0.6.0
rybakit/msgpack: 0.6.1
ext-tarantool: 0.3.2 (+ patch per 7.3) *
ext-msgpack: 2.0.3
ext-async: 0.3.0-8c1da46
ext-swoole: 4.4.12
ext-parallel: 1.1.3

* Sfortunatamente, u connettore ufficiale ùn funziona micca cù a versione PHP> 7.2. Per cumpilà è eseguisce l'estensione in PHP 7.3, aghju avutu aduprà patch.

Risultati

Modu sincronu

U protocolu Tarantool usa un furmatu binariu MessagePack per serializza i missaghji. In u connettore PECL, a serializazione hè oculata in a prufundità di a biblioteca è affetta u prucessu di codificazione da u codice userland. ùn pare micca pussibule. Un connettore PHP puru, à u cuntrariu, furnisce a capacità di persunalizà u prucessu di codificazione allargendu l'encoder standard o utilizendu a vostra propria implementazione. Ci sò dui codificatori dispunibili fora di a scatula, unu hè basatu annantu msgpack/msgpack-php (estensione ufficiale MessagePack PECL), l'altru hè attivatu rybakit/msgpack (in PHP puru).

Prima di paragunà i connettori, misuremu a prestazione di i codificatori MessagePack per u connettore PHP è in più teste useremu quellu chì mostra u megliu risultatu:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Ancu se a versione PHP (Pure) hè inferjuri à l'estensione PECL in velocità, in i prughjetti veri, avissi sempre cunsigliatu di utilizà. rybakit/msgpack, perchè in l'estensione MessagePack ufficiale, a specificazione di u formatu hè solu parzialmente implementata (per esempiu, ùn ci hè micca supportu per i tipi di dati persunalizati, senza quale ùn puderete micca aduprà Decimal - un novu tipu di dati introduttu in Tarantool 2.3) è hà un numeru di altri prublemi (cumprese i prublemi di cumpatibilità cù PHP 7.4). Eppo, in generale, u prugettu pare abbandunatu.

Allora, misuremu u rendiment di i connettori in modu sincronu:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Comu pò esse vistu da u graficu, u connettore PECL (Tarantool) mostra un rendimentu megliu cumparatu cù u connector PHP (Client). Ma questu ùn hè micca surprisante, postu chì l'ultime, in più di esse implementatu in una lingua più lenta, in realtà faci più travagliu: un novu ogettu hè creatu cù ogni chjama. Demande и rispunniu (in u casu di Select - ancu Criterium, è in u casu di Update/Upsert ― Docenti), entità separate A cunnessione, Imballatore и Manipulatori aghjunghjenu ancu sopra. Ovviamente, a flessibilità vene à un prezzu. Tuttavia, in generale, l'interprete PHP mostra un bonu rendimentu, ancu s'ellu ci hè una diferenza, hè insignificante è, forsi, serà ancu menu quandu si usa preloading in PHP 7.4, per ùn dì JIT in PHP 8.

Andemu avanti. Tarantool 2.0 hà introduttu u supportu SQL. Pruvemu di fà selezziunà, inserisce, aghjurnà è sguassà operazioni cù u protocolu SQL è paragunate i risultati cù l'equivalenti noSQL (binari):

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
I risultati SQL ùn sò micca assai impressiunanti (lasciami ricurdà chì simu sempre testendu u modu sincronu). Tuttavia, ùn aghju micca arrabbiatu annantu à questu in anticipu; u supportu SQL hè sempre in sviluppu attivu (relativamente recentemente, per esempiu, u supportu hè statu aghjuntu. dichjarazioni preparate) è, à ghjudicà da a lista imbusci, u mutore SQL hà da passà una quantità di ottimisazioni in u futuru.

Asincronu

Ebbè, avà vedemu cumu l'estensione Async pò aiutà à migliurà i risultati sopra. Per scrive prugrammi asincroni, l'estensione furnisce una API basatu in coroutines, chì avemu da aduprà. Scupremu empiricamente chì u numeru ottimali di coroutines per u nostru ambiente hè 25:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
"Sparge" 10,000 25 operazioni in XNUMX coroutines è vede ciò chì succede:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
U nùmeru di operazioni per seconda hè aumentatu da più di 3 volte per tarantool-php/client!

Sfortunatamente, u connettore PECL ùn hà micca cuminciatu cù ext-async.

E SQL?

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Comu pudete vede, in u modu asincronu a diffarenza trà u protokollu binariu è SQL hè diventatu in u marghjenu di errore.

Swoole

Di novu truvamu u numeru ottimale di coroutines, sta volta per Swoole:
Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Firmemu à 25. Ripetemu u listessu truccu cum'è cù l'estensione Async - distribute 10,000 25 operazioni trà 2 coroutines. Inoltre, aghjustemu un altru teste in quale avemu da sparte tuttu u travagliu in 5,000 dui prucessi (vale à dì, ogni prucessu hà da fà 25 XNUMX operazioni in XNUMX coroutines). I prucessi seranu creati usendu SwooleProcess.

Risultati:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Swole mostra un risultatu ligeramente più bassu cumparatu cù Async quandu eseguitu in un prucessu, ma cù 2 prucessi l'imaghjini cambia dramaticamente (u numeru 2 ùn hè statu sceltu per casu; nantu à a mo macchina, era 2 prucessi chì mostranu u megliu risultatu).

A propositu, l'estensione Async hà ancu una API per travaglià cù prucessi, ma ùn aghju micca nutatu nisuna differenza da eseguisce benchmarks in unu o più prucessi (hè pussibule chì aghju messu in un locu).

SQL vs protocolu binariu:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Cum'è cù Async, a diffarenza trà l'operazioni binari è SQL hè eliminata in modu asincronu.

Parallel

Siccomu l'estensione Parallela ùn hè micca di coroutines, ma di filamenti, misuremu u numeru ottimale di filamenti paralleli:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Hè uguali à 16 nantu à a mo macchina. Eseguiamo benchmarks di connettori su 16 fili paralleli:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Comu pudete vede, u risultatu hè ancu megliu cà cù estensioni asincrone (senza cuntà Swoole in esecuzione nantu à 2 prucessi). Nota chì per u connettore PECL, l'operazione Update è Upsert sò vacanti. Questu hè duvuta à u fattu chì sti operazioni fallenu cù un errore - ùn sò micca sapè s'ellu era a culpa di ext-parallel, ext-tarantool, o di i dui.

Avà paragunemu u rendiment SQL:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel
Avvisate a similitudine cù u graficu per i connettori chì funzionanu in modu sincronu?

Inseme

È infine, riassumemu tutti i risultati in un graficu per vede a stampa generale per l'estensioni pruvati. Aghjunghjemu solu una nova prova à u graficu, chì ùn avemu micca fattu ancu - eseguimu coroutines Async in parallelu cù Parallel *. L'idea di integrà l'estensioni sopra hè digià hè statu discutitu l'autori, ma senza cunsensu hè statu ghjuntu, vi tuccherà à fà tù stessu.

* Ùn era micca pussibule di lancià coroutines Swoole cù Parallel; pare chì queste estensioni sò incompatibili.

Dunque, i risultati finali:

Accelerazione di i connettori PHP per Tarantool utilizendu Async, Swoole è Parallel

Inveci di 'na cunchiusioni

In u mo parè, i risultati sò stati assai degni, è per una certa ragione sò sicuru chì questu ùn hè micca u limitu! Sè avete bisognu di decisu questu in un veru prughjettu solu per sè stessu, diceraghju solu chì per mè era un esperimentu interessante chì vi permette di valutà quantu pudete "squeeze" fora di un connettore TCP sincronu cù u minimu sforzu. Sì avete idee per migliurà i benchmarks, saraghju felice di cunsiderà a vostra dumanda di pull. Tuttu u codice cù struzzioni di lanciamentu è risultati hè publicatu in un separatu repository.

Source: www.habr.com

Add a comment