Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel

PHP ökosüsteemis on praegu Tarantooli serveriga töötamiseks kaks konnektorit - see on ametlik PECL-laiendus tarantool/tarantool-php, kirjutatud C-keeles ja tarantool-php/klient, kirjutatud PHP-s. Viimase autor olen mina.

Selles artiklis tahaksin jagada mõlema teegi jõudlustestimise tulemusi ja näidata, kuidas koodi minimaalsete muudatustega saate jõudlust suurendada 3–5 (sünteetiliste testide kohta!).

Mida me testime?

Testime ülalnimetatuid sünkroonne asünkroonselt, paralleelselt ja asünkroonselt paralleelselt töötavad pistikud. 🙂 Samuti ei taha me puudutada pistikute endi koode. Praegu on soovitud saavutamiseks saadaval mitu laiendust.

  • Swoole ― suure jõudlusega asünkroonne raamistik PHP jaoks. Kasutavad sellised Interneti-hiiglased nagu Alibaba ja Baidu. Alates versioonist 4.1.0 on ilmunud maagiline meetod SwooleRuntime::enableCoroutine(), mis võimaldab teil "konverteerida sünkroonsed PHP võrguteegid ühe koodireaga asünkroonseteks".
  • Async oli kuni viimase ajani väga paljutõotav laiendus asünkroonseks tööks PHP-s. Miks alles hiljuti? Kahjuks kustutas autor mulle teadmata põhjusel hoidla ja projekti edasine saatus on ebaselge. Ma pean seda kasutama üks kahvlitest. Sarnaselt Swoole'iga võimaldab see laiendus lihtsalt randmeliigutusega püksid sisse lülitada, et võimaldada asünkroonsust, asendades TCP- ja TLS-voogude standardrakenduse nende asünkroonsete versioonidega. Seda tehakse valikuga "async.tcp = 1"
  • Parallel ― üsna uus laiendus tuntud Joe Watkinsilt, selliste teekide autorilt nagu phpdbg, apcu, pthreads, pcov, uopz. Laiendus pakub API-d PHP-s mitme lõime jaoks ja on asendatud pthreadidega. Teegi oluline piirang on see, et see töötab ainult PHP ZTS (Zend Thread Safe) versiooniga.

Kuidas me testime?

Käivitame Tarantooli eksemplari, kus ettekirjutamise logimine on keelatud (wal_mode = puudub) ja suurenenud võrgupuhver (ettelugemine = 1 * 1024 * 1024). Esimene võimalus välistab töö kettaga, teine ​​võimaldab lugeda operatsioonisüsteemi puhvrist rohkem päringuid ja minimeerida seeläbi süsteemikõnede arvu.

Andmetega töötavate võrdlusaluste jaoks (sisestamine, kustutamine, lugemine jne) luuakse enne võrdlusaluse käivitamist (taas)memtx-ruum, milles esmased indeksi väärtused luuakse järjestatud täisarvude generaatori abil. (järjestus).
Ruumi DDL näeb välja selline:

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

Vajadusel täidetakse ruum enne etaloni käivitamist 10,000 XNUMX vormi korrutiga

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

Kordadele pääseb juurde juhusliku võtmeväärtuse abil.

Etalon ise on üks päring serverile, mida täidetakse 10,000 5 korda (pööret), mis omakorda täidetakse iteratsioonidena. Iteratsioone korratakse seni, kuni kõik ajahälbed 3 iteratsiooni vahel on lubatud vea piires 1%*. Pärast seda võetakse keskmine tulemus. Iteratsioonide vahel on XNUMX-sekundiline paus, et vältida protsessori pidurdamist. Lua prügikoguja keelatakse enne iga iteratsiooni ja on sunnitud käivitama pärast selle lõppemist. PHP protsess käivitatakse ainult võrdlusuuringu jaoks vajalike laiendustega, väljundi puhverdamine on lubatud ja prügikoguja keelatud.

* Pöörete arvu, iteratsioone ja vealäve saab muuta võrdlusaluse seadetes.

Testikeskkond

Allpool avaldatud tulemused tehti MacBookPro (2015), operatsioonisüsteemiga - Fedora 30 (kerneli versioon 5.3.8-200.fc30.x86_64). Tarantool käivitati dockeris parameetriga "--network host".

Paketi versioonid:

Tarantool: 2.3.0-115-g5ba5ed37e
Docker: 19.03.3, ehitage a872fc2f86
PHP: 7.3.11 (cli) (ehitatud: 22. oktoober 2019 08:11:04)
tarantool/klient: 0.6.0
rybakit/msgpack: 0.6.1
ext-tarantool: 0.3.2 (+ plaaster 7.3 jaoks)*
ext-msgpack: 2.0.3
ext-async: 0.3.0-8c1da46
ext-swoole: 4.4.12
väline paralleel: 1.1.3

* Kahjuks ametlik pistik PHP versiooniga > 7.2 ei tööta. Laienduse PHP 7.3 kompileerimiseks ja käitamiseks pidin kasutama plaaster.

Järeldused

Sünkroonne režiim

Tarantooli protokoll kasutab binaarvormingut MessagePack sõnumite järjestamiseks. PECL-konnektoris on serialiseerimine peidetud sügavale teegi sügavustesse ja see mõjutab kodeerimisprotsessi kasutajamaa koodist ei tundu võimalik. Puhas PHP-pistik, vastupidi, annab võimaluse kohandada kodeerimisprotsessi, laiendades standardset kodeerijat või kasutades oma rakendust. Karbist väljas on saadaval kaks kodeerijat, millest üks põhineb msgpack/msgpack-php (ametlik MessagePack PECL laiendus), teine ​​on sisse lülitatud rybakit/msgpack (puhtal PHP-s).

Enne konnektorite võrdlemist mõõdame PHP-pistiku MessagePacki kodeerijate jõudlust ja edasistes testides kasutame seda, mis näitab parimat tulemust:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Kuigi PHP versioon (Pure) jääb kiiruselt alla PECL-laiendile, soovitan reaalsetes projektides siiski seda kasutada rybakit/msgpack, kuna ametlikus MessagePacki laienduses on vormingu spetsifikatsioon rakendatud ainult osaliselt (näiteks puudub kohandatud andmetüüpide tugi, ilma milleta ei saa kasutada Decimal - uut andmetüüpi, mis on kasutusele võetud versioonis Tarantool 2.3) ja sellel on teiste arv probleeme (sh ühilduvusprobleemid PHP 7.4-ga). Üldiselt tundub projekt mahajäetud.

Niisiis, mõõdame konnektorite jõudlust sünkroonrežiimis:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Nagu graafikult näha, näitab PECL-pistik (Tarantool) paremat jõudlust võrreldes PHP-pistikuga (klient). Kuid see pole üllatav, arvestades, et viimane teeb lisaks aeglasemas keeles rakendamisele ka rohkem tööd: iga kõnega luuakse uus objekt Küsi и Vastus (Vali puhul - ka Kriteeriumidja Update/Upsert puhul ― Operations), eraldi üksused Ühendus, Pakkija и handler need lisavad ka üldkulusid. Ilmselgelt on paindlikkus oma hind. Kuid üldiselt näitab PHP-tõlk head jõudlust, ehkki erinevus on, see on ebaoluline ja võib-olla on see veelgi väiksem, kui kasutate PHP 7.4 eellaadimist, rääkimata JIT-ist PHP 8-s.

Liigume edasi. Tarantool 2.0 tutvustas SQL-i tuge. Proovime SQL-protokolli kasutades sooritada toiminguid Select, Insert, Update ja Delete ning võrrelda tulemusi noSQL (binaar) ekvivalentidega:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
SQL-i tulemused pole eriti muljetavaldavad (tuletan teile meelde, et testime endiselt sünkroonrežiimi). Selle peale ma aga enne ei pahandaks, SQL tugi on veel aktiivses arenduses (suhteliselt hiljuti lisandus näiteks tugi koostatud avaldused) ja loendi järgi otsustades küsimustes, SQL-mootor läbib tulevikus mitmeid optimeerimisi.

Asünk

Vaatame nüüd, kuidas Asynci laiendus aitab meil ülaltoodud tulemusi parandada. Asünkroonsete programmide kirjutamiseks pakub laiendus korutiinidel põhinevat API-d, mida me kasutame. Empiiriliselt saame teada, et meie keskkonna jaoks on optimaalne korutiinide arv 25:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
"Levitage" 10,000 25 toimingut XNUMX korutiini vahel ja vaadake, mis juhtub:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Toimingute arv sekundis suurenes rohkem kui 3 korda tarantool-php/klient!

Kahjuks ei käivitunud PECL-pistik ext-asynciga.

Aga SQL?

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Nagu näete, jäi asünkroonrežiimis erinevus binaarprotokolli ja SQL-i vahel vea piiridesse.

Swoole

Jällegi saame teada optimaalse korutiinide arvu, seekord Swoole'i ​​jaoks:
Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Peatume 25 juures. Kordame sama trikki nagu Asynci laiendiga – jagage 10,000 25 toimingut 2 korutiini vahel. Lisaks lisame veel ühe testi, milles jagame kogu töö kaheks kaheks protsessiks (ehk iga protsess teeb 5,000 korutiiniga 25 toimingut). Protsessid luuakse kasutades SwooleProcess.

Tulemused:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Swole näitab ühe protsessiga käivitades veidi madalamat tulemust võrreldes Asynciga, kuid 2 protsessiga muutub pilt kardinaalselt (number 2 ei olnud juhuslikult valitud, minu masinal näitas parimat tulemust 2 protsessi).

Muide, Asynci laiendusel on ka API protsessidega töötamiseks, kuid seal ma ei märganud mingit erinevust võrdlusnäitajate käitamisest ühes või mitmes protsessis (võimalik, et ma läksin kuskil sassi).

SQL vs binaarprotokoll:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Nagu ka asünkroonses režiimis, elimineeritakse binaar- ja SQL-operatsioonide erinevus.

Parallel

Kuna paralleellaiend ei puuduta mitte korutiini, vaid lõime, siis mõõdame paralleelsete lõimede optimaalset arvu:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Minu masinal võrdub see 16-ga. Käitame 16 paralleelse keermega konnektori etalonid:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Nagu näete, on tulemus isegi parem kui asünkroonsete laiendustega (kui mitte arvestada Swoole'i, mis töötab kahel protsessil). Pange tähele, et PECL-pistiku puhul on toimingud Update ja Upsert tühjad. Selle põhjuseks on asjaolu, et need toimingud ebaõnnestusid veaga – ma ei tea, kas see oli ext-parallel, ext-tarantool või mõlema süü.

Võrdleme nüüd SQL-i jõudlust:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel
Kas märkate sünkroonselt töötavate pistikute sarnasust graafikuga?

Koos

Ja lõpuks võtame kõik tulemused kokku ühes graafikus, et näha testitud laienduste üldpilti. Lisame graafikule vaid ühe uue testi, mida me veel teinud pole – käivitame paralleelselt Asynci korutiinid, kasutades Parallel*. Ülaltoodud laienduste integreerimise idee on juba olemas arutati autorid, kuid konsensust ei saavutatud, peate seda ise tegema.

* Paralleliga ei olnud võimalik käivitada Swoole'i ​​korutiine, tundub, et need laiendused ei ühildu.

Niisiis, lõplikud tulemused:

Tarantooli PHP-pistikute kiirendamine, kasutades Async, Swoole ja Parallel

Selle asemel, et järeldus

Minu meelest osutusid tulemused igati vääriliseks ja millegipärast olen kindel, et see pole piir! Kas peate selle reaalses projektis ainult enda jaoks otsustama, ütlen vaid, et minu jaoks oli see huvitav katse, mis võimaldab teil hinnata, kui palju saate sünkroonsest TCP-pistikust minimaalse vaevaga välja pigistada. Kui teil on ideid võrdlusaluste parandamiseks, võtan teie tõmbetaotluse hea meelega läbi. Kogu kood koos käivitamisjuhiste ja tulemustega avaldatakse eraldi hoidlad.

Allikas: www.habr.com

Lisa kommentaar