Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.

PHP ökosüsteemis on praegu kaks konnektorit, mis töötavad Tarantool serveriga - see on ametlik PECL laiendus tarantool/tarantool-php, mis on kirjutatud C-s, ja tarantool-php/client, mis on kirjutatud PHP-s. Mina olen viimase autor.

Selles artiklis jagan tulemusi nende kahe teegi jõudluse testimisest ja näitan, kuidas minimalseid muudatusi koodis tehes saavutada 3-5% jõudluse kasvu (süntetilistel testidel!).

Mida me testime?

Testime ülalmainitud sünkroonseid konnektoreid, käivitatuna asünkroonselt, paralleelselt ja asünkroonselt-paralleelselt. 🙂 Samuti ei soovi me konnektorite koodi muuta. Praegu on saadaval mitmeid laiendusi, mis võimaldavad soovitud tulemust:

  • Swoole ― kõrge jõudlusega asünkroonne raamistik PHP-le. Seda kasutavad sellised interneti hiiglased nagu Alibaba ja Baidu. Alates versioonist 4.1.0 ilmus maagiline meetod SwooleRuntime::enableCoroutine(), mis võimaldab "ühe koodireaga muuta PHP sünkroonset võrgu teeki asünkroonseks".
  • Async ― kuni hiljuti peeti seda üsna paljulubavaks laienduseks PHP asünkroonseks tööks. Miks kuni hiljuti? Kahjuks on põhjus mulle teadmata, autor kustutas hoidla ja projekti edasine saatus on ebaselge. Peame kasutama ühte haru. Nagu Swoole, võimaldab see laiendus lihtsalt asünkroonsuse aktiveerimist, asendades tavalised TCP ja TLS voogude nende asünkroonsete versioonidega. Seda saab teha lihtsalt valiku kaudu „async.tcp = 1«.
  • Parallel ― üsna uus laiendus tuntud Joe Watkinselt, kes on selliste teekide nagu phpdbg, apcu, pthreads, pcov ja uopz autor. See laiendus pakub API-d mitme lõimega tööks PHP-s ja positsioneeritakse kui pthreadsi asendaja. Oluline piirang on see, et teek töötab ainult ZTS (Zend Thread Safe) versiooniga PHP.

Kuidas me testime?

Käivitame Tarantooli eksemplari, millel on eelregistreerimise ajakirja funktsioon välja lülitatud (wal_mode = none) ja suurendatud võrgupuhvri (readahead = 1 * 1024 * 1024). Esimene valik välistab töötegemise kettaga, teine – võimaldab lugeda rohkem päringuid operatsioonisüsteemi puhvrisse ja seeläbi minimeerida süsteemikõnnete arvu.

Andmetega töötavate benchmarkide (lisamine, kustutamine, lugemine jne) jaoks luuakse benchmarki alustamisel (taas)memtx-ruum, milles esmase indeksi väärtused genereeritakse järjestatud täisarvude generaatoriga (järjekord).
DDL ruum näeb välja järgmine:

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 tähistatud 10,000 kätetüki näidisega enne benchmarki käivitamist.

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

Kätetükkidele pääseb juurde juhuslike võtmeväärtuste kaudu.

Benchmark ise serverile bir kez yapılan bir isteği 10,000 kez (devrim) gerçekleştirir, bu da yine yinelemelerde gerçekleştirilir. İterasyonlar, 5 yineleme arasındaki zaman sapmalarının %3'lük bir hata payı içinde kalana kadar tekrar edilir. Daha sonra ortalama sonuç alınır. İterasyonlar arasında işlemcinin throttling'e gitmemesi için 1 saniyelik bir bekleme süresi bulunmaktadır. Her yinelemeden önce Lua'nın çöp toplayıcısı devre dışı bırakılır ve tamamlandıktan sonra zorla çalıştırılır. PHP süreci yalnızca benchmark için gerekli eklentilerle, çıktı tamponlaması etkin ve çöp toplayıcısı devre dışı bırakılarak başlatılır.

* Devrim, yineleme sayısı ve hata eşiği benchmark ayarlarında değiştirilebilir.

Test ortamı

Aşağıda yayımlanan sonuçlar, işletim sistemi Fedora 30 (kernel versiyonu 5.3.8-200.fc30.x86_64) olan MacBookPro (2015) üzerinde yapılmıştır. Tarantool, " ile parametreyle docker içinde çalıştırılmıştır.--network host".

Paket versiyonları:

Tarantool: 2.3.0-115-g5ba5ed37e
Docker: 19.03.3, build a872fc2f86
PHP: 7.3.11 (cli) (oluşturma: 22 Ekim 2019 08:11:04)
tarantool/client: 0.6.0
rybakit/msgpack: 0.6.1
ext-tarantool: 0.3.2 (+ 7.3 için yamanmış)*
ext-msgpack: 2.0.3
ext-async: 0.3.0-8c1da46
ext-swoole: 4.4.12
ext-parallel: 1.1.3

* Kahjuks ametlik ühendus ei toimi PHP versiooniga > 7.2. Et koondada ja käivitada laiend PHP 7.3, tuli kasutada patch.

Tulemused

Sünkroonne režiim

Tarantooli protokoll kasutab binaarformaat MessagePack sõnumite serialiseerimiseks. PECL ühenduses on serialiseerimine peidetud sügavale teeki ja selle kodeerimisprotsessi mõjutamine userland-koodist ei ole võimalik. Puhta PHP ühendus, vastupidi, võimaldab kodeerimisprotsessi kohandamist standardse kodeerija laiendamise või oma rakendamise abil. Vaikimisi on saadaval kaks kodeerijat, millest üks põhineb msgpack/msgpack-php (ametlik MessagePack PECL laiend), teine — rybakit/msgpack (puhta PHP peal).

Enne ühenduste võrdlemist mõõdame MessagePack kodeerijate jõudlust PHP ühenduse jaoks ning edasistes testides kasutame seda, mis näitab parimat tulemust:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Kuigi PHP versioon (Pure) jääb PECL laiendile kiiruselt alla, soovitaksin siiski reaalsetes projektides kasutada just rybakit/msgpack, kuna ametlikus laienduses MessagePack formaadi spetsifikatsioon on rakendatud ainult osaliselt (näiteks ei ole kasutaja andmetüüpide toetust, ilma milleta ei saa kasutada Decimalit — uut andmetüüpi, mis on esitatud Tarantoolis 2.3) ning tal on mitmeid muid probleemide (sealhulgas ühilduvusprobleeme PHP 7.4-ga). Ja üldiselt tundub projekt mahajäetuna.

Seega mõõdame ühenduste jõudlust sünkroonses režiimis:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Nagu graafikust näha, näitab PECL (Tarantool) ühendus paremat jõudlust võrreldes PHP (Client) ühendusega. See ei ole üllatav, arvestades, et viimane, pealegi, et see on kirjutatud aeglasemas keeles, teeb põhimõtteliselt rohkem tööd: iga kutsumisega luuakse uus objekt Request ja Vastus (Selecti puhul — veel ka Criteria, ja Update/Upsert puhul — Operations), eraldi üksused Ühendus, Packer ja Handler toovad samuti lisakulusid. On ilmne, et paindlikkuse eest tuleb maksta. Kuid üldiselt näitab PHP tõlgendi head jõudlust, kuigi erinevus on olemas, on see ebaoluline ja võib olla isegi väiksem, kui kasutada Preloadingut PHP 7.4-s, rääkimata JIT-ist PHP 8-s.

Liigume edasi. Tarantool 2.0 toob kaasa SQL toe. Proovime teha Select, Insert, Update ja Delete tehinguid SQL-protokolli abil ning võrreldes tulemusi noSQL (binaarsete) vastetega:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
SQL tulemused ei ole eriti muljetavaldavad (kordan, et me testime endiselt sünkroonrežiimi). Siiski ei tasu mul pahandada, kuna SQL tugi on endiselt aktiivses arenduses (kohtuväliselt on näiteks lisatud tugi prepared statements). Ja, nagu loetelu näitab, ootab SQL mootor veel mitmeid optimeerimisi. issuesAsünkroonne

Noh, vaatame nüüd, kuidas asünkroonne laiendus suudab meie eeltoodud tulemusi parandada. Asünkroonsete programmide kirjutamiseks pakub laiendus API-d korutine (coroutine) põhjal, mida me kasutame. Katse tegemise käigus selgub, et meie keskkonna optimaalne korutinide arv on 25:

„Jaotame“ 10,000 tehingut 25 korutini vahel ja vaatame, mis välja tuli:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Tehingute arv sekundis kasvas rohkem kui kolm korda

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Kahjuks ei käivitu PECL konnektor ext-async'iga. tarantool-php/client!

Aga mis SQL-iga?

Aga mis SQLiga?

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Nagu näete, on asünkroonses režiimis binaarse protokolli ja SQL vaheline erinevus jäänud veamarginaali piiresse.

Swoole

Uurime jälle optimaalset korutinate arvu, seekord juba Swoole jaoks:
Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Peame kinni 25-st. Korrame sama trikki, mis Async laiendusega – jagame 10,000 toimingut 25 korutina vahel. Lisaks sellele lisame veel ühe testi, kus jagame kogu töö kahe protsessi vahel (st iga protsess täidab 5,000 toimingut 25 korutina). Protsessid luuakse kasutades SwooleProcess.

Tulemused:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Swoole näitab ühe protsessi käivitamisel veidi madalamat tulemust võrreldes Asynciga, kuid kahe protsessi puhul muutub olukord kardinaalselt (number 2 ei ole juhuslik, minu masinal näitas just 2 protsessi parimat tulemust).

Muide, Async laienduses on samuti API protsesside tööks, kuid seal ei märganud ma mingit erinevust, kas benšmarke käivitati ühes või mitmes protsessis (ei välista, et ma kuskil eksisin).

SQL vs binaarne protokoll:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Nii nagu Asynci puhul, muudab asünkroonne režiim binaarsete ja SQL-toimingute vahekorra olematuks.

Parallel

Kuna Parallel laiendus ei käsitle korutiine, vaid vooge, saame mõõta optimaalse paralleelsete voogude arvu:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
See on mu masinas 16. Käivitame ühenduspunktide benchmarkid 16 paralleelse vooga:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Kuidas näete, on tulemus isegi parem kui asünkroonsete laienduste puhul (välja arvatud Swoole, mis töötab 2 protsessis). Pange tähele, et PECL ühenduspunkti puhul on Update ja Upsert toimingute kohal tühjus. See on seotud sellega, et need toimingud kukkusid vigade tõttu välja — ei tea, kas ext-paralleel, ext-tarantool või mõlemad on süüdi.

Nüüd võrrelge SQL-i jõudlust:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.
Kas märkate sarnasust diagrammiga, mis on genereeritud sünkroonselt käitatud ühenduspunktide jaoks?

Kõik kokku

Ja viimaseks, viime kõik tulemused üheks diagrammiks, et näha üldpilti testitud laienduste jaoks. Lisame diagrammile ainult ühe uue testi, mida me pole veel teinud — käivitame Async korutiinid paralleelselt, kasutades Parallel*. Ühendamine eelnevalt mainitud laiendustega on juba arutatud autorite poolt, kuid nõusolek ei olnud saavutatud, peame seda ise tegema.

* Swoole korutiinide käivitamine Paralleliga ei õnnestunud, tundub, et need laiendused ei ühildu.

Seega, lõplikud tulemused:

Kiirendame PHP-konnektoreid Tarantooliga Async, Swoole ja Parallel abil.

Kokkuvõtte asemel

Minu arvates on tulemused üsna head ja mul on kummaline tunne, et see pole veel piir! Kas see on teile reaalses projektis vajalik, otsustate ainult teie, võin vaid öelda, et see oli minu jaoks huvitav katse, mis võimaldas hinnata, kui palju saab „välja pigistada“ sünkroonse TCP-konnektori abil minimaalse vaevaga. Kui teil on ideid, kuidas benchmarke parandada - olen rõõmus, et kaaluda teie pulli taotluse. Kogu kood koos käivitamisjuhiste ja tulemustega on avaldatud eraldi repositoriis.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster