Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У дакладзе Андрэй Барадзін раскажа, як яны ўлічылі вопыт маштабавання PgBouncer пры праектаванні пулера злучэнняў Адысея, як выкочвалі яго ў production. Акрамя таго, абмяркуем якія функцыі пулера хацелася б бачыць у новых версіях: нам важна не толькі зачыняць свае запатрабаванні, але развіваць супольнасць карыстачоў Адысея.

Відэа:

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Ўсім прывітанне! Мяне клічуць Андрэй.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У Яндэксе я займаюся распрацоўкай open source баз дадзеных. І сёньня ў нас тэма пра connection pooler злучэньняў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Калі вы ведаеце, як назваць connection pooler па-руску, то скажыце мне. Я вельмі хачу знайсці добры тэхнічны тэрмін, які павінен устаяцца ў тэхнічнай літаратуры.

Тэма даволі складаная, таму што ў шматлікіх базах дадзеных connection pooler убудаваны і пра яго нават ведаць не трэба. Нейкія наладкі, вядома, усюды ёсць, але ў Postgres так не атрымліваецца. І паралельна (на HighLoad++ 2019) ідзе даклад Мікалая Самахвалава пра настройку запытаў у Postgres. І я так разумею, што сюды прыйшлі людзі, якія ўжо настроілі запыты ідэальна, і гэта людзі, якія сутыкаюцца з больш рэдкімі сістэмнымі праблемамі, звязанымі з сеткай, утылізацыяй рэсурсаў. І месцамі гэта можа было даволі складана ў тым плане, што праблемы невідавочныя.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У Яндэксе ёсць Postgres. У Яндекс.Облаке жывуць многія сэрвісы Яндекса. І ў нас некалькі петабайт дадзеных, якія генеруюць не менш за мільён запытаў у секунду ў Postgres.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І мы даем дастаткова тыпавы кластар усім сэрвісам – гэта асноўная primary нода вузла, звычайныя дзве рэплікі (сінхронная і асінхронная), рэзервовае капіраванне, маштабаванне чытаючых запытаў на рэпліцы.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Кожны вузел кластара - гэта Postgres, на якім акрамя Postgres і сістэм маніторынгу яшчэ ўсталяваны connection pooler. Connection pooler выкарыстоўваецца для fencing і па сваім асноўным прызначэнні.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Што такое асноўнае прызначэнне connection pooler?

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У Postgres прынятая працэсная мадэль пры працы з базай дадзеных. Гэта азначае, што адно злучэнне - гэта адзін працэс, адзін бэкенд Postgres. І ў гэтым бэкендзе вельмі шмат розных кэшаў, якія даволі дорага рабіць рознымі для розных злучэнняў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Акрамя таго, у кодзе Postgres ёсць масіў, які завецца procArray. Ён змяшчае асноўныя дадзеныя аб сеткавых злучэннях. І амаль усе алгарытмы апрацоўкі procArray маюць лінейную складанасць, яны прабягаюцца па ўсім масіве сеткавых злучэнняў. Гэта даволі хуткі цыкл, але з вялікай колькасцю ўваходзяць сеткавых злучэнняў усё становіцца крыху даражэй. А калі ўсё стала крыху даражэй, у выніку можна заплаціць вельмі вялікі кошт за вялікую колькасць сеткавых злучэнняў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Існуюць 3 магчымыя падыходы:

  • На баку прыкладання.
  • На баку базы дадзеных.
  • І паміж, т. е. разнастайныя камбінацыі.

Нажаль, убудаваны pooler цяпер знаходзіцца ў стадыі распрацоўкі. Сябры ў кампаніі PostgreSQL Professional у асноўным гэтым займаюцца. Калі ён з'явіцца, цяжка прадказаць. І фактычна на выбар архітэктара ў нас два рашэнні. Гэта application-side pool і proxy pool.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Application-side pool - гэта самы просты спосаб. І амаль усе кліенцкія драйвера вам падаюць спосаб: мільёны вашых злучэнняў у кодзе прадставіць у выглядзе некаторых дзясяткаў злучэнняў у базу дадзеных.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Узнікае праблема з тым, што ў пэўны момант вы хочаце маштабаваць бэкэнд, вы хочаце разгарнуць яго на мноства віртуальных машын.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Затым вы яшчэ разумееце, што ў вас яшчэ некалькі зон даступнасцяў, некалькі дата-цэнтраў. І падыход з client side pooling прыводзіць да вялікіх лікаў. Вялікія - гэта каля 10 000 злучэнняў. Гэта край, што можа нармальна працаваць.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Калі казаць пра proxy poolers, то ёсць два poolers, якія ўмеюць шмат усяго. Яны не толькі poolers. Яны poolers + яшчэ класная функцыянальнасць. Гэта Pgpool и Crunchy-Proxy.

Але, нажаль, гэтая дадатковая функцыянальнасць не ўсім патрэбна. І яна прыводзіць да таго, што poolers падтрымліваюць толькі сесійны pooling, т. е. адзін уваходны кліент, адзін выходны кліент у базу дадзеных.

Для нашых задач гэта не вельмі добрае падыходзіць, таму мы выкарыстоўваем PgBouncer, які рэалізуе transaction pooling, т. е. серверныя злучэнні супастаўляюцца кліенцкім злучэнням толькі на час транзакцыі.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І на нашай нагрузцы - гэта праўда. Але ёсць некалькі праблем.Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Праблемы пачынаюцца, калі вы хочаце дыягнаставаць сесію, таму што ўсе ўваходныя злучэнні ў вас лакальныя. Усе дашлі з loopback і неяк трасаваць сесію становіцца складана.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Вядома, вы можаце выкарыстоўваць application_name_add_host. Гэта спосаб на баку Bouncer дадаць IP-адрас у application_name. Але application_name усталёўваецца дадатковым злучэннем.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

На гэтым графіку, дзе жоўтая лінія - гэта рэальныя запыты, а дзе сіняя - запыты, якія ўлятаюць у базу. І вось гэтая розніца - гэта менавіта ўсталёўка application_name, які патрэбен толькі для трасіроўкі, але ён зусім не бясплатны.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Акрамя таго, у Bouncer нельга абмежаваць адзін pool, т. е. колькасць злучэнняў з базай дадзеных на вызначанага карыстача, на вызначаную базу.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Да чаго гэта прыводзіць? У вас ёсць нагружаны сэрвіс, напісаны на C++ і дзесьці побач маленькі сэрвіс на нодзе, які нічога страшнага з базай не робіць, але яго драйвер вар'яцее. Ён адчыняе 20 000 злучэнняў, а ўсё астатняе пачакае. У вас нават код нармальны.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Мы, вядома, напісалі маленькі патч для Bouncer, які дадаў гэтую настройку, г. зн. абмежаванне кліентаў на pool.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Можна было б гэта зрабіць на баку Postgres, т. е. ролі ў базе дадзеных абмежаваць колькасцю злучэнняў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Але тады вы страціце магчымасць зразумець, чаму ў вас няма злучэнняў з серверам. PgBouncer не прабівае памылку злучэння, ён вяртае заўсёды адну і тую ж інфармацыю. І вы не можаце зразумець: магчыма, у вас пароль памяняўся, магчыма, проста база лягла, магчыма, нешта не так. Але дыягностыкі ніякай няма. Калі сесію нельга ўсталяваць, вы не даведаецеся, чаму гэта нельга зрабіць.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У пэўны момант вы глядзіце на графікі дадатку і бачыце, што прыкладанне не працуе.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Глядзіце ў топ і бачыце, што Bouncer аднаструменны. Гэта паваротны момант у жыцці сервісу. Вы разумееце, што вы рыхтаваліся да маштабавання базы дадзеных праз паўтара гады, а вам трэба маштабаваць pooler.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Мы прыйшлі да таго, што нам трэба больш PgBouncer'аў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

https://lwn.net/Articles/542629/

Трохі запатчылі Bouncer.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І зрабілі так, што могуць быць паднятыя з перавыкарыстаннем TCP-порта некалькі Bouncers. І ўжо аперацыйная сістэма ўваходныя TCP-злучэнні паміж імі аўтаматычна round-robin'ом перакладае.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Гэта празрыста для кліентаў, т. е. усё выглядае так, як быццам у вас адзін Bouncer, але ў вас ёсць фрагментацыя idle-злучэнняў паміж запушчанымі Bouncer'амі.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І ў пэўны момант вы можаце заўважыць, што вось гэтыя 3 Bouncers з'ядаюць кожны сваё ядро ​​на 100%. Вам трэба шмат Bouncers. Чаму?

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Таму што ў вас есць TLS. У вас ёсць шыфраванае злучэнне. І калі пробенчмаркаць Postgres з TLS і без TLS, тыя вы выявіце, што колькасць усталяваных злучэнняў падае амаль на два парадку з уключэннем шыфравання, таму што TLS handshake спажывае рэсурсы цэнтральнага працэсара.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І ў топе вы можаце ўбачыць даволі шмат крыптаграфічных функцый, якія выконваюцца пры хвалі ўваходзяць злучэнняў. Паколькі ў нас primary можа перамыкацца паміж зонамі даступнасці, то хваля ўваходзячых злучэнняў - гэта даволі тыповая сітуацыя. Т. е. па нейкай прычыне стары primary быў недаступны, усю нагрузку адправілі ў іншы дата-цэнтр. Яны ўсе адначасова прыйдуць павітацца з TLS.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І вялікая колькасць TLS handshake можа не вітацца ўжо з Bouncer, а горла яму здушыць. З-за таймаўту хваля ўваходных злучэнняў можа стаць незатухаючай. Калі ў вас retry у базу без exponential backoff, яны не будуць прыходзяць зноў і зноў кагерэнтнай хваляй.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Вось прыклад 16 PgBouncer, якія грузяць 16 ядраў на 100%.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Мы дашлі да каскаднага PgBouncer. Гэта найлепшая канфігурацыя, якую можна дасягнуць на нашай нагрузцы з Bouncer. Вонкавыя Bouncers у нас служаць для TCP handshake, а ўнутраныя Bouncers служаць для рэальнага pooling, для таго, каб не моцна фрагментаваць вонкавыя злучэнні.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У такой канфігурацыі магчымы плыўны рэстарт. Можна рэстартаваць ўсе гэтыя 18 Bouncers па адным. Але падтрымліваць такую ​​канфігурацыю дастаткова складана. Сістэмныя адміністратары, DevOps і людзі, якія сапраўды нясуць адказнасць за гэты сервер, будуць не вельмі рады такой схеме.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Здавалася б, можна ўсе нашы дапрацоўкі прасоўваць у open source, але Bouncer не вельмі добрае сапсуецца. Напрыклад, магчымасць, запусціць некалькі PgBouncers на адным порце закамміцілі месяц таму. А pull request з гэтай функцыяй быў некалькі год таму.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

https://www.postgresql.org/docs/current/libpq-cancel.html

https://github.com/pgbouncer/pgbouncer/pull/79

Або яшчэ адзін прыклад. У Postgres вы можаце адмяніць які выконваецца запыт, адправіўшы сакрэт па-іншаму злучэнню без лішняй аўтэнтыфікацыі. Але некаторыя кліенты адпраўляюць проста TCP-reset, т. е. ірвуць сеткавае злучэнне. Што пры гэтым зробіць Bouncer? Ён нічога не зробіць. Ён працягне выконваць запыт. Калі ў вас прыйшло мноства злучэнняў, якія невялікімі запытамі паклалі аснову, то лёгка адарваць злучэнне ад Bouncer будзе недастаткова, неабходна яшчэ завяршыць тыя запыты, якія бягуць у базе.

Гэта было запатчана і гэтую праблему ўсё яшчэ не ўмяржылі ў upstream Bouncer'а.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І так мы дашлі да таго, што нам патрэбен свой connection pooler, які будзе развівацца, патчыцца, у якім можна будзе аператыўна выпраўляць праблемы і які, вядома, павінен быць шматструменным.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Шматструменнасць мы паставілі як асноўную задачу. Нам трэба добра вытрымліваць хвалю якія ўваходзяць TLS-злучэнняў.

Для гэтага нам прыйшлося распрацаваць асобную бібліятэку, якая завецца Machinarium, якая прызначаная для апісання машынных станаў сеткавага злучэння як паслядоўнага кода. Калі вы паглядзіце ў зыходны код libpq, то вы ўбачыце даволі складаныя выклікі, якія могуць вярнуць вам вынік і сказаць: «Выклічы мяне крыху пазней. Цяпер у мяне пакуль што IO, але, калі IO пройдзе ў мяне нагрузка для працэсара». І гэта шматузроўневая схема. Сеткавае ўзаемадзеянне звычайна апісваюць машынай станаў. Мноствам правілаў тыпу "Калі я раней атрымаў загаловак пакета памеру N, то зараз я чакаю N байт", "Калі я адпраўляў пакет SYNC, то зараз я чакаю пакет з метададзенымі выніку". Атрымліваецца даволі складаны контринтуитивный код, як калі б лабірынт пераўтварылі ў маленькую разгортку. Мы зрабілі так, што замест машыны станаў праграміст апісвае асноўны шлях узаемадзеяння ў выглядзе звычайнага імператыўнага кода. Проста ў гэтым імператыўным кодзе трэба ўстаўляць месцы, дзе паслядоўнасць выканання трэба перапыніць чаканнем дадзеных ад сеткі, перадаўшы кантэкст выканання іншай каруціне (green thread-у). Гэты падыход аналагічны таму, што мы самы чаканы шлях у лабірынце запісваем запар, а потым дадаем да яго адгалінавання.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У выніку ў нас ёсць адзін струмень, які робіць TCP accept і round-robin'ом перадае мноству workers TPC-злучэнне.

Пры гэтым кожнае кліенцкае злучэнне працуе заўсёды на адным працэсары. І гэта дазваляе зрабіць яго cache-friendly.

І акрамя таго, мы дапрацавалі крыху збор маленькіх пакетаў у адзін вялікі пакет для таго, каб разгрузіць сістэмны TCP-stack.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Акрамя таго, мы палепшылі транзакцыйны пулінг у тым плане, што Odyssey пры ўсталяванай наладзе можа адправіць CANCEL і ROLLBACK у выпадку абрыву сеткавага злучэння, т. е. калі запыт ніхто не чакае, Odyssey скажа базе, каб яна не імкнулася выканаць той запыт, які можа расходаваць каштоўныя рэсурсы.

І па магчымасці мы захоўваем злучэнні за адным і тым жа кліентам. Гэта дазваляе не пераўсталёўваць application_name_add_host. Калі гэта магчыма, то ў нас няма дадатковай пераўсталёўкі параметраў, якія патрэбны для дыягностыкі.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Мы працуем у інтарэсах Яндэкс.Аблокі. І калі вы карыстаецеся managed PostgreSQL і ў вас усталяваны connection pooler, вы можаце стварыць лагічную рэплікацыю вонкі, т. е. з'ехаць ад нас, калі вам захочацца, пры дапамозе лагічнай рэплікацыі. Bouncer вонкі струмень лагічнай рэплікацыі не аддасць.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Гэта прыклад настройкі лагічнай рэплікацыі.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Акрамя таго, у нас ёсць падтрымка фізічнай рэплікацыі вонкі. У Воблаку яна, вядома, немагчымая, таму што тады вам кластар аддасць занадта шмат інфармацыі пра сябе. Але ў вашых усталёўках, калі вам патрэбна фізічная рэплікацыя праз connection pooler у Odyssey, гэта магчыма.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У Odyssey цалкам сумяшчальны маніторынг з PgBouncer. У нас такая ж кансоль, якая выконвае амаль усе тыя ж самыя каманды. Калі чагосьці бракуе, дасылайце pull request, ці хаця б issue у GitHub, будзем дарабляць патрэбныя каманды. Але асноўная функцыянальнасць кансолі PgBouncer у нас ужо ёсць.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І, канешне, у нас ёсць error forwarding. Мы вернем тую памылку, якую паведаміла база. Вы атрымаеце інфармацыю, чаму вы не пападаеце ў базу, а не проста, што вы ў яе не пападаеце.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Гэтая магчымасць выключаецца на выпадак, калі вам патрэбна 100%-ная сумяшчальнасць з PgBouncer. Мы можам паводзіць сябе гэтак жа, як Bouncer, проста на ўсялякі выпадак.

Распрацоўка

Некалькі слоў аб зыходным кодзе Odyssey.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

https://github.com/yandex/odyssey/pull/66

Напрыклад, ёсць каманды "Pause / Resume". Яны звычайна выкарыстоўваюцца для абнаўлення базы дадзеных. Калі вам трэба абнавіць Postgres, тыя вы можаце паставіць яго на паўзу ў connection pooler, зрабіць pg_upgrade, пасля гэтага зрабіць resume. І са боку кліента гэта будзе выглядаць так, як быццам база проста тармазіла. Гэтую функцыянальнасць нам прынеслі людзі з супольнасці. Яна пакуль яшчэ не прымеркавана, але хутка ўсё будзе. (Ужо прымержана)

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

https://github.com/yandex/odyssey/pull/73 - ужо прымеркавана

Акрамя таго, адна з новых фіч у PgBouncer, гэта падтрымка SCRAM Authentication, якую нам таксама прынёс чалавек, які не працуе ў Яндэкс.Аблокі. І тое і іншае - гэта складаная функцыянальнасць і важная.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Таму хочацца расказаць з чаго зроблены Odyssey, раптам вы таксама зараз хочаце крышку папісаць код.

У вас ёсць зыходная база Odyssey, якая абапіраецца на дзве асноўныя бібліятэкі. Бібліятэка Kiwi - гэта рэалізацыя Postgres'авага пратакола паведамленняў. Т. е. натыўны proto 3 у Postgres – гэта стандартныя паведамленні, якімі франтэнды, бэкенды могуць абменьвацца. Яны рэалізаваны ў бібліятэцы Kiwi.

Бібліятэка Machinarium - гэта бібліятэка рэалізацыі патокаў. Невялікі фрагмент гэтага Machinarium напісаны на асэмблеры. Але, не палохайцеся, тамака ўсяго 15 радкоў.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Архітэктура Odyssey. Ёсць асноўная машына, у якой запушчаны coroutines. У гэтай машыне рэалізуецца accept уваходных TCP-злучэнняў і размеркаванне па workers.

Унутры аднаго worker можа працаваць апрацоўшчык некалькіх кліентаў. А таксама галоўным чынам струмені круцяцца кансоль і апрацоўка crone-задач па выдаленні злучэнняў, якія больш не патрэбныя ў pool.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Для тэставання Odyssey выкарыстоўваецца стандартны набор тэстаў Postgres. Проста запускаем install-check праз Bouncer і праз Odyssey, атрымліваем нулявы div. Там некалькі тэстаў, звязаныя з фарматаваннем дат, не праходзяць абсалютна аднолькава ў Bouncer і ў Odyssey.

Акрамя таго, ёсць мноства драйвераў, якія маюць сваё тэсціраванне. І іх тэсты мы выкарыстоўваем для тэсціравання Odyssey.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Акрамя таго, з-за нашай каскаднай канфігурацыі нам даводзіцца тэставаць розныя звязкі: Postgres + Odyssey, PgBouncer + Odyssey, Odyssey + Odyssey для таго, каб быць упэўненымі ў тым, што, калі Odyssey апынуўся ў нейкай з частак у каскадзе, ён таксама па-ранейшаму працуе так, як мы чакаем.

граблі

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Мы выкарыстоўваем Odyssey у production. І было б не сумленна, калі б я сказаў, што ўсё проста працуе. Не, т. е. так, але не заўсёды. Напрыклад, у production усё проста працавала, потым дашлі нашы сябры з PostgreSQL Professional і сказалі, што ў нас ёсць memory leak. Яны праўда былі, мы іх выправілі. Але гэта было проста.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Потым мы выявілі, што ў connection pooler ёсць уваходныя TLS-злучэнні і выходныя TLS-злучэнні. І ў злучэннях патрэбны кліенцкія сертыфікаты і серверныя сертыфікаты.

Серверныя сертыфікаты Bouncer і Odyssey перачытваюць іх pcache, але кліенцкія сертыфікаты перачытваць з pcache не трэба, таму што наш які маштабуецца Odyssey у выніку ўпіраецца ў сістэмную прадукцыйнасць чытання гэтага сертыфіката. Гэта для нас стала нечаканасцю, таму што ўпёрся ён далёка не адразу. Спачатку ён лінейна маштабаваўся, а пасля 20 000 уваходных адначасовых злучэнняў гэтая праблема сябе выявіла.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Pluggable Authentication Method - гэта магчымасць аўтэнтыфікавацца ўбудаванымі lunux'авымі сродкамі. У PgBouncer яна рэалізавана так, што ёсць асобны струмень на чаканне адказу ад PAM і ёсць асноўны струмень PgBouncer, які абслугоўвае бягучае злучэнне і можа папытаць іх пажыць у струмені PAM.

Мы гэта не сталі рэалізоўваць па адной простай прычыне. У нас жа шмат плыняў. Навошта нам гэта патрэбна?

У выніку гэта можа ствараць праблемы з тым, што, калі ў вас ёсць PAM-аўтэнтыфікацыя і не PAM-аўтэнтыфікацыі, то вялікая хваля PAM-аўтэнтыфікацыі можа істотна затрымліваць не PAM-аўтэнтыфікацыю. Гэта адна з тых штук, якую мы не выправілі. Але калі вы хочаце гэта выправіць, можаце заняцца вось гэтым.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Яшчэ адны граблі былі з тым, што ў нас ёсць адзін паток, які робіць accept усім уваходным злучэнням. І потым іх перадае на worker pool, дзе будзе адбывацца TLS handshake.

У выніку, калі ў вас ёсць кагерэнтная хваля з 20 000 сеткавых злучэнняў, яны ўсё будуць прынятыя. І на баку кліента libpq пачне справаздачу таймаўтаў. Па змаўчанні накшталт 3 секунды тамака варта.

Калі яны ўсё не могуць адначасова зайсці ў базу, то яны не могуць зайсці ў базу, таму што ўсё гэта можа быць пакрыта не экспанентным retry.

Мы прыйшлі да таго, што скапіявалі тут схему з PgBouncer з тым, што ў нас есць throttling колькасці TCP-злучэнняў, якім мы робім accept.

Калі мы бачым, што мы аксепцім злучэнні, а яны ў выніку не паспяваюць пахендшайкіцца, мы ставім іх у чаргу для таго, каб яны не расходавалі рэсурсы цэнтральнага працэсара. Гэта прыводзіць да таго, што адначасовы handshake можа рабіцца не для ўсіх злучэнняў, якія прыйшлі. Але хаця б нехта ў базу зойдзе, нават калі нагрузка дастаткова моцная.

Дарожная карта

Чаго хацелася б убачыць у будучыні ў Odyssey? Што мы гатовы самі распрацоўваць і што мы чакаем ад супольнасці?

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

На жнівень 2019 года.

Вось так выглядаў roadmap Odyssey у жніўні:

  • Мы хацелі SCRAM і PAM authentication.
  • Мы хацелі forward якія чытаюць запытаў на standby.
  • Жадалася бы online-restart.
  • І магчымасць рабіць паўзу на сэрвэры.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Палова гэтага roadmap выканана, прычым не намі. І гэта добра. Таму давайце абмяркуем тое, што засталося і дадамо яшчэ.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Што тычыцца forward read-only queries to standby? Мы маем рэплікі, якія без выканання запытаў будуць проста грэць паветра. Яны нам неабходны для забеспячэння failover і switchover. У выпадку праблем у адным з дата-цэнтры хацелася б іх заняць нейкай карыснай працай. Таму што тыя ж самыя цэнтральныя працэсары, тую самую памяць мы не можам сканфігураваць па-іншаму, таму што інакш не будзе працаваць рэплікацыя.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У прынцыпе, у Postgres, пачынаючы з дзясяткі ёсць магчымасць пры злучэнні паказаць гэтак жа session_attrs. Вы ў злучэнні можаце пералічыць усе хасты баз дадзеных і сказаць, навошта вы ідзяце ў базу дадзеных: запісаць ці толькі прачытаць. І драйвер сам абярэ першы па спісе хост, які яму больш падабаецца, які выконвае патрабаванні session_attrs.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Але праблема гэтага падыходу ў тым, што ён не кантралюе лаг рэплікацыі. У вас можа быць нейкая рэпліка, якая адстала на непрымальны для вашага сервісу час. Для таго каб зрабіць поўнафункцыянальнае выкананне якія чытаюць запытаў на рэпліцы, у сутнасці, нам трэба падтрымаць у Odyssey магчымасць не працаваць, калі чытаць нельга.

Odyssey павінен хадзіць часам у базу і пытаць рэплікацыйную адлегласць ад primary. І калі яно дасягнула лімітавага значэння, новыя запыты ў базу не пускаць, сказаць кліенту, што трэба зноўку ініцыяваць злучэнні і, магчыма абраць іншы хост для выканання запытаў. Гэта дазволіць базе хутчэй аднавіць рэплікацыйны лаг і зноў вярнуцца для адказу запытам.

Тэрміны рэалізацыі складана назваць, бо гэта open source. Але, спадзяюся, што не 2,5 гады як у калегаў з PgBouncer. Вось гэтую функцыю хацелася б бачыць у Odyssey.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

У суполцы людзі пыталіся пра падтрымку prepared statement. Цяпер вы можаце стварыць prepared statement двума спосабамі. Па-першае, вы можаце выканаць SQL-каманду, а менавіта "prepared". Для таго, каб зразумець гэтую SQL-каманду нам трэба навучыцца разумець SQL на баку Bouncer. Гэта быў бы overkill, таму што гэта перабор, бо нам патрэбен цалкам парсер. Мы не можам парсіць кожную SQL-каманду.

Але ёсць prepared statement на ўзроўні пратаколу паведамленняў на proto3. І гэта тое месца, калі інфармацыя аб тым, што ствараецца prepared statement, прыходзіць у структураваным выглядзе. І мы маглі б падтрымаць разуменне таго, што на нейкім сэрвэрным злучэнні кліент папрасіў стварыць prepared statements. І нават калі транзакцыя зачынілася, нам трэба па-ранейшаму падтрымліваць складнасць сервера і кліента.

Але тут узнікае разыходжанне ў дыялогу, таму што хтосьці кажа аб тым, што трэба разумець, які менавіта prepared statements стварыў кліент і падзяляць сервернае злучэнне паміж усімі кліентамі, якія стварылі гэтае сервернае злучэнне, т. е. якія стварылі такі prepared statement.

Андрэс Фройнд сказаў, што калі да вас прыйшоў кліент, які ўжо ствараў у іншым серверным злучэнні такі prepared statement, то стварыце яго за яго. Але, здаецца, гэта крыху няправільна выконваць запыты ў базе замест кліента, але з пункту гледжання распрацоўшчыка, які піша пратакол узаемадзеяння з базай, гэта было б зручна, калі б яму проста далі сеткавае злучэнне, у якім ёсць такі падрыхтаваны запыт.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

І яшчэ адна фіча, якую нам трэба рэалізаваць. У нас зараз ёсць маніторынг, сумяшчальны з PgBouncer. Мы можам вярнуць сярэдні час выканання запыту. Але сярэдні час - гэта сярэдняя тэмпература па бальніцы: хтосьці халодны, хтосьці цёплы - у сярэднім усе здаровыя. Гэта не праўда.

Нам трэба рэалізаваць падтрымку перцэнтыляў, якія б указвалі на тое, што ёсць павольныя запыты, якія расходуюць рэсурсы, і зрабілі б маніторынг больш прымальным.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Самае галоўнае - жадаецца версію 1.0 (Ужо выйшла версія 1.1). Справа ў тым, што зараз Odyssey знаходзіцца ў версіі 1.0rc, т. е. release candidate. І ўсе граблі, якія я пералічыў, былі адрамантаваны роўна з той самай версіяй, акрамя memory leak.

Што для нас будзе азначаць вэрсія 1.0? Мы выкочваем Odyssey на свае базы. Ён ужо цяпер працуе на нашых базах, але калі ён дасягне кропкі ў 1 запытаў у секунду, то мы можам сказаць, што гэта рэлізная версія і гэта версія, якую можна назваць 000.

У суполцы некалькі чалавек папрасілі, каб у версіі 1.0 былі яшчэ паўза і SCRAM. Але гэта будзе азначаць, што нам трэба будзе выкаціць у production ужо наступную версію, таму што ні SCRAM, ні паўза да гэтага часу не змярцвелы. Але, хутчэй за ўсё, гэтае пытанне будзе дастаткова аператыўна вырашана.

Odyssey roadmap: што яшчэ мы жадаем ад пулера злучэнняў. Андрэй Барадзін (2019)

Я чакаю вашых захапляльных патрабаванняў. І яшчэ хацелася б пачуць, якія ў вас есць праблемы з Bouncer. Давайце іх абмяркуем. Можа быць, мы зможам нейкія функцыі рэалізаваць, якія патрэбны вам.

На гэтым мая частка скончана, я хацеў бы паслухаць вас. Дзякуй!

пытанні

Калі я свой пастаўлю application_name, ён будзе правільна прачынацца, у тым ліку ў transaction pooling у Odyssey?

У Odyssey ці ў Bouncer?

У Odyssey. У Bouncer прачынаецца.

Сэт мы зробім.

І калі маё рэальнае злучэнне будзе скакаць па іншых злучэннях, то яно будзе перадавацца?

Мы зробім сэт усіх параметраў, якія пералічаны ў спісе. Я не магу сказаць, ці ёсць у гэтым спісе application_name. Здаецца, яго там бачыў. Мы ўсталюем усё тыя ж параметры. Адным запытам там сэт зробіць усё тое, што было ўсталявана кліентам пры стартапе.

Дзякуй, Андрэй, за даклад! Добры даклад! Рады, што Odyssey з кожнай хвілінай развіваецца ўсё хутчэй і хутчэй. Жадаю гэтак жа працягваць. Мы ўжо да вас звярталіся з просьбай мець multi data-source падлучэнне, каб Odyssey мог падлучацца адначасова да розных баз дадзеных, т. е. майстар slave, а потым аўтаматычна пасля failover падлучацца да новага майстра.

Так, я, здаецца, узгадваю гэтую дыскусію. Цяпер ёсць некалькі storages. Але пераключэння паміж імі няма. Мы павінны на сваім баку апытваць сэрвер, што ён яшчэ жывы і разумець, што адбыўся failover, хто выкліча pg_recovery. У мяне ёсць стандартны спосаб зразумець, што мы дашлі не на майстар. І мы павінны зразумець неяк з памылак ці як? Т. е. ідэя цікавая, яна абмяркоўваецца. Пішыце больш каментароў. Калі ў вас ёсць працоўныя рукі, якія ведаюць C, тое гэта наогул выдатна.

Пытанне маштабавання па рэпліках нас таксама цікавіць, таму што мы хочам зрабіць adoption рэплікаваных кластараў максімальна простым для распрацоўшчыкаў дадатку. Але тут жадалася б больш каментароў, т. е. як менавіта зрабіць, як добра зрабіць.

Пытанне таксама пра рэплікі. Атрымліваецца, што ў вас ёсць майстар і некалькі рэплікаў. І зразумела, што ў рэпліку ходзяць радзей, чым у майстар за злучэннямі, бо ў іх можа быць адрозненне. Вы казалі, што адрозненне ў дадзеных можа быць такое, што не будзе задавальняць ваш бізнэс і вы не будзеце туды хадзіць, пакуль яна не дарэплікуецца. Пры гэтым калі вы доўга туды не хадзілі, а потым пачалі хадзіць, то тыя дадзеныя, якія патрэбныя, не будуць адразу даступныя. Т. е. калі мы ўвесь час ходзім у майстар, то там кэш прагрэты, а ў рэпліцы кэш трохі адстае.

Ды гэта праўда. У pcache не будзе блокаў дадзеных, якія вы жадаеце, у real cache не будзе інфармацыі аб табліцах, якія вы жадаеце, у планах не будзе распарсенных запытаў, наогул нічога не будзе.

І калі ў вас ёсць нейкі кластар, і вы дадаеце туды новую рэпліку, то пакуль яна стартуе, у ёй усё дрэнна, т. е. яна нарошчвае свой кэш.

Я зразумеў ідэю. Правільным падыходам было б запусціць невялікі працэнт запытаў спачатку на рэпліку, якія б прагрэлі кэш. Грубіянска кажучы, у нас ёсць умова, што мы павінны адставаць не больш, чым на 10 секунд ад майстра. І гэта ўмова ўключаць не адной хваляй, а плаўна для некаторых кліентаў.

Так, павялічваць вагу.

Гэта добрая ідэя. Але спачатку трэба рэалізаваць гэтае адключэнне. Спачатку трэба выключыцца, а потым падумаем, як уключыцца. Гэта выдатная фіча, каб плаўна ўключацца.

У nginx ёсць такая опцыя slowly start у кластары для сервера. І ён паступова нарошчвае нагрузку.

Так, выдатная ідэя, паспрабуем, калі дойдзем да гэтага.

Крыніца: habr.com

Дадаць каментар