PostgreSQL і налады ўзгодненасці запісу для кожнага канкрэтнага злучэння

Пераклад артыкула падрыхтаваны спецыяльна для студэнтаў курса «Базы Даных». Цікава развівацца ў гэтым напрамку? Запрашаем вас на Дзень Адчыненых Дзверы, дзе мы падрабязна распавядаем пра праграму, асаблівасці анлайн-фармату, кампетэнцыі і кар'ерныя перспектывы, якія чакаюць выпускнікоў пасля навучання.

PostgreSQL і налады ўзгодненасці запісу для кожнага канкрэтнага злучэння

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

Нашто мне гэта?

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

Знаёмцеся, кампраміс

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

Кампраміс 1: Прадукцыйнасць

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

Кампраміс 2: Узгодненасць

Вынік у выпадку збою ў працы лідара ў гэтых двух падыходах таксама будзе розным. Калі праца выконваецца асінхронна, то пры ўзнікненні такой памылкі, не ўсе запісы будуць зафіксаваны рэплікамі. Колькі будзе страчана? Залежыць ад самога дадатку і эфектыўнасці рэплікацыі. Рэплікацыя Compose перашкодзіць рэпліцы стаць лідэрам у выпадку, калі колькасць інфармацыі ў ёй на 1 Мб менш, чым у лідэры, гэта значыць патэнцыйна можа быць страчана да 1 Мб запісаў пры асінхроннай працы.

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

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

Кампраміс 3: Збоі

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

Па адным злучэнні на транзакцыю?

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

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

Забеспячэнне кантролю на практыцы

Па змаўчанні PostgreSQL забяспечвае ўзгодненасць. Гэта кантралюецца параметрам сервера synchronous_commit. Па змаўчанні ён у становішчы on, але ў яго ёсць тры іншых варыянты: local, remote_write або off.

Пры ўсталёўцы параметра ў off спыняюцца ўсе сінхронныя коміты, нават у лакальнай сістэме. Параметр у local вызначае сінхронны рэжым для лакальнай сістэмы, але запісы ў рэплікі вырабляюцца асінхронна. Remote_write заходзіць яшчэ далей: запісы ў рэплікі робяцца асінхронна, але вяртаюцца, калі рэпліка прыняла запіс, але не запісала яе на дыск.

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

Цяпер, мы раскажам вам, як наладзіць гэта ў адно імгненне, але ўявіце, што мы ўсталявалі synchronous_commit в local для сервера. Мы задаліся пытаннем, ці можна змяняць параметр synchronous_commit на лета, і аказалася, што не проста можна, для гэтага нават ёсць цэлых два спосабы. Першы - гэта задаць сесію вашага злучэння наступным чынам:

SET SESSION synchronous_commit TO ON;  
// Your writes go here

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

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

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Your writes go here
COMMIT;  

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

Настройка PostgreSQL

Да гэтага мы ўяўлялі сабе сістэму PostgreSQL з synchronous_commit, устаноўленым у local. Каб гэта было рэальна на баку сервера, вам трэба будзе ўсталяваць два параметры канфігурацыі сервера. Яшчэ адзін параметр synchronous_standby_names будзе ўступаць у свае правы, калі synchronous_commit будзе ў on. Ён вызначае якія рэплікі маюць права на сінхронныя коміты, і мы ўсталюем яго ў *, што будзе азначаць задзейнічанне ўсіх рэплік. Гэтыя значэння звычайна наладжваюцца ў файле канфігурацыі шляхам дадання:

synchronous_commit = local  
synchronous_standby_names='*'

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

Калі вы сачылі за развіццём праекта Governor, вы маглі заўважыць некаторыя нядаўнія змены (1, 2), якія дазволілі карыстальнікам Governor тэставаць гэтыя параметры і кантраляваць іх узгодненасць.

Яшчэ пара слоў…

Літаральна тыдзень таму, я б вам сказаў, што немагчыма настолькі тонка наладзіць PostgreSQL. Менавіта тады Курт, чалец каманды платформы Compose, настойваў на тым, што такая магчымасць ёсць. Ён уціхамірыў мае пярэчанні і знайшоў у дакументацыі PostgreSQL наступнае:

PostgreSQL і налады ўзгодненасці запісу для кожнага канкрэтнага злучэння

Гэты параметр можа быць зменены ў любы час. Паводзіны для любой транзакцыі вызначаюцца настройкай, якая дзейнічае пры коміце. Таму магчыма і карысна, каб для некаторых транзакцый коміты здзяйсняліся сінхронна, а для іншых - асінхронна. Напрыклад, каб прымусіць адну multistatement транзакцыю рабіць коміты асінхронна, калі значэнне параметру па змаўчанні процілегла, задайце SET LOCAL synchronous_commit TO OFF у транзакцыі.

З дапамогай такой невялікай мадыфікацыі ў файле канфігурацыі мы далечы карыстачам магчымасць кантраляваць іх узгодненасць і прадукцыйнасць.

Крыніца: habr.com

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