Лепшы спосаб захаваць копію дадзеных, аптымізаваную для чытання

У мяне ёсць сістэма, якая апрацоўвае розныя аперацыі з сотнямі кліентаў у хвіліну. Кожная транзакцыя абмежаваная падмноствам функцыянальных магчымасцяў, і, такім чынам, для кожнага тыпу здзелкі (каля 25 з тых, у мяне ёсць) асобная табліца базы дадзеных (гэта дазваляе пазбегнуць блакіроўкі чакае ўсіх кліентаў, злучаных). Гэтыя кліенты падключаюцца да некалькіх вэб-прыкладанняў # C працуе ў IIS на Windows.

Тым не менш, у нас ёсць патрабаванне для доступу толькі для чытання для падмноства дадзеных, якая з'яўляецца прадуктам большасці гэтых здзелак. У цяперашні час гэты працэс толькі для чытання з'яўляецца 14 табліцы <�моцны> LEFT OUTER JOIN , які пакутліва павольна. (Мы выкарыстоўваем сервер MS SQL)

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

Што будзе самым стабільным і які маштабуецца падыход?

Як я бачу гэта ёсць тры варыянты, ні адзін з якіх я сапраўды люблю:

  1. Db спускавыя
  2. <�Літый> даведачны сэрвіс (дэман), які абнаўляе дадзеныя (перыядычна або з дапамогай трыгера) </літый>
  3. Фонавая задача абпальваюць у маёй сеткі, якая абнаўляе дадзеныя.

EDIT: У ідэале, ДД хоча, каб дадзеныя быць не больш за 3-х секунд нясвежымі. Мы гаворым толькі дзесяткі тысяч радкоў (менш 100K) каля 90 слупкоў.

0
Вы думаеце пра канцэпцыю называецца «агрэгаваныя табліцы», ён звычайна выкарыстоўваецца ў BI. Спосаб пайсці на гэта шмат у чым залежыць ад набору дадзеных для кіравання. Для досыць малых набораў дадзеных, вы можаце пайсці з абнаўленнем агрэгаваных табліц пры абнаўленні звычайных табліц. (З дапамогай трыгера або ў кодзе.) Калі няма, то вы павінны ісці з нейкім фонам службы.
дададзена аўтар Florian Margaine, крыніца

5 адказы

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

Фармат файла залежыць ад таго, што вам трэба адбыць гэтай дзяржаве.

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

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

1
дададзена
Гэта не вырашае літаральна ні адной з праблем, змушаючы ОП згарнуць сваю ўласную замену базы дадзеных.
дададзена аўтар mınxomaτ, крыніца
@ Dan1111: Я не згодны. Гаворка ідзе ўсё аб атрыманні дадзеных хутка. Я не прапаную замену базы дадзеных, але кэш файлавай сістэмы. Вялікая розніца. Запытваючы частку толькі прапанавала пазней у адказ на гэты адказ і не выразна вызначана ў самім пытаньні.
дададзена аўтар Jonathan van de Veen, крыніца
Таму ў асноўным вы прапануеце змясціць кэш ў файл дзе-небудзь. Тады мы маем справу з забеспячэннем мноства чытання і запісы сервераў могуць атрымаць доступ да яго як-то, то мы маем справу з унутранай структурай, а затым, вядома, будзе цяжка запытаць, таму што, калі мы хочам, каб зрабіць пошук па 20K радкоў ўнутры што файл прадукцыйнасць будзе яшчэ горш ці больш памяці больш інтэнсіўна, чым калі мы робім гэта ў SQL ...
дададзена аўтар Cyle, крыніца

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

аперацыя запісу

As you mention your "transactions with a subset of functionality," these are your use cases/models for аперацыя запісуs. This way, you can optimise the write models as your business drives you. Your write models could be still stored in your current RDBMS choice.

Першае важнае адрозненне і дабаўленая вартасць тут з'яўляецца тое, што вы дазваляеце сабе:

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

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

аперацыя чытання

Depending on your data structure and relations, read models are a way to store data in a denormalized way. As you wrote: a current аперацыя чытання consists of 14 SQL joins, which could be a nightmare to deal with. This is where use-case optimised read models can step in.

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

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

Чытайце бок захоўванне можа вар'іравацца ад RDMS пасціцца NoSQL рашэнняў, такімі як дакумент БД і ключ-значэнне крамы.

Сінхранізацыя паміж сховішчамі дадзеных

Як мне зрабіць гэта: кожны раз, калі <�ет> Каманда выконвае, ён публікуе падзея , якія змяшчаюць карысную нагрузку ідэнтыфікатараў, неабходных для запуску аднаўлення крамы чытання (каб быць у сінхранізацыі з запісам бок).

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

Канкрэтны лёгкі прыклад:

  1. A request is caught by an IIS-hosted WebApi or MVC controller.
  2. The Controller populates the respective command object with values from the request.
  3. A CommandHandler gets fired up from the Controller.
    • The command handler does its job storing the given write model
    • The command handler raises an event to notify the subscribers about the change
  4. An EventHandler, responsible for handling the event raised by the previous command handler, fires up a new command that's responsible for reconstituting the read store side.

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

Некаторыя рэчы, каб адзначыць:

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

Ваша пытанне аб тым, «што, калі апрацоўшчык падзеі памірае?» гонг, каб зрабіць гэта трохі больш складаным, шляхам увядзення новых канцэпцый, званых Eventual Паслядоўнасць і паведамленні/падзеі ў чарзе. Цытаванне Greg Young:

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

Гэтая канцэпцыя пашырае гэты адказ з:

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

выснову

All this above is nothing new. I like to call this CQRS Lite - a term I have borrowed from Dino Esposito. He has a very comprehensive tutorial course on this at PluralSight. I wholeheartedly recommend that you watch it there, as there is a lot to learn from him. [1]

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

Іншым добрым крыніцай інфармацыі па гэтым пытанні CQRS Performance Engineering: Чытанне супраць Read/Write Models з Derick Бейлі.

1
дададзена
Таксама ў залежнасці ад свежасці дадзеных, неабходных, начны працэс ETL можа быць выкарыстаны ў Денормализованные табліцы на адной і тыя ж (ці іншыя) базах дадзеных. Начны працэс ETL можа затым быць аптымізаваны для выканання ў патрэбны час.
дададзена аўтар zzr, крыніца
@WindRaven Гэта патрабаванне, каб дадзеныя былі даступныя кожны другі, па начах нідзе не побач, дзе мы хочам, каб гэта было :)
дададзена аўтар Cyle, крыніца
@kayess Так што гэта выдатна, але гэта проста паўторна фраза, што я разумею ўжо. Ключ для мяне знаходзіцца ў сярэдняй частцы - сінхранізацыя. Як бы я зрабіць гэта так надзейна, хутка і ад збояў? З практычнага боку кода - трыгера, нт службы, пакетны рэжым працы, што? Выкарыстоўваючы ключ-значэнне захоўвае гэта жарт - я павінен даць набор аб'ектаў, якія могуць быць прагартаў, так што, безумоўна, не будзе працаваць.
дададзена аўтар Cyle, крыніца
@kayess Дык што ж вы робіце, калі ваш EventHandler памірае ў сярэдзіне крамы абнаўлення для чытання (напрыклад, перазагрузкі кампутара, IISRESET, powerloss і г.д.)?
дададзена аўтар Cyle, крыніца

Адказ залежыць ад:

  • If you have many updated datarows (i.e. > 100 000 rows per hour)
  • and if it is ok that the aggregated data is one days old

datawarehouses або «BI» сістэма выкарыстаць другі <�моцны> Аналіз базы дадзеных , які абнаўляецца адзін раз у дзень, калі <�моцны> транзакцыйнай базы дадзеных (дзе аперацыі запісу маюць месца) мае нізкую нагрузку.

Гэта мае тое перавага, што транзакцыйных базы дадзеных не блакуецца, калі аналіз адбываецца.

0
дададзена

Another option is to alter the code which updates the database to populate both tables.

Гэта проста, калі базавы код мае адпаведны ўзровень абстракцыі вакол насельніцтва стала - гэта значыць. дзеянні абнаўленняў з'яўляюцца ў нейкім ўпакоўцы класа, бібліятэкі або API. Вы проста змяніць гэтую абгортку, каб зрабіць дзве ўстаўкі/абнаўлення, а не адзін у адпаведных месцах.

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

0
дададзена
@zaitsman блакавання з'яўляецца праблемай, якая можа быць пераадоленая. Напрыклад, вы маглі б мець чаргу для абнаўленняў ў табліцы.
дададзена аўтар mınxomaτ, крыніца
@zaitsman я не разумею. Не было б быць адтэрмінавана толькі бягучай аперацыяй абнаўлення, то наступныя абнаўлення будуць адтэрмінаваныя на аперацыі чытання?
дададзена аўтар mınxomaτ, крыніца
На жаль, гэта не падыходзіць. У гэтым выпадку я мог бы таксама перапісаць увесь мой код, каб выкарыстоўваць адну табліцу, таму што праблема тут будзе замак на стале толькі для чытання.
дададзена аўтар Cyle, крыніца
калі я магу гэта зрабіць, то аперацыя чытання можа быць адкладзеная на агульны час, неабходнае для апрацоўкі гэтай чарзе.
дададзена аўтар Cyle, крыніца
У мяне ёсць 10K ўваходзяць запытаў у, скажам, 2-х хвілінах. Калі я пабудаваць паслядоўную чаргу абнаўленняў, каб пазбегнуць блакіроўкі табліцы, то для мяне, каб атрымаць дадзеныя з запыту 10Kth мне трэба чакаць, пакуль уся мая чарга не робіцца. Гэта не адпавядае маім патрабаванням.
дададзена аўтар Cyle, крыніца

Materialized view may work for you here.

<�Р> Для таго, каб падтрымліваць эфектыўнае запытванні, агульнае рашэнне заключаецца ў стварэнні ў   загадзя, выгляд, што матэрыялізуе дадзеныя ў фармаце, найбольш падыходных для   патрабаваныя вынікі ўстаноўлены. Матэрыялізаваць ўяўленне шаблон апісвае   генеравання запаўняюцца прадстаўлення дадзеных у асяроддзях, дзе крыніца   дадзеныя не ў фармаце, які падыходзіць для запытаў, дзе   генерацыі падыходнага запыту з'яўляецца цяжкім, ці там, дзе прадукцыйнасць запытаў   бедна з-за характар ​​дадзеных або сховішча дадзеных. </р>
0
дададзена
@zaitsman Так <�я>, што </я> старонка не мае практычнага рашэння.
дададзена аўтар Flamewires, крыніца
На жаль, гэта паняцце менавіта тое, што я спрабаваў апісаць - табліцу, у якой захоўваюцца дадзеныя. Але няма ніякага практычнага рашэння або кода на гэтай старонцы MSDN.
дададзена аўтар Cyle, крыніца
Калі ласка, не публікуйце адказы, якія толькі спасылкі на знешнія рэсурсы.
дададзена аўтар Andy, крыніца