
NĂ« ekosistemin PHP aktualisht egzistojnĂ« dy konektorĂ« pĂ«r tĂ« punuar me serverin Tarantool â kjo Ă«shtĂ« zgjerimi zyrtar PECL , i shkruar nĂ« C, dhe , i shkruar nĂ« PHP. UnĂ« jam autori i kĂ«tij tĂ« fundit.
Në këtë artikull do të doja të ndaja rezultatet e testimit të performancës së të dy bibliotekave dhe të tregoj se si me ndryshime minimale në kod mund të arrihet një rritje prej 3-5 përqindësh (në teste sintetike!).
ĂfarĂ« do tĂ« testojmĂ«?
Do të testojmë të përmendurat më sipër konektorët sinkronë
- Swoole â njĂ« kĂ«tĂ« e asinkronĂ« e performant pĂ«r PHP. PĂ«rdoret nga gjigantĂ«t e internetit si Alibaba dhe Baidu. Me versionin 4.1.0 doli metoda magjikeSwooleRuntime::enableCoroutine()
- , e cila lejon "me një rresht kodi të transformoni bibliotekat e rrjetit sinkron të PHP në asinkrone". njënga forkat. Si Swoole, ky zgjerim lejon me një lëvizje të lehtë të kthesh asinkronitet duke zëvendësuar implementimin standard të TCP dhe TLS me versionet e tyre asinkrone. Kjo bëhet përmes opsionit "«.
- Parallel
â njĂ« zgjerim tĂ«rheqĂ«s nga i njohuri Joe Watkins, autori i biblioteka si phpdbg, apcu, pthreads, pcov, uopz. Zgjerimi ofron njĂ« API pĂ«r punĂ« me shumĂ« tela nĂ« PHP dhe pozicionohet si zĂ«vendĂ«sim pĂ«r pthreads. NjĂ« kufizim tĂ« rĂ«ndĂ«sishĂ«m tĂ« bibliotekĂ«s Ă«shtĂ« se ajo punon vetĂ«m me versionin ZTS (Zend Thread Safe) tĂ« PHP.
Si do tâi testojmĂ«?Do tĂ« nisim njĂ« instancĂ« tĂ« Tarantool-it pa activizimin e regjistrit tĂ« paraparĂ« (wal_mode = none) dhe me njĂ« buffer rrjeti tĂ« pĂ«rmirĂ«suar (readahead = 1 * 1024 * 1024
). Opcioni i parë do të përjashtojë punën me diskun, ndërsa i dyti do të lejojë leximin e më shumë kërkesave nga bufferi i sistemit operativ dhe kështu minimizimin e numrit të thirrjeve sistemore.
Për benchmark-et që punojnë me të dhëna (futje, fshirje, lexim etj.), para fillimit të benchmark-ut do të krijohet (ripërtërihet) hapësira memtx, në të cilën vlerat e indeksit primar krijohen nga një gjenerator i vlerave të renditura të numrave të plotë (sequence).
DDL e hapësirës 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}})
Nëse është e nevojshme, para fillimit të benchmark-ut, hapësira plotësohet me 10,000 këtuza të këtij lloji{id, "tuplД_"}
Qasja në këtuza bëhet përmes një vlerë të rastësishme të çelësit.
Benchmark-u përbëhet nga një kërkesë të vetme ndaj serverit, e cila ekzekutohet 10,000 herë (revolucione), të cilat, nga ana e tyre, ekzekutohen në iteracione. Iteracionet përsëriten derisa të gjitha devijimet në kohë mes 5 iteracioneve të jenë brenda tolerancës së lejuar prej 3%*. Pas kësaj rezultati mesatar merret. Ndërmjet iteracioneve është një pauzë prej 1 sekonde, për të mos lejuar që procesori të kalojë në throttling. Grumbulluesi i mbeturinave Lua është deaktivizuar para çdo iteracioni dhe aktivizohet me detyrim pas përfundimit të saj. Procesi PHP niset vetëm me zgjerimet e nevojshme për benchmark, me aktivizimin e bufferizimit të daljes dhe deaktivizimin e grumbulluesit të mbeturinave.
* Numri i revolucionave, iteracioneve dhe kufiri i tolerancës mund të ndryshohen në parametrit e benchmark-ut.
Mjedisi i testimitRezultatet e publikuara mĂ« poshtĂ« janĂ« bĂ«rĂ« nĂ« MacBookPro (2015), sistemi operativ â Fedora 30 (versioni i bĂ«rthamĂ«s 5.3.8-200.fc30.x86_64). Tarantool Ă«shtĂ« drejtuar 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) (ndërtuar: 22 Tetor 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 .
Rezultatet
Mënyra sinkrone
Protokolli i Tarantool-it pĂ«rdor formatin binar pĂ«r serializimin e mesazheve. NĂ« konektorin PECL, serializimi Ă«shtĂ« fshehur thellĂ« nĂ« brendĂ«si tĂ« bibliotekĂ«s dhe nuk Ă«shtĂ« e mundur tĂ« ndikosh nĂ« procesin e kodimit nga kodi i pĂ«rdoruesit . Konnektori nĂ« PHP tĂ« pastĂ«r, nga ana tjetĂ«r, ofron mundĂ«sinĂ« pĂ«r tĂ« personalizuar procesin e kodifikimit duke zgjeruar koduesin standard ose duke pĂ«rdorur implementimin tuaj. Nga kutia janĂ« nĂ« dispozicion dy kodues, njĂ«ri i bazuar nĂ« (zgjatja zyrtare e MessagePack PECL), tjetri â nĂ« (nĂ« PHP tĂ« pastĂ«r).
Para se të krahasojmë konnektorët, le të masim performancën e koduesve të MessagePack për konnektorin PHP dhe në testet e mëtejshme do të përdorim atë, i cili do të tregojë rezultatin më të mirë:

Megjithëse versioni PHP (Përzier) është më i ngadalshëm se zgjatja PECL, në projekte reale megjithatë do t'ju rekomandoja të përdorni , sepse në zgjatjen zyrtare të MessagePack, specifikimi i formatit është implementuar vetëm pjesërisht (për shembull, nuk ka mbështetje për lloje të dhënash të personalizuara, pa të cilat nuk mund të përdorni Decimal - lloji i ri i të dhënave, i prezantuar në Tarantool 2.3) dhe ka një sërë çështjesh të tjera (duke përfshirë probleme të kompatibilitetit me PHP 7.4). Dhe në përgjithësi, projekti duket se është braktisur.
Pra, le të masim performancën e konnektorëve në modin sinkron:

Siç duket nga grafiku, konnektori PECL (Tarantool) tregon njĂ« performancĂ« mĂ« tĂ« mirĂ« nĂ« krahasim me konnektorin nĂ« PHP (Client). Por kjo nuk Ă«shtĂ« befasuese, duke pasur parasysh se ky i fundit, pĂ«rveç se Ă«shtĂ« implementuar nĂ« njĂ« gjuhĂ« mĂ« tĂ« ngadalshme, kryen gjithashtu mĂ« shumĂ« punĂ«: nĂ« çdo thirrje krijohet njĂ« objekt i ri KĂ«rkesa dhe PĂ«rgjigje (nĂ« rastin e Select â madje edhe Kriteret, dhe nĂ« rastin e Update/Upsert â Operacioneve), entitete tĂ« veçanta Connection, Packer dhe Handler shtojnĂ« gjithashtu overhead. ĂshtĂ« e qartĂ« qĂ« pĂ«r fleksibilitetin duhet tĂ« paguash. MegjithatĂ«, nĂ« pĂ«rgjithĂ«si, interpretuese PHP tregon njĂ« performancĂ« tĂ« mirĂ«, edhe pse diferenca Ă«shtĂ« aty, por ajo Ă«shtĂ« e vogĂ«l dhe mund tĂ« bĂ«het edhe mĂ« e vogĂ«l me pĂ«rdorimin e preload nĂ« PHP 7.4, pa folur pĂ«r JIT nĂ« PHP 8.
Le të vazhdojmë. Në Tarantool 2.0 ka ardhur mbështetje për SQL. Le të provojmë të kryejmë operacione Select, Insert, Update dhe Delete duke përdorur protokollin SQL dhe të krahasojmë rezultatet me ekuivalentët noSQL (binare):

Rezultatet e SQL nuk janë shumë impresionuese (mosharoni se ende jemi duke testuar modin sinkron). Megjithatë, nuk do të shqetësohesha për këtë para kohe, mbështetja për SQL është ende në zhvillim aktiv (relativisht së fundmi, për shembull, është shtuar mbështetja për ) dhe, duke parë listën , motorin SQL e presin disa optimizime në të ardhmen.
Async
Tani le të shohim se si zgjatja Async mund të na ndihmojë për të përmirësuar rezultatet më sipër. Për të shkruar aplikacione asinkrone, zgjatja ofron një API të bazuar në korutina, dhe ne do ta përdorim atë. Duke eksperimentuar, zbulojmë se numri optimal i korutinave për mjedisin tonë është 25:

âE shpĂ«rndajmĂ«â 10,000 operacione nĂ« 25 korutina dhe shohim se çfarĂ« rezultati kemi:

Numri i operacioneve në sekondë u rrit më shumë se tri herë për !
Fatkeqësisht, konnektori PECL nuk u aktivizua me ext-async.
Por si është me SQL?

Siç e shihni, në modin asinkron diferenca midis protokollit binar dhe SQL u ul brenda kufijve të gabimit.
tĂ« drejtuar asinkron, paralel dhe asinkron-paralel. đ Gjithashtu, nuk duam tĂ« prekim kodin e vetĂ« konektorĂ«ve. Aktualisht ekzistojnĂ« disa zgjerime qĂ« lejojnĂ« arritjen e dĂ«shiruar:
Përsëri zbulojmë numrin optimal të korutinave, tani për Swoole:

Do të ndalemi në 25. Të njëjtin trik, që me zgjatjen Async, e përsërisim - shpërndajmë 10,000 operacione midis 25 korutina. Përveç kësaj, do të shtojmë një provë tjetër, në të cilën do të ndajnë të gjithë punën në 2 procese (dmth çdo proces do të kryejë 5,000 operacione në 25 korutina). Proceset do të krijohen përmes SwooleProcess.
Rezultatet:

Swole tregon një rezultat disi më të ulët në krahasim me Async kur ekzekutohet në një proces, por me 2 procese, situata ndryshon ndjeshëm (numri 2 është zgjedhur jo rastësisht, në makinën time pikërisht 2 procese treguan rezultatin më të mirë).
Për më tepër, në zgjatjen Async gjithashtu ka API për punuar me procese, megjithatë nuk kam vënë re ndonjë ndryshim nga ekzekutimi i benchmarkeve në një apo disa procese (nuk përjashtohet se diku kam bërë një gabim).
SQL vs protokolli binar:

Ashtu si me Async, diferenca midis operacioneve binar dhe SQL u zhduk në mënyrë asinkrone.
async.tcp = 1
Duke qenë se zgjatja Paralele nuk lidhet me korutina, por me procese, do të masim numrin optimal të proceseve paralele:

Ai është 16 në makinën time. Le të ekzekutojmë benchmarket e konnektorëve në 16 procese paralele:

Siç e shihni, rezultati është edhe më i mirë se me zgjatjet asinkrone (përveç Swoole të aktivizuar në 2 procese). Vini re se për konnektorin PECL, në vendin e operacioneve Update dhe Upsert, është bosh. Kjo është për shkak se këto operacione dështuan me një gabim - nuk di nëse është faj i ext-parallel, ext-tarantool apo i të dyjave.
Tani le të krahasojmë performancën e SQL:

Vini re ngjashmërinë me grafikun për konnektorët që u aktivizuan sinkronikisht?
E gjithë kjo
Në fund, le të sintetizojmë të gjitha rezultatet në një grafik, për të parë pamjen e përgjithshme të zgjatjeve që po testojmë. Do të shtojmë në grafik vetëm një test të ri, që ende nuk e kemi bërë - do të nisnim korutinat Async paralelisht duke përdorur Parallel*. Ideja e integrimit të zgjatjeve të përmendura më sipër është nga autorët, megjithatë nuk është arritur një konsensus, do të duhet ta bëjmë këtë vetë.
* Nuk arritëm të nisim korutinat Swoole me Parallel, duket se këto zgjatje janë të papajtueshme.
Prandaj, rezultatet përfundimtare:

Në vend të përfundimit
Mendimi im Ă«shtĂ« se rezultatet janĂ« mjaft tĂ« kĂ«naqshme, dhe ndjej se kjo nuk Ă«shtĂ« akoma kufiri! NĂ«se do t'ju nevojitej kjo nĂ« njĂ« projekt real, e vendosni vetĂ«m ju, unĂ« do tĂ« thosha se pĂ«r mua ky ishte njĂ« eksperiment interesant, qĂ« lejon vlerĂ«simin e asaj çfarĂ« mund tĂ« âshpĂ«rndahenâ nga njĂ« lidhje TCP sinkron me pĂ«rpjekje minimale. NĂ«se keni ide pĂ«r pĂ«rmirĂ«simin e benchmark-Ă«ve - do tĂ« pranoni me kĂ«naqĂ«si kĂ«rkesĂ«n tuaj pĂ«r bashkĂ«punim. I gjithĂ« kodi me udhĂ«zime pĂ«r nisje dhe rezultatet Ă«shtĂ« publikuar nĂ« njĂ« .
Burimi: habr.com
