Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel

PHP ekosistēmā paÅ”laik ir divi savienotāji darbam ar Tarantool serveri - tas ir oficiālais PECL paplaÅ”inājums tarantool/tarantool-php, rakstÄ«ts C un tarantool-php/klients, rakstÄ«ts PHP. Es esmu pēdējās autors.

Šajā rakstā es vēlos dalīties ar abu bibliotēku veiktspējas pārbaudes rezultātiem un parādīt, kā ar minimālām koda izmaiņām var sasniegt veiktspējas pieaugumu par 3-5 (uz sintētiskajiem testiem!).

Ko mēs pārbaudīsim?

Mēs pārbaudÄ«sim iepriekÅ” minētos sinhroni savienotāji, kas darbojas asinhroni, paralēli un asinhroni-paralēli. šŸ™‚ Mēs arÄ« nevēlamies pieskarties paÅ”u savienotāju kodiem. PaÅ”laik ir pieejami vairāki paplaÅ”inājumi, lai sasniegtu vēlamo:

  • Swoole ā€• augstas veiktspējas asinhronā sistēma PHP. Izmanto tādi interneta giganti kā Alibaba un Baidu. KopÅ” versijas 4.1.0 ir parādÄ«jusies maÄ£iska metode SwooleRuntime::enableCoroutine(), kas ļauj ā€œpārveidot sinhronās PHP tÄ«kla bibliotēkas par asinhronām ar vienu koda rindiņuā€.
  • Async vēl nesen bija ļoti daudzsoloÅ”s paplaÅ”inājums asinhronam darbam PHP. Kāpēc vēl nesen? Diemžēl man nezināma iemesla dēļ autors repozitoriju izdzēsa un projekta turpmākais liktenis ir neskaidrs. Man tas bÅ«s jāizmanto Š¾Š“Š½ŠøŠ¼ no dakŔām. Tāpat kā Swoole, arÄ« Å”is paplaÅ”inājums ļauj viegli ieslēgt bikses ar plaukstas pirkstu, lai iespējotu asinhroniju, aizstājot TCP un TLS straumju standarta ievieÅ”anu ar to asinhronajām versijām. Tas tiek darÄ«ts, izmantojot opciju "async.tcp = 1".
  • paralēle ā€• diezgan jauns paplaÅ”inājums no labi zināmā Džo Vatkinsa, tādu bibliotēku autora kā phpdbg, apcu, pthreads, pcov, uopz. PaplaÅ”inājums nodroÅ”ina API daudzpavedienu veidoÅ”anai PHP un ir novietots kā pthreads aizstājējs. BÅ«tisks bibliotēkas ierobežojums ir tas, ka tā darbojas tikai ar PHP ZTS (Zend Thread Safe) versiju.

Kā mēs pārbaudīsim?

PalaidÄ«sim Tarantool instanci ar atspējotu priekÅ”rakstÄ«Å”anas reÄ£istrÄ“Å”anu (wal_mode = nav) un palielināts tÄ«kla buferis (priekÅ”lasÄ«Å”ana = 1 * 1024 * 1024). Pirmā opcija novērsÄ«s darbu ar disku, otrā - ļaus nolasÄ«t vairāk pieprasÄ«jumu no operētājsistēmas bufera un tādējādi samazināt sistēmas zvanu skaitu.

Etaloniem, kas darbojas ar datiem (ievietoÅ”ana, dzÄ“Å”ana, lasÄ«Å”ana utt.), pirms etalona palaiÅ”anas tiks (atkārtoti) izveidota memtx telpa, kurā primārās indeksa vērtÄ«bas izveido sakārtotu veselu skaitļu vērtÄ«bu Ä£enerators. (secÄ«ba).
Kosmosa DDL izskatās Ŕādi:

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

Ja nepiecieÅ”ams, pirms etalona palaiÅ”anas vieta tiek aizpildÄ«ta ar 10,000 XNUMX veidlapas korteņiem

{id, "tuplŠµ_<id>"}

Korpusiem var piekļūt, izmantojot nejauÅ”as atslēgas vērtÄ«bu.

Pats etalons ir viens pieprasÄ«jums serverim, kas tiek izpildÄ«ts 10,000 5 reižu (apgriezienu), kas, savukārt, tiek izpildÄ«ts iterācijās. Iterācijas tiek atkārtotas, lÄ«dz visas laika novirzes starp 3 iterācijām ir pieļaujamās kļūdas robežās 1%*. Pēc tam tiek ņemts vidējais rezultāts. Starp iterācijām ir XNUMX sekundes pauze, lai novērstu procesora pārtraukÅ”anu. Lua atkritumu savācējs tiek atspējots pirms katras iterācijas, un tas ir spiests sākt pēc tā pabeigÅ”anas. PHP process tiek palaists tikai ar etalonam nepiecieÅ”amajiem paplaÅ”inājumiem, ar iespējotu izvades buferizāciju un atspējotu atkritumu savācēju.

* Apgriezienu skaitu, atkārtojumus un kļūdu slieksni var mainīt etalona iestatījumos.

Testa vide

Tālāk publicētie rezultāti tika veikti, izmantojot MacBookPro (2015), operētājsistēmu Fedora 30 (kodola versija 5.3.8-200.fc30.x86_64). Tarantool tika palaists dokerā ar parametru "--network host".

Pakotņu versijas:

Tarantool: 2.3.0-115-g5ba5ed37e
Docker: 19.03.3, būvējiet a872fc2f86
PHP: 7.3.11 (cli) (bÅ«vēts: 22. gada 2019. oktobris, 08:11:04)
tarantool/klients: 0.6.0
rybakit/msgpack: 0.6.1
ext-tarantool: 0.3.2 (+ ielāps 7.3)*
ext-msgpack: 2.0.3
ext-async: 0.3.0-8c1da46
ex-swoole: 4.4.12
ārējie paralēlie: 1.1.3

* Diemžēl oficiālais savienotājs nedarbojas ar PHP versiju> 7.2. Lai apkopotu un palaistu paplaÅ”inājumu PHP 7.3, man bija jāizmanto plāksteris.

rezultātus

Sinhronais režīms

Tarantool protokols izmanto bināro formātu MessagePack lai serializētu ziņas. PECL savienotājā serializācija ir paslēpta dziļi bibliotēkas dziļumos un ietekmē kodÄ“Å”anas procesu no lietotāja zemes koda neŔķiet iespējams. TÄ«rs PHP savienotājs, gluži pretēji, nodroÅ”ina iespēju pielāgot kodÄ“Å”anas procesu, paplaÅ”inot standarta kodētāju vai izmantojot savu ievieÅ”anu. Ir pieejami divi kodētāji, no kuriem viens ir balstÄ«ts uz msgpack/msgpack-php (oficiālais MessagePack PECL paplaÅ”inājums), otrs ir ieslēgts rybakit/msgpack (tÄ«rā PHP).

Pirms savienotāju salÄ«dzināŔanas mēs izmērÄ«sim MessagePack kodētāju veiktspēju PHP savienotājam un turpmākajos testos izmantosim to, kas uzrādÄ«s vislabāko rezultātu:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Lai gan PHP versija (Pure) ātrumā ir zemāka par PECL paplaÅ”inājumu, reālos projektos es tomēr ieteiktu to izmantot rybakit/msgpack, jo oficiālajā MessagePack paplaÅ”inājumā formāta specifikācija ir ieviesta tikai daļēji (piemēram, nav atbalsta pielāgotiem datu tipiem, bez kuriem nevarēsit izmantot Decimal - jaunu datu tipu, kas ieviests Tarantool 2.3) un tam ir citu skaits problēmas (tostarp saderÄ«bas problēmas ar PHP 7.4). Nu vispār projekts izskatās pamests.

Tātad, izmērīsim savienotāju veiktspēju sinhronajā režīmā:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Kā redzams diagrammā, PECL savienotājs (Tarantool) parāda labāku veiktspēju, salÄ«dzinot ar PHP savienotāju (klientu). Bet tas nav pārsteidzoÅ”i, ņemot vērā, ka pēdējais, papildus tam, ka tiek ieviests lēnākā valodā, faktiski veic vairāk darba: ar katru zvanu tiek izveidots jauns objekts PieprasÄ«t Šø Atbilde (Izvēles gadÄ«jumā - arÄ« Kritēriji, un Update/Upsert gadÄ«jumā ā€• DarbÄ«bas), atseviŔķas vienÄ«bas saistÄ«ba, Saiņotājs Šø Handler tie arÄ« pieskaita pieskaitāmās izmaksas. AcÄ«mredzot elastÄ«bai ir sava cena. Tomēr kopumā PHP tulks uzrāda labu sniegumu, lai gan ir atŔķirÄ«ba, tā ir niecÄ«ga un, iespējams, bÅ«s vēl mazāka, ja izmantos priekÅ”ielādÄ“Å”anu PHP 7.4, nemaz nerunājot par JIT PHP 8.

Ejam tālāk. Tarantool 2.0 pievienoja SQL atbalstu. Mēģināsim veikt atlases, ievietoÅ”anas, atjaunināŔanas un dzÄ“Å”anas darbÄ«bas, izmantojot SQL protokolu, un salÄ«dzināt rezultātus ar noSQL (binārajiem) ekvivalentiem:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
SQL rezultāti nav Ä«paÅ”i iespaidÄ«gi (atgādināŔu, ka mēs joprojām testējam sinhrono režīmu). Tomēr es par to neapvainotos pirms laika, SQL atbalsts joprojām ir aktÄ«va izstrādes stadijā (salÄ«dzinoÅ”i nesen, piemēram, tika pievienots atbalsts sagatavoti paziņojumi) un, spriežot pēc saraksta jautājumi, SQL dzinējam nākotnē tiks veiktas vairākas optimizācijas.

Asinhronizācija

Nu, tagad redzēsim, kā Async paplaÅ”inājums var mums palÄ«dzēt uzlabot iepriekÅ” minētos rezultātus. Lai rakstÄ«tu asinhronas programmas, paplaÅ”inājums nodroÅ”ina API, kuras pamatā ir korutÄ«nas, kuras mēs izmantosim. EmpÄ«riski noskaidrojam, ka optimālais korutÄ«nu skaits mÅ«su videi ir 25:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
"Izplatiet" 10,000 25 operāciju XNUMX korutīnās un skatiet, kas notiek:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Operāciju skaits sekundē palielinājās vairāk nekā 3 reizes par tarantool-php/klients!

Diemžēl PECL savienotājs nesākās ar ext-async.

Kā ar SQL?

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Kā redzat, asinhronajā režīmā atŔķirība starp bināro protokolu un SQL kļuva kļūdas robežās.

Swoole

Atkal mēs noskaidrojam optimālo korutÄ«nu skaitu, Å”oreiz Swoole:
Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Apstāsimies pie 25. Atkārtosim to paÅ”u triku kā ar Async paplaÅ”inājumu ā€“ sadaliet 10,000 25 operāciju starp 2 korutÄ«nām. Papildus pievienosim vēl vienu testu, kurā visu darbu sadalÄ«sim 5,000 divos procesos (tas ir, katrs process veiks 25 operācijas XNUMX korutÄ«nās). Procesi tiks izveidoti, izmantojot SwooleProcess.

Rezultāti:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Palaižot vienā procesā Swole uzrāda nedaudz zemāku rezultātu, salÄ«dzinot ar Async, bet ar 2 procesiem bilde krasi mainās (skaitlis 2 nav izvēlēts nejauÅ”i, manā maŔīnā tieÅ”i 2 procesi uzrādÄ«ja labāko rezultātu).

Starp citu, Async paplaÅ”inājumam ir arÄ« API darbam ar procesiem, taču tur es nepamanÄ«ju nekādu atŔķirÄ«bu no etalonu palaiÅ”anas vienā vai vairākos procesos (iespējams, ka es kaut kur sajaucu).

SQL pret bināro protokolu:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Tāpat kā ar Async, atŔķirÄ«ba starp binārajām un SQL operācijām tiek novērsta asinhronajā režīmā.

paralēle

Tā kā paralēlais paplaÅ”inājums nav saistÄ«ts ar korutÄ«nām, bet gan par pavedieniem, izmērÄ«sim optimālo paralēlo pavedienu skaitu:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Manā maŔīnā tas ir vienāds ar 16. IzpildÄ«sim savienotāja etalonus 16 paralēlos pavedienos:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Kā redzat, rezultāts ir pat labāks nekā ar asinhroniem paplaÅ”inājumiem (neskaitot Swoole, kas darbojas 2 procesos). Ņemiet vērā, ka PECL savienotājam operācijas Update un Upsert ir tukÅ”as. Tas ir saistÄ«ts ar faktu, ka Ŕīs darbÄ«bas neizdevās ar kļūdu ā€” es nezinu, vai tā bija ext-parallel, ext-tarantool vai abu vaina.

Tagad salīdzināsim SQL veiktspēju:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel
Vai ievērojat līdzību ar diagrammu savienotājiem, kas darbojas sinhroni?

Kopā

Visbeidzot, apkoposim visus rezultātus vienā diagrammā, lai redzētu pārbaudÄ«to paplaÅ”inājumu kopējo ainu. Pievienosim diagrammai tikai vienu jaunu testu, ko mēs vēl neesam izdarÄ«juÅ”i - paralēli palaist Async korutÄ«nas, izmantojot Parallel*. Ideja integrēt iepriekÅ” minētos paplaÅ”inājumus jau ir tika apspriests autori, bet vienprātÄ«ba netika panākta, tas bÅ«s jādara paÅ”am.

* Nebija iespējams palaist Swoole korutÄ«nu ar Parallel; Ŕķiet, ka Å”ie paplaÅ”inājumi nav saderÄ«gi.

Tātad, galīgie rezultāti:

Tarantool PHP savienotāju paātrināŔana, izmantojot Async, Swoole un Parallel

Tā vietā, lai noslēgtu

Manuprāt, rezultāti izrādÄ«jās diezgan cienÄ«gi, un nez kāpēc esmu pārliecināts, ka tas nav ierobežojums! NeatkarÄ«gi no tā, vai reālā projektā tas ir jāizlemj tikai un vienÄ«gi paÅ”am, es tikai teikÅ”u, ka man tas bija interesants eksperiments, kas ļauj novērtēt, cik daudz jÅ«s varat ā€œizspiestā€ no sinhronā TCP savienotāja ar minimālu piepÅ«li. Ja jums ir idejas etalonu uzlaboÅ”anai, es ar prieku izskatÄ«Å”u jÅ«su pieprasÄ«jumu. Viss kods ar palaiÅ”anas instrukcijām un rezultātiem ir publicēts atseviŔķā sadaļā krātuves.

Avots: www.habr.com

Pievieno komentāru