Взаємодія з даними за допомогою декількох баз даних / серверів


18

Усі проекти, з якими мені доводилося займатися, вимагали лише однієї бази даних на одному сервері. Мені цікаво дізнатися більше про те, як проекти, які потребують масштабування, переміщаються до декількох баз даних та / або серверів, щоб допомогти керувати навантаженням. Я знаю про високу масштабованість , але мене особливо цікавлять приклади коду чи додаткові ресурси, де я міг би прочитати більше з цього питання.

Наприклад:

  • Як будуються з'єднання між двома таблицями на кількох базах даних? (Корисний приклад коду тут).
  • Чи є якісь спеціальні стратегії відстеження, які таблиці є в якій базі даних?
  • Чи повинен код програми знати, що одна чи кілька баз даних поширюються на декілька серверів? Якщо ні, то на якому рівні фільтруються запити?
  • Коли настав час вийти за межі налаштування 1 сервер бази даних / 1? Наскільки звичайно це потрібно робити?

На це питання краще відповісти Адміністратори бази даних . Нічого насправді в цьому теж немає, тому я просто перевірятиму модники DBA. Якщо це підходить там, ви хотіли б, щоб він мігрував?
Адам Лір

@AnnaLear - я думаю, що це залежить від відповідей. На даний момент мене більше цікавить додаток цього питання, тому наразі я думаю, що тут може бути краще.
VirtuosiMedia

@AnnaLear ack, погодьтеся з ОП, то якщо вони хочуть конкретний код програми.
jcolebrand

Відповіді:


13

Гаразд, розбимо його:

  • Як будуються з'єднання між двома таблицями на кількох базах даних? (Корисний приклад коду тут).

Це досить просто. Об'єкти SQL містять місця від однієї до чотирьох конвенцій іменування:

Ім'я сервера.дадабази.менне ім'я.таблетки

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

Select a.*,b.* from 
tableA a inner join 
tableB b on a.col1=b.col1

Якщо одна з ваших таблиць знаходиться в іншій базі даних, і обидві використовують схему за замовчуванням для своїх баз даних, ви просто додасте базу даних до другої таблиці:

Select a.*,b.* from 
tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Якщо ви знаходитесь у третій базі даних, відрізняється від будь-якої з запитів, ви використовуєте обидва імена бази даних явно:

Select a.*,b.* from 
databaseD..tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Якщо ви користуєтесь різними схемами та / або власниками, ви можете додати їх у:

Select a.*,b.* from 
databaseD.john.tableA a inner join 
databaseC.accounting.tableB b on a.col1 = b.col1

І нарешті, якщо ви дуже обережно ставитесь до цього і маєте дуже вагомі причини, ви можете приєднатися до (зазвичай невеликої) таблиці на іншому сервері:

Select a.* from 
databaseD.john.TableA a inner join 
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
  • Коли настав час вийти за межі налаштування 1 сервер бази даних / 1? Наскільки звичайно це потрібно робити? Чи є якісь спеціальні стратегії відстеження, які таблиці є в якій базі даних?

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

Отже, щоб відповісти на ваше друге запитання спочатку, оскільки у вас, як правило, є причина у наявності окремих баз даних, це може бути досить очевидно з того, щоб знати дизайн вашої системи, де щось є.

Про те, коли / чому потрібно вийти за межі єдиної бази даних. Зазвичай це поєднання правил бізнесу, політики та / або технічних причин.

Наприклад, там, де я працюю, ми маємо 16 баз даних, що поширюються на 4 сервери. У нас є MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Наведіть кілька прикладів того, чому вони різні:

  • FinancialDB, конфіденційна інформація
  • База даних DB, специфічні різні вимоги до зберігання та відновлення
  • ReferenceDB, низька транзакція, висока читання
  • ReportingDB, дуже високо зчитуваний, потребує відновлення / тиражування в різних інших середовищах, на відміну від багатьох інших даних
  • StagingDB, нічого постійного, просто посилений темпдб, над яким ми маємо більше контролю
  • MainDB, інтерфейси з усіма іншими БД, але потребує диференціальних резервних копій, так що ... ми розділили
  • Таблиці HighVolumeTransaction (які є відносно перехідними) до власних БД, щоб зберегти розумний розмір резервної копії.
  • Архів, безліч одних і тих же даних з Main та Reporting, але з більш тривалими термінами зберігання та складнішими запитами, що копаються вглиб даних. Якщо це все-таки поєднувалося з Main / Reporting, це призведе до погіршення нашої системи.

Чи потрібно знати код програми, що одна чи більше баз даних поширюються на декілька серверів? Якщо ні, то на якому рівні фільтруються запити?

У широкому сенсі вони, мабуть, так і роблять. Як мінімум вони повинні знати, на який сервер вони вказують у рядку підключення до бази даних. Обробка, звітність, основна тощо.

Звідти їм потрібен контекст бази даних для виконання під. Як правило, це було б найбільш використовуваним для програми, можливо навіть оригінальним з однієї бази даних / одного серверного дня програми. У МОЖЛИВИМО додаток явно перемикає контекст бази даних під час кожного дзвінка, але це дуже важко налаштувати базу даних, не змінюючи додаток.

Звичайний (або принаймні МОЙ звичайний) підхід - це завжди доступ через одну або, можливо, дві основні бази даних.

Потім створіть перегляди в інших базах даних за необхідності в поєднанні з взаємодією з базою даних через збережені процедури.

Отже, для ілюстрації:

Скажімо, ви хочете отримати демографічну інформацію Клієнта, Дані про продажі та Кредитний баланс, і це поширюється на три таблиці спочатку в MainDB.

Отже, ви пишете дзвінок зі свого додатка:

Select c.ClientName, c.ClientAddress, s.totalSales,f.CreditBlance from
Clients c join Sales s on c.clientid = s.clientid inner join AccountReceivable f on 
c.clientid=f.clientid where c.clientid = @clientid

Дивовижно. Однак тепер, коли ми змінюємо стовпець або перейменовуємо / переміщуємо таблицю, вам доведеться оновити код програми. Отже, замість цього ми робимо дві речі:
Створення клієнтів, продажів, перегляди рахунків на рахунку (ви б не використовували Select *, але я демонструю тут)

Use MainDB
GO
Create view v_Clients as select * from Clients
Create view v_Sales as select * from Sales
Create view v_AccountReceivable as select * from AccountReceivable
Go

Тоді ми також створили б збережену процедуру, spGetClientSalesAR

Create proc spGetClientSalesAR @clientID int
as
Select c.ClientName as ClientName, 
       c.ClientAddress as ClientAddress, 
       s.totalSales as TotalSales, 
       f.CreditBlance as CreditBalance 
from
v_Clients c join v_Sales s 
    on c.clientid = s.clientid 
inner join v_AccountReceivable f 
    on c.clientid=f.clientid 
where c.clientid = @clientid

І попросіть ваш додаток так.

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

В крайньому випадку я навіть міг зробити свій старий MainDB лише купою обстріляних зберігаються процедур і поглядів таким чином, що під тими створеними нами переглядами виглядав так:

Create view v_Clients as select * from ServerX.DatabaseY.dbo.Clients
Create view v_Sales as select * from ServerQ.DatabaseP.dbo.Sales
Create view v_AccountReceivable as select * from ServerJ.DatabaseK.dbo.AccountReceivable

І ваш додаток ніколи не дізнається різницю (якщо припустити швидку передачу даних та чітко сформовані дані між іншим).

Очевидно, що це надзвичайно, і я брешу, якби я сказав, що все було заплановано таким чином, але використання збережених процедур / поглядів, навіть якщо ви робите це під час рефакторингу, дозволить вам отримати велику гнучкість, оскільки ваш додаток зростає зі своєї скромної однієї бази даних / одного сервера початок.


TetonSig - Дякую за відповідь. Я не зміг вчасно повернутися до питання, щоб присвоїти вам повну нагороду (я подорожував), але створив нову нагороду за питання, і зможу присвоїти вам це за 24 години.
VirtuosiMedia

Нічого, дякую. Я ціную це. Відповідаючи на запитання, було дуже весело.
TetonSig

5

Основний спосіб, з яким я стикався з декількома серверами баз даних у веб-світі (оскільки це питання позначено PHP), - це налаштування, де була одна база даних "master" (запис), а потім одна чи більше реплікуваних "slave" (read) баз даних . Запис у базу даних виконується проти бази даних 'master'. Вміст цієї бази даних реплікується на "рабовласницькі" сервери майже в режимі реального часу. Запити - особливо інтенсивні звіти - потім запускаються проти однієї з "підлеглих" баз даних, щоб перенести навантаження на ці сервери. Майте на увазі, що саме ця настройка найкраща для програм, які читають багато, але не багато пишуть. Це аж ніяк не єдиний спосіб упорядкувати речі.


3

Як будуються з'єднання між двома таблицями на кількох базах даних? (Корисний приклад коду тут).

Їх немає. Бази даних NoSQL взагалі не "приєднуються", і навіть якби ви могли з'єднати SQL на серверах RDBMS, ви не хотіли б, якщо цінуєте продуктивність (див. Помилки розподілених обчислень ).

Чи є якісь спеціальні стратегії відстеження, які таблиці є в якій базі даних?

У реляційній базі даних / SQL розділення зазвичай проводиться в межах одного сервера / бази даних, використовуючи різні файли, розміщені на різних дисках. Майже за визначенням рішення горизонтального масштабування означає, що всі бази даних мають усі таблиці, і у вас є якесь транзакційне дзеркальне відображення, реплікація або спеціальне рішення можливої ​​консистенції, щоб переконатися, що всі дані потрапляють туди, куди належить.

Якщо ви фактично розділяєте базу даних логічно, а не лише фізично, то відображення, визначені у вашому DAL або ORM, оголосять, які таблиці є в якій базі даних.

Бази даних NoSQL - це сукупність рішень для розділення. Іноді розділяються "таблиці" (або частіше "колекції"). В іншому випадку це "рядки" (або "документи"). У деяких випадках це насправді стовпці , як у базі даних, орієнтованої на стовпці, як HBase. Це повністю залежить від технології, яку ви використовуєте. Єдине, що у них є спільним, - це те, що сам двигун все це відстежує, тому все, що вам потрібно зробити, - це подати запит на документ або рядок.

Звичайно, припускаючи, що ви фактично використовуєте функції загострення, а не просто створюєте купу різних баз даних. Якщо ви робите останнє, то ви самі.

Чи повинен код програми знати, що одна чи кілька баз даних поширюються на декілька серверів? Якщо ні, то на якому рівні фільтруються запити?

Якщо вони різні логічні бази даних, так. Якщо вони розподілені лише фізично, то ні - припускаючи, що або ваша конкретна база даних спочатку підтримує шардинг, або ви використовуєте рішення для балансування навантаження (для баз даних SQL). Також якщо припустити, що всі ваші операції без громадянства; якщо ви хочете горизонтального масштабування, вам доведеться відмовитися від кислоти.

Коли настав час вийти за межі налаштування 1 сервер бази даних / 1? Наскільки звичайно це потрібно робити?

Настав час, коли ви оптимізували все, що можливо, на одному сервері і все ще не можете вичавити достатню продуктивність через обмеження на навантаження вводу / виводу. Якщо вам доведеться задати питання, то ще зарано.

Зауважте, що проблеми з продуктивністю пристойного продукту RDBMS (Oracle, SQL Server) частіше виникають через поганий дизайн, погану індексацію, погані запити, конфлікт блокування тощо; ці вироби можуть масштабувати вертикально до смішної міри. Отже, вам слід розглянути питання про «перехід за межі налаштування 1 сервера баз даних / 1», коли ви абсолютно впевнені, що ваші проблеми з продуктивністю пов'язані з обмеженнями в апаратному забезпеченні, а не лише з використанням проекту / впровадження підпункту.

Або, мабуть, ще одна причина переходу людей на розподілені бази даних полягає в тому, що вони не готові платити багато (або будь-які) гроші за ліцензійні збори і хочуть вирватися з SQL як свідомий вибір для торгівлі низькою вартістю за збільшення складності додатків. Цілком обґрунтована причина, якщо ви запускаєте програмне забезпечення, але зазвичай не застосовуєтесь у корпоративному секторі.


+1 - Я насправді не розглядав NoSQL, але це все одно корисно. Спасибі.
VirtuosiMedia

1

Існує три основні типи конфігурацій реплікації для баз даних:

  • Господар-раб
  • Майстер-Майстер
  • Консенсус

Приклад Master-Slave: майстер MySQL + раби MySQL, MongoDB

Приклад Master-Master: CouchDB, Cassandra, Riak

Приклад консенсусу: ScalienDB

...назвати декілька.

Вони мають різні характеристики. Конфігурації master-slave дозволяють веденим вузлам наздоганяти ведучого за їх максимальною швидкістю при дуже швидкому обслуговуванні запитів на читання, тоді як головний сервер відповідає за цілісність даних. Оскільки всі записи йдуть до ведучого, ніколи не виникає суперечок із блокуванням, оскільки один відносно повільний сценарій блокує багатьох читачів, але, з іншого боку, рабовласницькі сервери зрештою несуперечливі, і ви не отримуєте гарантій ізоляції транзакцій, які б у вас були від читання лише від майстра. (подальше читання; ACID vs BASE, рівні ізоляції транзакцій, реплікація бази даних, MVCC / ізоляція: знімок, транзакційна реплікація)

Майстер-Майстер завжди дозволяє пише, так що вам доведеться кілька влади на те, що це правда. Це може бути або не бути проблемою, залежно від того, що робить ваша програма, але якщо ви пишете суперечливі дані, ви можете отримати кілька результатів наступного разу, коли прочитаєте той ключ / рядок / стовпець, який вам доведеться об'єднати з логікою програми та зберегти назад до бази даних. (подальше читання: теорема CAP, реплікація CouchDB, реплікація Riak, послідовне хешування, Bitcask & StormDB, Quorum- w / MongoDB про розбиття мережі, стратегії вирішення злиття)

Бази даних, що базуються на консенсусі, з реплікацією через вузли, такі як Scalien, завжди будуть послідовними при записі, але ціною обміну декількома повідомленнями перед тим, як ACKing писати. Це не є великою проблемою, якщо у вас швидка Ethernet і вам не потрібно записувати на диск перед ACKing, що вам не знадобиться, якщо ваші мінімум три сервери знаходяться на різних серверних стійках з окремими джерелами живлення (один гине; інші два впевнені, що вони збереглися на диску). (подальше читання; PAXOS, PAXOS COMMIT, двофазна комісія з розподіленими транзакціями, трифазна комісія)

Інше подальше читання: (книга: "Елементи розподілених обчислень", векторні годинники, вектори версій, матричні вектори, логічні годинники, алгоритм хлібопекарських виробів, інтервальний годинник, актори та реактивне програмування та реактори, операційна пам'ять програмного забезпечення, трансактори, AKKA, Stact, помилки розподілених обчислень, протоколи пліток, розширення антисантропійного протоколу пліток Кассандри, розподілені хеш-таблиці, документи про об'єднання даних у розподіленому налаштуванні, архітектура ZooKeeper, презентація InfoQ на "асинхронному протоколі", архітектура HBase, папір MapReduce, папір Amazon Dynamo що запустив усі матеріали NoSQL, черга, кластеризація rabbitmq з високою доступністю)

Я сподіваюся, що я дав трохи їжі для роздумів :). Ви можете піти за мною на Twitter @henrikfeldt, якщо ви хочете твіти про цей матеріал.


1

Гаразд, ось ось ще одна точка зору на масштабованість.

Давайте обговоримо, що це означає, щоб речі були даними, що це означає мати поведінку та що означає мати логіку програми.

Зазвичай, коли хтось заходить у землю підприємств та подібні програми, людина може зазнати ідеї багатошаровості. Звичайно, багатошаровість є повсюдно в комп’ютерах, таких як мережевий стек (модель ISO), або графіка (Photoshop), або SOA (служби можуть викликати братів і сестер або дітей, але ніколи батьків).

Однак специфічний тип шару, який зловживають, незважаючи на те, що коли-небудь, є "GUI", "Business Logic Layer", а потім "Layer Data Layer". Я маю на увазі, так, ідея в принципі хороша, як і комунізм в принципі, але насправді це не так.

Давайте розберемося, чому. Аргумент, який я буду використовувати, стосується зв'язку; точки з одного шару, які торкаються точок на іншому шарі. Кожного разу, коли ви починаєте створювати n-ярусний додаток, який є шаруватим, у режимі за замовчуванням для підприємств, у який входять люди, вони створюють багато точок дотику між шарами.

По своїй суті ідея полягає в тому, що шари взаємозамінні; але їх немає! Чому? Через все з’єднання на сайті виклику.

Натомість погляньте, чому мережа роз’єднана! Тому що інтерфейс - це байт-потік над одним покажчиком файлу, який вказує на відкритий сокет! Усі шари в моделях ISO схожі на те, що модель дизайну під назвою "ланцюжок відповідальності" полягає в орієнтації на об'єкт! Кожен шар обертає нижній шар, не знаючи семантики даних у цьому нижньому шарі.

Оскільки пакет даних прямує до Ethernet та сирих електричних сигналів внизу, він постійно обертається шарами, які знають лише власну специфічну оболонку повідомлення, власну специфічну "групу байтів", яку він може надсилати; і більше нічого. Не потрібно змінювати шляхи викликів залежно від вмісту пакета.

Контрастуйте це з n-ярусом, коли вам доведеться змінювати шлях виклику в шарах додатків під час "виклику", який проходить ваші шари на шляху до бази даних - наприклад, "клієнти із золота" поліморфно є набором "звичайних клієнтів" і тому, оскільки ми використовуємо «таблицю за підкласом», нам потрібно знати про це тепер, коли дані (сутність) переходять по шарах; як у так званому "шарі бізнес-логіки", так і в рівні даних, який фактично робить економію.

Це ні масштабується, ні є оптимальним з точки зору обчислень.

Чому це не масштабується? Тому що архітектура поєднана, і ви все ще знаходитесь в тому ж старому БД, який ви намагалися масштабувати до багатьох вузлів! Але, оскільки для цього вам потрібна ACID, для цього і третього об'єкта (об’єкта даних) вам потрібно мати їх у єдиній базі даних, яка здійснює транзакції!

Правильно, так що з цією гнівкою не виходить; які ще способи існують?

Ну, є ненависна абревіатура під назвою "SOA", тобто архітектура, орієнтована на сервіс. Звичайно, Томаш Ерлс у світі запропонував би вам реалізувати всі свої шари, але замість них XML та SOAP.

З усіх перерахованих вище причин, це неправильний шлях, тому що ви з'єднаєтеся з цими проксі-серверами XML так, як ви приєднаєтесь до шарів програми, як пояснено вище.

Натомість використовуйте обмін повідомленнями, і нехай все, що реалізує функціональність, слухайте їх. Тоді ваша сервісна поверхня стає списком повідомлень, які ви можете надіслати, і ви не зв’язали свої операції зі своїм фасадом обслуговування; і вам навіть не потрібно знати, який додаток або кінцева точка реалізують ці операції, адже все, що ви робите, - це публікація повідомлення про те, що якийсь інший механізм маршрутизації спрямовуватиметься до потрібного споживача!

Оскільки ви відокремили фасади послуг від фактичних операцій, які ви хочете виконати, тепер ви можете додати кілька служб; насправді, так це робить Netflix. Погляньте на ці презентації: http://www.slideshare.net/adrianco/global-netflix-platform . http://www.slideshare.net/adrianco/global-netflix-platform . Вони гарні!


0

Існує нова база даних SQL (ACID) у бета-версії, яка, як стверджується, має властивості еластичного масштабування. Зараз діє безкоштовна бета-програма, і я пропоную вам поглянути, вона називається NuoDB.

Мабуть, він легко перевершує MySQL навіть на одній машині з потоком, але щасливо масштабується до 70+ випадків у певних орієнтирах.


Єдина нитка? Як це тоді відповідний орієнтир?
Генрік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.