Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету

Қазіргі уақытта PHP экожүйесінде Tarantool серверімен жұмыс істеуге арналған екі қосқыш бар - бұл ресми PECL кеңейтімі. tarantool/tarantool-php, C тілінде жазылған және tarantool-php/клиент, PHP тілінде жазылған. Мен соңғысының авторымын.

Бұл мақалада мен екі кітапхананың өнімділігін сынау нәтижелерімен бөліскім келеді және кодқа ең аз өзгертулермен өнімділікті 3-5 арттыруға қалай қол жеткізуге болатынын көрсеткім келеді (синтетикалық сынақтар бойынша!).

Біз нені сынаймыз?

Біз жоғарыда аталғандарды сынаймыз синхронды асинхронды, параллель және асинхронды-параллель жұмыс істейтін қосқыштар. 🙂 Біз сондай-ақ қосқыштардың кодына қол тигізгіміз келмейді. Қазіргі уақытта қалағаныңызға қол жеткізу үшін бірнеше кеңейтімдер бар:

  • Swoole ― РНР үшін жоғары өнімді асинхронды фреймворк. Alibaba және Baidu сияқты интернет алпауыттары пайдаланады. 4.1.0 нұсқасынан бастап сиқырлы әдіс пайда болды SwooleRuntime::enableCoroutine(), бұл сізге «синхронды PHP желілік кітапханаларын кодтың бір жолымен асинхрондыларға түрлендіруге» мүмкіндік береді.
  • Async соңғы уақытқа дейін PHP-де асинхронды жұмыс үшін өте перспективалы кеңейтім болды. Неліктен соңғы уақытқа дейін? Өкінішке орай, маған белгісіз себептермен автор репозиторийді жойды және жобаның болашақ тағдыры түсініксіз. Мен оны пайдалануым керек біреуі шанышқылардан. Swoole сияқты, бұл кеңейтім TCP және TLS ағындарының стандартты орындалуын олардың асинхронды нұсқаларымен алмастыру арқылы асинхронияны қосу үшін білек қимылымен шалбарыңызды оңай қосуға мүмкіндік береді. Бұл « опциясы арқылы жүзеге асырыладыasync.tcp = 1«.
  • Параллель ― phpdbg, apcu, pthreads, pcov, uopz сияқты кітапханалардың авторы атақты Джо Уоткинстің жаңа кеңейтімі. Кеңейтім PHP-де көп ағынды жүргізу үшін API ұсынады және pthreads үшін ауыстыру ретінде орналастырылған. Кітапхананың айтарлықтай шектеуі ол тек PHP ZTS (Zend Thread Safe) нұсқасымен жұмыс істейді.

Біз қалай сынаймыз?

Алдын ала жазу журналы өшірілген Tarantool данасын іске қосайық (wal_mode = жоқ) және ұлғайтылған желі буфері (оқу алды = 1 * 1024 * 1024). Бірінші нұсқа дискімен жұмысты болдырмайды, екіншісі операциялық жүйе буферінен көбірек сұрауларды оқуға мүмкіндік береді және осылайша жүйелік қоңыраулардың санын азайтады.

Деректермен жұмыс істейтін эталондар үшін (енгізу, жою, оқу және т.б.) эталонды бастамас бұрын memtx кеңістігі (қайта) жасалады, онда бастапқы индекс мәндері реттелген бүтін мәндердің генераторы арқылы жасалады. (тізбегі).
DDL кеңістігі келесідей көрінеді:

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

Қажет болса, эталонды іске қоспас бұрын кеңістік пішіннің 10,000 XNUMX кортежімен толтырылады.

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

Кортеждерге кездейсоқ кілт мәні арқылы қол жеткізіледі.

Эталонның өзі серверге бір сұраныс болып табылады, ол 10,000 5 рет орындалады (революция), ол өз кезегінде итерацияларда орындалады. Итерациялар 3 итерация арасындағы барлық уақыттағы ауытқулар 1%* рұқсат етілген қате шегінде болғанша қайталанады. Осыдан кейін орташа нәтиже алынады. Процессордың тежелуіне жол бермеу үшін итерациялар арасында XNUMX секундтық үзіліс бар. Луаның қоқыс жинағышы әр итерация алдында өшіріледі және ол аяқталғаннан кейін іске қосуға мәжбүр болады. PHP процесі тек эталонға қажетті кеңейтімдермен, шығыс буферлеуі қосылған және қоқыс жинаушы өшірілген кезде іске қосылады.

* Айналымдар санын, итерацияларды және қате шегін эталон параметрлерінде өзгертуге болады.

Сынақ ортасы

Төменде жарияланған нәтижелер MacBookPro (2015), операциялық жүйе – Fedora 30 (ядро нұсқасы 5.3.8-200.fc30.x86_64) жасалған. Tarantool докерде «параметрімен іске қосылды.--network host".

Пакет нұсқалары:

Tarantool: 2.3.0-115-g5ba5ed37e
Docker: 19.03.3, a872fc2f86 құрастырыңыз
PHP: 7.3.11 (cli) (құрылған: 22 жылғы 2019 қазан 08:11:04)
tarantool/клиент: 0.6.0
rybakit/msgpack: 0.6.1
ext-tarantool: 0.3.2 (+ 7.3 үшін патч)*
ext-msgpack: 2.0.3
ext-async: 0.3.0-8c1da46
сыртқы жүн: 4.4.12
экс-параллель: 1.1.3

* Өкінішке орай, ресми қосқыш PHP > 7.2 нұсқасымен жұмыс істемейді. PHP 7.3 кеңейтімін құрастыру және іске қосу үшін маған қолдануға тура келді патч.

нәтижелері

Синхронды режим

Tarantool протоколы екілік пішімді пайдаланады MessagePack хабарларды сериялау үшін. PECL қосқышында сериялау кітапхананың тереңдігінде жасырылады және пайдаланушы жерінің кодынан кодтау процесіне әсер етеді мүмкін емес сияқты. Таза PHP қосқышы, керісінше, стандартты кодтаушыны кеңейту немесе өзіңіздің іске асыруыңызды пайдалану арқылы кодтау процесін теңшеу мүмкіндігін береді. Қораптан шыққан екі кодтаушы бар, біреуі негізделген msgpack/msgpack-php (ресми MessagePack PECL кеңейтімі), екіншісі қосулы rybakit/msgpack (таза PHP тілінде).

Қосқыштарды салыстырмас бұрын, біз PHP қосқышы үшін MessagePack кодтауыштарының өнімділігін өлшейміз және одан әрі сынақтарда ең жақсы нәтижені көрсететінін қолданамыз:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
PHP нұсқасы (Pure) жылдамдығы бойынша PECL кеңейтімінен төмен болса да, нақты жобаларда мен оны әлі де пайдалануды ұсынамын. rybakit/msgpack, себебі ресми MessagePack кеңейтімінде пішім спецификациясы тек ішінара орындалған (мысалы, реттелетін деректер түрлеріне қолдау жоқ, онсыз сіз Decimal қолданбасын пайдалана алмайсыз - Tarantool 2.3 жүйесінде енгізілген жаңа деректер түрі) және басқалардың саны проблемалар (PHP 7.4-пен үйлесімділік мәселелерін қоса). Жалпы, жоба тасталған көрінеді.

Сонымен, синхронды режимде қосқыштардың өнімділігін өлшейік:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Графиктен көрініп тұрғандай, PECL қосқышы (Tarantool) PHP қосқышымен (Клиент) салыстырғанда жақсы өнімділікті көрсетеді. Бірақ бұл таңқаларлық емес, өйткені соңғысы баяу тілде жүзеге асырылумен қатар, шын мәнінде көп жұмыс істейді: әрбір қоңыраумен жаңа нысан жасалады. өтініш и Жауап (Таңдау жағдайында - сонымен қатар критерийлері, және Жаңарту/Жоғарту жағдайында ― операциялар), бөлек нысандар байланыс, Packer и өңдегіші олар сондай-ақ үстеме шығындарды қосады. Әлбетте, икемділіктің бағасы бар. Дегенмен, жалпы алғанда, PHP интерпретаторы жақсы өнімділікті көрсетеді, айырмашылығы бар болса да, ол шамалы және PHP 7.4-де JIT-ті айтпағанда, PHP 8-те алдын ала жүктеуді пайдаланған кезде одан да аз болуы мүмкін.

Әрі қарай жүрейік. Tarantool 2.0 SQL қолдауын енгізді. SQL протоколы арқылы Таңдау, Кірістіру, Жаңарту және Жою операцияларын орындап көрейік және нәтижелерді noSQL (екілік) эквиваленттерімен салыстырайық:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
SQL нәтижелері өте әсерлі емес (синхронды режимді әлі де сынап жатқанымызды еске сала кетейін). Дегенмен, мен бұл туралы алдын ала ренжімес едім; SQL қолдауы әлі де белсенді дамуда (салыстырмалы түрде жақында, мысалы, қолдау қосылды. мәлімдемелер дайындады) және тізімге қарағанда мәселелер, SQL қозғалтқышы болашақта бірқатар оңтайландырулардан өтеді.

Асинк

Енді Async кеңейтімі жоғарыдағы нәтижелерді жақсартуға қалай көмектесетінін көрейік. Асинхронды бағдарламаларды жазу үшін кеңейтім біз қолданатын корутиндерге негізделген API ұсынады. Біздің ортамыз үшін корутиндердің оңтайлы саны 25 екенін эмпирикалық түрде анықтаймыз:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
10,000 корутинге 25 XNUMX операцияны «таратыңыз» және не болатынын көріңіз:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
үшін секундына операциялар саны 3 еседен астам өсті tarantool-php/клиент!

Өкінішке орай, PECL қосқышы ext-async арқылы басталмады.

SQL туралы не деуге болады?

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Көріп отырғаныңыздай, асинхронды режимде екілік протокол мен SQL арасындағы айырмашылық қателік шегінде болды.

Swoole

Біз қайтадан корутиндердің оңтайлы санын білеміз, бұл жолы Свул үшін:
Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
25-ке тоқталайық. Async кеңейтімімен бірдей трюкті қайталайық - 10,000 корутин арасында 25 2 операцияны таратыңыз. Сонымен қатар, біз барлық жұмысты 5,000 екі процеске бөлетін тағы бір сынақ қосамыз (яғни, әрбір процесс 25 корутинде XNUMX операцияны орындайды). Қолдану арқылы процестер жасалады SwooleProcess.

нәтижелері:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Swole бір процесте іске қосылған кезде Async-пен салыстырғанда біршама төмен нәтиже көрсетеді, бірақ 2 процесс кезінде сурет күрт өзгереді (2 саны кездейсоқ таңдалмаған; менің құрылғымда ең жақсы нәтиже көрсеткен 2 процесс болды).

Айтпақшы, Async кеңейтімінде процестермен жұмыс істеуге арналған API бар, бірақ мен бір немесе бірнеше процестерде эталондарды орындаудан ешқандай айырмашылықты байқамадым (бір жерде қателескен болуым мүмкін).

SQL және екілік протокол:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Async сияқты, екілік және SQL операциялары арасындағы айырмашылық асинхронды режимде жойылады.

Параллель

Параллельдік кеңейтім корутиндер туралы емес, ағындар туралы болғандықтан, параллель ағындардың оңтайлы санын өлшейік:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Бұл менің құрылғымда 16-ға тең. 16 параллель ағында қосқыш көрсеткіштерін орындайық:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Көріп отырғаныңыздай, нәтиже асинхронды кеңейтімдерге қарағанда жақсырақ (2 процесте жұмыс істейтін Swoole есептелмейді). PECL қосқышы үшін Жаңарту және Upsert әрекеттері бос екенін ескеріңіз. Бұл бұл әрекеттердің қателікпен орындалмауымен байланысты - бұл экс-параллель, экс-tarantool немесе екеуінің де кінәсі екенін білмеймін.

Енді SQL өнімділігін салыстырайық:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету
Синхронды түрде жұмыс істейтін қосқыштарға арналған графикпен ұқсастығын байқадыңыз ба?

Бәрі бірге

Соңында, тексерілген кеңейтімдердің жалпы суретін көру үшін барлық нәтижелерді бір графикте қорытындылайық. Диаграммаға әлі жасалмаған бір ғана жаңа сынақты қосайық - Parallel* көмегімен Async coroutines параллельді іске қосайық. Жоғарыда аталған кеңейтімдерді біріктіру идеясы қазірдің өзінде бар талқыланды авторлар, бірақ консенсусқа қол жеткізілмеді, мұны өзіңіз жасауыңыз керек.

* Swoole coroutines Parallel көмегімен іске қосу мүмкін болмады; бұл кеңейтімдер үйлеспейтін сияқты.

Сонымен, соңғы нәтижелер:

Async, Swoole және Parallel көмегімен Tarantool үшін PHP қосқыштарын жеделдету

Орнына жасасу

Менің ойымша, нәтиже өте лайықты болды, және қандай да бір себептермен бұл шектеу емес екеніне сенімдімін! Мұны тек өзіңіз үшін нақты жобада шешу керек пе, тек мен үшін бұл синхронды TCP қосқышынан қаншалықты аз күш-жігермен «сығуға» болатынын бағалауға мүмкіндік беретін қызықты эксперимент екенін айтайын. Егер сізде эталондарды жақсарту туралы идеяларыңыз болса, мен сіздің сұрауыңызды қарауға қуаныштымын. Іске қосу нұсқаулары мен нәтижелері бар барлық код бөлек жарияланады репозиторийлер.

Ақпарат көзі: www.habr.com

пікір қалдыру