Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel

Aktualisht, nĂ« ekosistemin PHP ekzistojnĂ« dy konektorĂ« pĂ«r punĂ« me serverin Tarantool — zgjerimi zyrtar PECL tarantool/tarantool-php, i shkruar nĂ« C, dhe tarantool-php/client, i shkruar nĂ« PHP. UnĂ« jam autori i kĂ«tij tĂ« fundit.

NĂ« kĂ«tĂ« artikull dua tĂ« ndaj rezultatet e testimit tĂ« performancĂ«s sĂ« tĂ« dyja bibliotekave dhe tĂ« tregoj se si, me ndryshime minimale nĂ« kod, mund tĂ« arrihet njĂ« rritje e performancĂ«s prej 3–5 herĂ« (nĂ« teste sintetike!).

ÇfarĂ« do tĂ« testojmĂ«?

Do tĂ« testojmĂ« konektorĂ«t e pĂ«rmendur mĂ« sipĂ«r, sinkronĂ« , tĂ« ekzekutuar nĂ« mĂ«nyrĂ« asinkrone, paralelisht dhe nĂ« mĂ«nyrĂ« asinkrone-paralele. 🙂 Gjithashtu, nuk duam tĂ« prekim kodin e vetĂ« konektorĂ«ve. Aktualisht janĂ« tĂ« disponueshme disa zgjerime qĂ« lejojnĂ« tĂ« arrihet rezultati i dĂ«shiruar:

  • Swoole — njĂ« framework asinkron me performancĂ« tĂ« lartĂ« pĂ«r PHP. PĂ«rdoret nga gjigantĂ« tĂ« internetit si Alibaba dhe Baidu. QĂ« nga versioni 4.1.0 Ă«shtĂ« shfaqur metoda magjike SwooleRuntime::enableCoroutine(), e cila lejon qĂ« “me njĂ« rresht kodi, bibliotekat sinkrone tĂ« rrjetit nĂ« PHP tĂ« shndĂ«rrohen nĂ« asinkrone”.
  • Async — deri vonĂ« ishte njĂ« zgjerim mjaft premtues pĂ«r punĂ« asinkrone nĂ« PHP. Pse deri vonĂ«? FatkeqĂ«sisht, pĂ«r njĂ« arsye qĂ« nuk e di, autori e ka fshirĂ« repository-n dhe e ardhmja e projektit mbetet e paqartĂ«. Do tĂ« duhet tĂ« pĂ«rdorim njĂ« nga fork-et. Ashtu si Swoole, edhe ky zgjerim lejon tĂ« aktivizohet lehtĂ«sisht asinkronia duke zĂ«vendĂ«suar implementimin standard tĂ« rrjedhave TCP dhe TLS me versionet e tyre asinkrone. Kjo bĂ«het pĂ«rmes opsionit “async.tcp = 1«.
  • Parallel — njĂ« zgjerim mjaft i ri nga Joe Watkins, i njohur si autor i bibliotekave phpdbg, apcu, pthreads, pcov, uopz. Zgjerimi ofron njĂ« API pĂ«r punĂ« shumĂ«fijĂ«she nĂ« PHP dhe pozicionohet si zĂ«vendĂ«sues i pthreads. Kufizimi i rĂ«ndĂ«sishĂ«m i kĂ«saj biblioteke Ă«shtĂ« se funksionon vetĂ«m me versionin ZTS (Zend Thread Safe) tĂ« PHP.

Si do ta testojmë?

Do të nisim një instancë të Tarantool me ditarin e regjistrimit paraprak të çaktivizuar (wal_mode = none) dhe me buffer rrjeti të rritur (readahead = 1 * 1024 * 1024). Opsioni i parë do të përjashtojë punën me diskun, ndërsa i dyti do të lejojë leximin e më shumë kërkesave nga buffer-i i sistemit operativ dhe kështu do të minimizojë numrin e thirrjeve sistemore.

Për benchmark-et që punojnë me të dhëna (shtim, fshirje, lexim etj.), para nisjes së benchmark-ut do të krijohet ose rikrijohet një memtx-space, ku vlerat e indeksit primar gjenerohen nga gjeneratori i vlerave të renditura të numrave të plotë (sequence).
DDL i space duket kështu:

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

Sipas nevojës, para nisjes së benchmark-ut, space mbushet me 10,000 tuple të formës

{id, "tuplД_"}

Qasja te tuple kryhet sipas një vlere të rastësishme të çelësit.

Vetë benchmark-u përfaqëson një kërkesë të vetme ndaj serverit, e cila ekzekutohet 10,000 herë (revolucione), që nga ana e tyre kryhen në iteracione. Iteracionet përsëriten derisa të gjitha devijimet kohore midis 5 iteracioneve të jenë brenda kufirit të lejuar të gabimit prej 3 %*. Pas kësaj merret rezultati mesatar. Midis iteracioneve ka një pauzë prej 1 sekonde, që procesori të mos kalojë në throttling. Garbage collector i Lua çaktivizohet para çdo iteracioni dhe niset me forcë pas përfundimit të tij. Procesi PHP niset vetëm me zgjerimet e nevojshme për benchmark-un, me output buffering të aktivizuar dhe garbage collector të çaktivizuar.

* Numri i revolucioneve, iteracioneve dhe pragu i gabimit mund të ndryshohen në cilësimet e benchmark-ut.

Mjedisi i testimit

Rezultatet e publikuara mĂ« poshtĂ« janĂ« marrĂ« nĂ« njĂ« MacBookPro (2015), me sistem operativ Fedora 30 (versioni i kernelit 5.3.8-200.fc30.x86_64). Tarantool u nis nĂ« Docker me parametrin “--network host".

Versionet e paketave:

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

* Fatkeqësisht, konektori zyrtar nuk punon me versionin PHP > 7.2. Për të kompiluar dhe nisur zgjerimin në PHP 7.3, u desh të përdorej patch-i.

Rezultatet

Modaliteti sinkron

Protokolli i Tarantool përdor formatin binar MessagePack për serializimin e mesazheve. Në konektorin PECL, serializimi është i fshehur thellë në brendësi të bibliotekës dhe të ndikosh në procesin e kodimit nga kodi userland nuk është e mundur. Ndryshe, konektori në PHP të pastër ofron mundësinë e personalizimit të procesit të enkodimit duke zgjeruar enkoderin standard ose duke përdorur implementimin tuaj. Si parazgjedhje janë të disponueshëm dy enkoderë: njëri bazohet në msgpack/msgpack-php (zgjerimi zyrtar MessagePack PECL), ndërsa tjetri në rybakit/msgpack (në PHP të pastër).

Para se të krahasojmë konektorët, le të masim performancën e enkoderëve MessagePack për konektorin PHP dhe në testet e mëtejshme do të përdorim atë që jep rezultatin më të mirë:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Edhe pse versioni PHP (Pure) Ă«shtĂ« mĂ« i ngadaltĂ« se zgjerimi PECL, nĂ« projekte reale unĂ« pĂ«rsĂ«ri do tĂ« rekomandoja pĂ«rdorimin e rybakit/msgpack, sepse nĂ« zgjerimin zyrtar MessagePack specifikimi i formatit Ă«shtĂ« implementuar vetĂ«m pjesĂ«risht (pĂ«r shembull, nuk ka mbĂ«shtetje pĂ«r tipe tĂ« personalizuara tĂ« tĂ« dhĂ«nave, pa tĂ« cilat nuk do tĂ« mund tĂ« pĂ«rdorni Decimal — tipi i ri i tĂ« dhĂ«nave i prezantuar nĂ« Tarantool 2.3) dhe ka njĂ« sĂ«rĂ« problemesh tĂ« tjera problemi (pĂ«rfshirĂ« problemet e pajtueshmĂ«risĂ« me PHP 7.4). Dhe nĂ« pĂ«rgjithĂ«si, projekti duket i braktisur.

Tani le të masim performancën e konektorëve në modalitetin sinkron:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Siç shihet nga grafiku, konektori PECL (Tarantool) tregon performancĂ« mĂ« tĂ« mirĂ« krahasuar me konektorin nĂ« PHP (Client). Por kjo nuk Ă«shtĂ« pĂ«r t’u habitur, duke pasur parasysh se i dyti, pĂ«rveçse Ă«shtĂ« implementuar nĂ« njĂ« gjuhĂ« mĂ« tĂ« ngadaltĂ«, nĂ« thelb kryen mĂ« shumĂ« punĂ«: nĂ« çdo thirrje krijohet njĂ« objekt i ri Request dhe PĂ«rgjigjja (nĂ« rastin e Select — edhe Criteria, ndĂ«rsa nĂ« rastin e Update/Upsert — Operations), entitetet e veçanta Connection, Packer dhe Handler gjithashtu shtojnĂ« overhead. ËshtĂ« e qartĂ« se fleksibiliteti ka koston e vet. MegjithatĂ«, nĂ« pĂ«rgjithĂ«si, interpreteri PHP tregon performancĂ« tĂ« mirĂ«; edhe pse ka diferencĂ«, ajo Ă«shtĂ« e vogĂ«l dhe ndoshta do tĂ« jetĂ« edhe mĂ« e vogĂ«l me pĂ«rdorimin e preloading nĂ« PHP 7.4, pa pĂ«rmendur JIT nĂ« PHP 8.

Le tĂ« vazhdojmĂ«. NĂ« Tarantool 2.0 u shtua mbĂ«shtetja pĂ«r SQL. Le tĂ« provojmĂ« tĂ« kryejmĂ« operacionet Select, Insert, Update dhe Delete duke pĂ«rdorur protokollin SQL dhe t’i krahasojmĂ« rezultatet me ekuivalentĂ«t noSQL (binarĂ«):

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Rezultatet e SQL nuk janë veçanërisht mbresëlënëse (ju kujtoj se ende po testojmë modalitetin sinkron). Megjithatë, nuk do të nxitoja të zhgënjehesha për këtë, sepse mbështetja për SQL është ende në zhvillim aktiv (për shembull, jo shumë kohë më parë u shtua mbështetja për prepared statements) dhe, duke gjykuar nga lista e issues, motori SQL më tej pret një sërë optimizimesh.

Async

Tani të shohim se si zgjerimi Async mund të na ndihmojë të përmirësojmë rezultatet e mësipërme. Për të shkruar programe asinkrone, zgjerimi ofron një API të bazuar në korutina (coroutines), dhe pikërisht atë do të përdorim. Nga testimet rezulton se numri optimal i korutinave për mjedisin tonë është 25:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
I “shpĂ«rndajmĂ«â€ 10,000 operacione nĂ« 25 korutina dhe shohim çfarĂ« rezultati morĂ«m:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Numri i operacioneve për sekondë u rrit më shumë se 3 herë për tarantool-php/client!

Për fat të keq, konektori PECL nuk u nis me ext-async.

Po me SQL çfarë ndodh?

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Siç mund ta shihni, në modalitetin asinkron diferenca midis protokollit binar dhe SQL ra brenda kufijve të devijimit statistikor.

Swoole

Përsëri po përcaktojmë numrin optimal të korutinave, këtë herë për Swoole:
Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Do tĂ« ndalemi te 25. Le tĂ« pĂ«rsĂ«risim tĂ« njĂ«jtin truk si me zgjerimin Async — do tĂ« shpĂ«rndajmĂ« 10,000 operacione mes 25 korutinave. PĂ«rveç kĂ«saj, do tĂ« shtojmĂ« edhe njĂ« test ku tĂ« gjithĂ« ngarkesĂ«n do ta ndajmĂ« nĂ« 2 procese (pra secili proces do tĂ« kryejĂ« 5,000 operacione nĂ« 25 korutina). Proceset do tĂ« krijohen me ndihmĂ«n e SwooleProcess.

Rezultatet:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Swoole tregon një rezultat pak më të ulët krahasuar me Async kur ekzekutohet në një proces, por me 2 procese pamja ndryshon rrënjësisht (numri 2 nuk është zgjedhur rastësisht: në kompjuterin tim pikërisht 2 procese dhanë rezultatin më të mirë).

Meqë ra fjala, zgjerimi Async ka gjithashtu API për punë me procese, por aty nuk vura re ndonjë ndryshim nga ekzekutimi i benchmark-eve në një apo disa procese (nuk përjashtohet që mund të kem bërë ndonjë gabim diku).

SQL kundrejt protokollit binar:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Ashtu si me Async, diferenca midis operacioneve binare dhe atyre SQL zbutet në modalitetin asinkron.

Parallel

Meqenëse zgjerimi Parallel nuk ka të bëjë me korutina, por me fije ekzekutimi, le të masim numrin optimal të fijeve paralele:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Në kompjuterin tim ai është 16. Le të nisim benchmark-et e konektorëve në 16 fije paralele:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
Siç mund ta shihni, rezultati Ă«shtĂ« madje mĂ« i mirĂ« se me zgjerimet asinkrone (me pĂ«rjashtim tĂ« Swoole tĂ« nisur nĂ« 2 procese). Vini re se pĂ«r konektorin PECL, te operacionet Update dhe Upsert nuk ka tĂ« dhĂ«na. Kjo lidhet me faktin se kĂ«to operacione dĂ«shtuan me gabim — nuk e di nĂ«se faji Ă«shtĂ« i ext-parallel, ext-tarantool apo i tĂ« dyjave.

Tani le të krahasojmë performancën e SQL:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel
E vutë re ngjashmërinë me grafikun për konektorët e nisur në mënyrë sinkrone?

Gjithçka së bashku

Dhe nĂ« fund, le t’i pĂ«rmbledhim tĂ« gjitha rezultatet nĂ« njĂ« grafik tĂ« vetĂ«m, qĂ« tĂ« shohim pamjen e pĂ«rgjithshme tĂ« zgjerimeve tĂ« testuara. NĂ« grafik do tĂ« shtojmĂ« vetĂ«m njĂ« test tĂ« ri, tĂ« cilin ende nuk e kemi bĂ«rĂ« ― do t’i nisim coroutine-t Async paralelisht me ndihmĂ«n e Parallel*. Ideja e integrimit tĂ« zgjerimeve tĂ« pĂ«rmendura mĂ« sipĂ«r Ă«shtĂ« diskutuar nga autorĂ«t, por ende nuk Ă«shtĂ« arritur konsensus, ndaj do tĂ« na duhet ta bĂ«jmĂ« vetĂ«.

* Nuk u arrit të niseshin coroutine-t Swoole me Parallel; duket se këto zgjerime nuk janë të pajtueshme.

Pra, rezultatet përfundimtare:

Accelerating PHP connectors for Tarantool with Async, Swoole, and Parallel

Në përfundim

Sipas mendimit tim, rezultatet dolĂ«n mjaft tĂ« mira, dhe pĂ«r ndonjĂ« arsye jam i bindur se kjo nuk Ă«shtĂ« ende kufiri! NĂ«se kjo ju nevojitet nĂ« njĂ« projekt real, kĂ«tĂ« mund ta vendosni vetĂ«m ju vetĂ«; unĂ« mund tĂ« them vetĂ«m se pĂ«r mua ishte njĂ« eksperiment interesant, qĂ« bĂ«ri tĂ« mundur vlerĂ«simin se sa mund tĂ« “nxirret” nga njĂ« konektor TCP sinkron me pĂ«rpjekje minimale. NĂ«se keni ide pĂ«r pĂ«rmirĂ«simin e benchmark-ve, do ta shqyrtoj me kĂ«naqĂ«si pull request-in tuaj. I gjithĂ« kodi me udhĂ«zimet e nisjes dhe rezultatet Ă«shtĂ« publikuar nĂ« njĂ« repotitĂ« e tij.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster