Вертикальне та горизонтальне масштабування. Функціональність інформаційної системи для управління логістикою мережевої роздрібної компанії

До довготривалої інформаційної системи обов'язково пред'являється вимога масштабованості (~ зміна розмірів), тобто деякого зростання без переписування всього програмного коду та заміни всього обладнання.

Система може масштабуватися за трьома напрямками: 1) розмір (додаткові користувачі, ресурси), 2) протяжність у географічному сенсі, 3) адміністрування (у багатьох адміністративно незалежних організаціях).

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

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

Розмір бази даних. Зі збільшенням БД до десятків та сотень гігабайт операції резервування, відновлення та завантаження стануть вузьким місцем.

Складність транзакцій. Розробники додатків роблять їх дедалі «розумнішими», полегшуючи користувачам роботу, даючи можливість аналізувати дані. Але при цьому експоненційно зростає кількість взаємозв'язків даних, внаслідок чого, по-перше, зростає складність написання, тому підвищується ймовірність помилок. А, по-друге, при виконанні такої транзакції системі необхідно переробити велику кількість даних, що може виявитися неможливим для даної потужності процесора, обсягу оперативної пам'яті і т.п. Що, у свою чергу, вимагає написання якихось особливих алгоритмів вивантаження даних, кешування тощо.

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

Розширювані системи можуть використовувати один (або обидва!) принцип нарощування потужності обчислювальної системи: мультипроцесування, кластерна технологія.

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

На шляху масштабованості стоять

Централізовані служби,

Централізовані дані,

Централізовані алгоритми.

Централізована служба передбачає, що деяка служба (програма) перебуває лише одному комп'ютері. Якщо звернення до цієї служби від різних клієнтів відбуваються не часто і не одночасно, то це цілком прийнятне рішення. В іншому випадку така служба буде вузьким місцем системи. Для того, щоб централізована служба викликала менше проблем, потрібно використовувати швидкісні лінії зв'язку, а комп'ютер, на якому розташована ця служба, повинен бути досить швидким, мати оперативну пам'ять та буфери достатнього обсягу. Безперечна перевага такої служби полягає в тому, що її легко оновлювати. Якщо служба є процес, що вимагає своєї роботи великих обчислювальних ресурсів, може виявитися набагато вигідніше забезпечити наявність цих ресурсів тільки одному комп'ютері, а чи не на безлічі клієнтів. Але, з іншого боку, часто за краху централізованої служби система загалом втрачає працездатність.



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

У системі, що масштабується, пропонується застосовувати децентралізовані служби. Цього можна досягти двома шляхами: або реплікувавши (скопіювавши) службу на кілька комп'ютерів, або (якщо це можливо), розбивши службу на окремі завдання, рознести відповідні фрагменти по різних комп'ютерах. Приклад: у досить великій локальній мережі рекомендується DHCP сервер (що займається видачею в оренду IP-адрес), сховище профілів, що переміщуються, розташовувати не на контролері домену, а на окремому комп'ютері (звичайно ж, включеному в потрібний час).

Часто централізована служба пов'язані з централізованими даними. Централізовані дані часто легше захищати (простіше влаштовувати резервне копіювання). Але обсяг таких даних може бути настільки великим, що не вистачить ніяких розумних обчислювальних потужностей. У централізованих сховищах часто ускладнюється пошук необхідних даних. З одного боку, час пошуку зростає у разі зростання сховища. З іншого, у разі централізованого сховища зростає набір ознак – параметрів пошуку, оскільки з даними працює багато різних завдань. Для централізованих даних дуже важливо робити архівні копії, щоб зменшити можливі втрати при поломці централізованого сховища. Приклад централізованих даних – сервер бази даних (MY SQL, MS SQL тощо).

Система, що масштабується, повинна працювати з децентралізованими даними. Хороший приклад – служба DNS, яка зіставляє символьному імені мережного ресурсу його IP-адресу. Архітектура дерева DNS-сервера дозволяє розділити інформацію на фрагменти, кожен з яких підтримується одним сервером. Між серверами встановлено зв'язок та визначено протокол їхньої взаємодії. Забезпечення цього – ціна застосування децентралізованого сховища. Децентралізоване сховище має деяку цікаву властивість: неоднаковий час доступу до інформації. Для того, щоб згладити ці відмінності, тобто з метою прискорення принаймні повторного доступу до віддалених даних DNS сервера застосовують кешування інформації. Але ви пам'ятаєте, що кешування призводить до проблеми суперечливості даних. Проблеми, що виникають при децентралізації даних, основна з яких – суперечливість даних на різних комп'ютерах, розглянемо трохи згодом. Розберемо 13 моделей несуперечності.

Централізований алгоритм теж погано для розподіленої системи. Алгоритм вважатимуться централізованим, якщо його закінчення, тобто прийняття рішення, йому потрібна повна інформація, отримана від безпосередніх джерел. Згадаймо алгоритми маршрутизації, вивчені у курсі «Інформаційні мережі». Розглянемо як приклад централізованого алгоритму «протокол стану каналів». У цьому алгоритмі передбачається, що складова таблиця маршрутизатор пов'язується з кожним маршрутизатором. Це призводить до величезної кількості службових пакетів, що передаються. Цей алгоритм вимогливий до ресурсів маршрутизатора і до мережі, хоча він виявляється слабко чутливим до зникнення маршрутизатора. Алгоритм «протокол вектора відстаней» не належить до централізованих алгоритмів, т.к. для ухвалення рішення (побудови своєї таблиці маршрутизації) маршрутизатору потрібно зв'язатися лише з сусідами. Цей алгоритм набагато менше займає мережу, але може прийняти неправильне рішення при зникненні маршрутизатора (проблема зростання відстані нескінченно)

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

Приховування часу очікування часто реалізується за рахунок асинхронного зв'язку, при якому процес, що запросив віддалену службу, займається деякою роботою (не залежною від очікуваної відповіді), доки не прийде відповідь. Для того щоб реалізувати це, організується багатопоточний додаток, один з потоків (ниток) якого у разі запиту блокується і чекає відповіді, тобто працює з віддаленим сервісом синхронно, а потоки, що залишилися, працюють асинхронно, тобто продовжують виконання. Але влаштувати асинхронне виконання не завжди можливе, наприклад, при інтерактивній роботі користувача з віддаленою базою даних. У такому разі рекомендується влаштувати принаймні часткову перевірку даних на стороні клієнта за допомогою скриптів, скоротивши тим самим кількість звернень до віддаленої бази даних і, отже, зменшивши час очікування клієнта.

Друга важлива технологія масштабування – розподіл. Ми вже згадували про розподілену службу DNS. Важливий аспект реалізації розподілу даних - ім'я. Проблема полягає в тому, що імена повинні бути унікальними, тобто потрібно тим чи іншим способом організувати простір імен. Так само, як і для файлів, кожен інтернет-об'єкт має мати унікальне повне ім'я, що включає імена DNS серверів від об'єкта до кореня DSN.

І, зрештою, третя технологія – реплікація. При реплікації всі дані, що спільно використовуються, або деякі їх частини копіюються на кілька комп'ютерів. В результаті цього дані можна наблизити до користувача, зменшивши тим самим час доступу, знизивши навантаження на комп'ютери, що підтримують сховище. Ціна такого рішення – необхідність забезпечення несуперечності даних. Слід розрізняти реплікацію та кешування. Реплікація відбувається з ініціативи сервера даних (власника), а кешування – з ініціативи клієнта (користувача).

Якщо ми маємо справу з кешуванням, клієнт (наприклад, Internet Explorer) повинен самостійно стежити за актуальністю даних. Механізми, що застосовуються для цього: а) запити на оновлення даних через певний час; б) запити про актуальність (незмінність на сервері). У першому випадку може передаватися незмінене це, що зайве завантажує мережу. А в другому спочатку клієнт з'ясовує, чи змінилися дані, і лише у разі їх зміни надсилає запит на пересилання даних. Очевидно, якщо дані змінюються рідко, то краще використовувати другий метод, інакше – перший. Тепер – кілька слів про несуперечність. У зв'язку з тим, що в розподіленій системі можуть бути різні клієнти, яким потрібен різний ступінь «свіжості» для різних даних, різні дані мають різний час оновлення та інші характеристики, а передача даних це – дороге задоволення, то в різних випадках будуть потрібні різні методи забезпечення несуперечності.

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

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

У системі з поганою масштабованістю додавання ресурсів призводить лише до незначного підвищення продуктивності, а з деякого «порогового» моменту додавання ресурсів не дає корисного ефекту.

Вертикальне та

Вертикальне масштабування

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

Горизонтальне масштабування

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

Показники

також

Примітки

Посилання

Масштабованість - здатність пристрою збільшувати свої
можливості
шляхом нарощування числа функціональних блоків,
виконують одні та
ті самі завдання.
Глосарій.ru

Зазвичай про масштабування починають думати тоді, коли один
сервер не справляється з покладеною на нього роботою. З чим саме він не
справляється? Робота будь-якого web-сервера за великим рахунком зводиться до основного
заняття комп'ютерів - обробці даних. Відповідь на HTTP (або будь-який інший) запит
передбачає проведення деяких операцій над деякими даними. Відповідно,
у нас є дві основні сутності - це дані (що характеризуються своїм обсягом) і
обчислення (що характеризуються складністю). Сервер може не впоратися зі своєю
роботою через великий обсяг даних (вони можуть фізично не поміщатися на
сервері), або через велику обчислювальну навантаження. Мова тут йде,
звичайно, про сумарне навантаження - складність обробки одного запиту може бути
невелика, але велика кількість може «завалити» сервер.

В основному ми говоритимемо про масштабування на прикладі
типового зростаючого web-проекту, проте описані тут принципи підходять і для
інших сфер застосування. Спочатку ми розглянемо архітектуру проекту та просте
розподіл її складових частин на кілька серверів, а потім поговоримо про
масштабування обчислень та даних.

Типова архітектура сайту

Життя типового сайту починається з дуже простої архітектури
- це один web-сервер (зазвичай у його ролі виступає Apache),
який займається всією роботою з обслуговування HTTP-запитів,
вступників від відвідувачів. Він віддає клієнтам так звану «статику», то
є файли, що лежать на диску сервера і не потребують обробки: картинки (gif,
jpg, png), аркуші стилів (css), клієнтські скрипти (js, swf). Той самий сервер
відповідає на запити, що вимагають обчислень - зазвичай це формування
html-сторінок, хоча іноді «на льоту» створюються і зображення та інші документи.
Найчастіше відповіді такі запити формуються скриптами, написаними на php,
perl або інші мови.

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

Вирішення цієї проблеми - розподіл роботи з обробки
запитів між двома різними програмами – тобто. поділ на frontend та
backend. Легкий frontend-сервер виконує завдання щодо віддачі статики, а інші
запити перенаправляє (проксує) на backend, де виконується формування
сторінок. Очікування повільних клієнтів також бере на себе frontend, і якщо він використовує
мультиплексування (коли один процес обслуговує кількох клієнтів - так
працюють, наприклад, nginx або lighttpd), то очікування практично нічого не
стоїть.

З інших компонентів сайту слід зазначити базу даних,
якої зазвичай зберігаються основні дані системи - тут найпопулярніші
безкоштовні СУБД MySQL та PostgreSQL. Часто окремо виділяється сховище
бінарних файлів, де містяться картинки (наприклад, ілюстрації до статей
сайту, аватари та фотографії користувачів) або інші файли.

Таким чином, ми отримали схему архітектури, що складається з
кількох компонентів.

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

Шляхи подальшого поділу компонентів теж зрозумілі - наприклад, можна винести frontend на окремий сервер. Але зазвичай frontend
вимагає мало системних ресурсів і на цьому етапі його винесення не дасть суттєвого
приросту продуктивності. Найчастіше сайт упирається у продуктивність
скриптів – формування відповіді (html-сторінки) займає надто довгий час.
Тому наступним кроком зазвичай є масштабування backend-сервера.

Розподіл обчислень

Типова ситуація для зростаючого сайту - база даних вже
винесена на окрему машину, поділ на frontend та backend виконано,
проте відвідуваність продовжує збільшуватися і backend не встигає обробляти
запити. Це означає, що нам необхідно розподілити обчислення на кілька
серверів. Зробити це просто – достатньо купити другий сервер і поставити на
його програми та скрипти, необхідні для роботи backend.
Після цього потрібно зробити так, щоб запити користувачів розподілялися
(Балансувалися) між отриманими серверами. Про різні способи балансування
буде сказано нижче, поки зазначимо, що зазвичай цим займається frontend,
який налаштовують так, щоб він рівномірно розподіляв запити між
серверами.

Важливо, щоб усі backend-сервери були здатні правильно
відповідати на запити. Зазвичай для цього необхідно, щоб кожен із них працював з
одним і тим самим актуальним набором даних. Якщо ми зберігаємо всю інформацію в єдиній
базі даних, то СУБД сама забезпечить спільний доступ та узгодженість даних.
Якщо деякі дані зберігаються локально на сервері (наприклад, php-сесії
клієнта), то варто подумати про перенесення їх у загальне сховище, або більше
складний алгоритм розподілу запитів.

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

  • Синхронізація на рівні програми. В цьому випадку наші
    скрипти самостійно записують зміни на всі копії бази даних (і самі несуть
    відповідальність за правильність даних). Це не найкращий варіант, оскільки він
    вимагає обережності під час реалізації і дуже нестійкий до помилок.
  • Реплікація- тобто автоматичне тиражування
    змін, зроблених одному сервері, на всі інші сервера. Зазвичай при
    використання реплікації зміни записуються завжди на один і той же сервер - його називають master, а інші копії - slave. У більшості СУБД є
    вбудовані чи зовнішні засоби для організації реплікації. Розрізняють
    синхронну реплікацію - у цьому випадку запит на зміну даних буде очікувати,
    поки дані будуть скопійовані на всі сервери, і лише потім завершиться успішно - і асинхронну - в цьому випадку зміни копіюються на slave-сервера з
    затримкою, проте запит на запис завершується швидше.
  • Multi-masterреплікація. Цей підхід аналогічний
    попередньому, проте тут ми можемо проводити зміну даних, звертаючись не до
    одному певному серверу, а до будь-якої копії бази. При цьому зміни
    синхронно чи асинхронно потраплять на інші копії. Іноді таку схему називають
    терміном "кластер бази даних".

Можливі різні варіанти розподілу системи на серверах.
Наприклад, у нас може бути один сервер бази даних і кілька backend (дуже
типова схема), або навпаки - один backend і кілька БД. А якщо ми масштабуємо
і backend-сервера, і базу даних, можна об'єднати backend і копію бази на
одній машині. У будь-якому випадку, як тільки у нас з'являється кілька екземплярів
будь-якого сервера, виникає питання, як правильно розподілити між ними
навантаження.

Методи балансування

Нехай ми створили кілька серверів (будь-якого призначення - http, база даних тощо), кожен з яких може обробляти запити. Перед
нами постає завдання – як розподілити між ними роботу, як дізнатися, на якій
сервер надсилати запит? Можливі два основні способи розподілу запитів.

  • Балансуючий вузол. У цьому випадку клієнт надсилає запит на один
    фіксований, відомий йому сервер, а той уже перенаправляє запит на один із
    робочих серверів Типовий приклад - сайт з одним frontend і кількома
    backend-серверами, на які проксуються запити. Однак «клієнт» може
    перебувати і всередині нашої системи - наприклад, скрипт може надсилати запит до
    проксі-сервер бази даних, який передасть запит одному з серверів СУБД.
    Сам балансуючий вузол може працювати як на окремому сервері, так і на одному
    із робочих серверів.

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

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


Зрозуміло, є й комбінації цих підходів. Наприклад,
такий відомий спосіб розподілу навантаження, як DNS-балансування, заснований на
тому, що при визначенні IP-адреси сайту клієнту видається
адресу одного з кількох однакових серверів. Таким чином, DNS виступає в
ролі балансуючого вузла, якого клієнт отримує «розподіл». Однак
сама структура DNS-серверів передбачає відсутність точки відмови за рахунок
дублювання - тобто поєднуються переваги двох підходів. Звичайно, у такого
способу балансування є і мінуси - наприклад, таку систему складно динамічно
перебудовувати.

Робота із сайтом зазвичай не обмежується одним запитом.
Тому при проектуванні важливо зрозуміти, чи можуть бути послідовні запити.
клієнта бути коректно оброблені різними серверами, або клієнт має бути
прив'язаний до одного серверу під час роботи з сайтом. Це особливо важливо, якщо на
сайті зберігається тимчасова інформація про сесію роботи користувача (у цьому
у випадку також можливий вільний розподіл - проте тоді необхідно зберігати
сесії загалом всім серверів сховище). «Прив'язати» відвідувача до
конкретному серверу можна за його IP-адресою (яка, однак, може змінюватися),
або за cookie (у яку заздалегідь записано ідентифікатор сервера), або навіть
просто перенаправивши його на потрібний домен.

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

Розподіл даних

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

  • Вертикальний розподіл(vertical partitioning) - у найпростішому випадку
    є винесення окремих таблиць бази даних на інший сервер. При
    цьому нам потрібно змінити скрипти, щоб звертатися до різних серверів за
    різними даними. У межах ми можемо зберігати кожну таблицю окремому сервері
    (хоча практично це навряд чи буде вигідно). Очевидно, що за такого
    розподіл ми втрачаємо можливість робити SQL-запити, що об'єднують дані з
    двох таблиць, що знаходяться на різних серверах. За потреби можна реалізувати
    логіку об'єднання у додатку, але це буде настільки ефективно, як у СУБД.
    Тому при розбитті бази даних необхідно проаналізувати зв'язки між таблицями,
    щоб розносити максимально незалежні таблиці.

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

  • Горизонтальний розподіл(horizontal partitioning) - полягає в
    розподіл даних однієї таблиці по кількох серверах. Фактично, на
    на кожному сервері створюється таблиця такої ж структури, і в ній зберігається
    певна частина даних. Розподіляти дані по серверах можна за різними
    критеріям: за діапазоном (записи з id< 100000 идут на сервер А, остальные - на сервер Б), по списку значений (записи типа «ЗАО» и «ОАО» сохраняем на сервер
    А, решта - на сервер Б) або за значенням хеш-функції від деякого поля
    запис. Горизонтальне розбиття даних дозволяє зберігати необмежене
    кількість записів, проте ускладнює вибірку. Найбільш ефективно можна обирати
    записи, тільки коли відомо, на якому сервері вони зберігаються.

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

Як згадувалося вище, крім бази даних сайту часто потрібно
сховище для бінарних файлів. Розподілені системи зберігання файлів
(Фактично, файлові системи) можна розділити на два класи.

  • Працюючі на рівні операційної системи. При цьому для
    програми робота з файлами в такій системі не відрізняється від звичайної роботи з
    файлами. Обмін інформацією між серверами перебирає операційна система.
    Як приклади таких файлових систем можна навести давно відоме
    сімейство NFS або менш відому, але сучаснішу систему Lustre.
  • Реалізовані на рівні програмирозподілені
    сховища мають на увазі, що роботу з обміну інформацією провадить саме
    додаток. Зазвичай функції роботи зі сховищем для зручності винесені в
    окрему бібліотеку. Один із яскравих прикладів такого сховища – MogileFS, розроблена
    творцями LiveJournal. Інший поширений приклад - використання
    протоколу WebDAV і сховища, що його підтримує.

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

Висновки

Підсумовуючи сказане, сформулюємо висновки у вигляді коротких тез.

  • Дві основні (і пов'язані між собою) завдання масштабування - це розподіл обчислень та розподіл даних
  • Типова архітектура сайту має на увазі поділ ролей і
    включає frontend, backend, базу даних та іноді сховище файлів
  • При невеликих обсягах даних та великих навантаженнях застосовують
    дзеркаловання бази даних - синхронну або асинхронну реплікацію
  • При великих обсягах даних необхідно розподілити базу даних – розділити
    її вертикально чи горизонтально
  • Бінарні файли зберігаються у розподілених файлових системах
    (реалізованих на рівні ОС або у додатку)
  • Балансування (розподіл запитів) може бути рівномірним або
    з розподілом по функціоналу; з балансуючим вузлом, або за клієнта
  • Правильне поєднання методів дозволить тримати будь-які навантаження;)

Посилання

Продовжити вивчення цієї теми можна на цікавих англомовних сайтах та блогах.

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

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

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

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

вертикальним масштабуванням , а другий, що виражається у збільшенні кількості мережевих комп'ютерів (серверів)

розподіленої системи –горизонтальним масштабуванням.

Географічна масштабованість. Здатність системи зберігати свої основні характеристики, такі як продуктивність, простота та зручність використання, при територіальному рознесенні її компонентів від локальнішого взаємного розташування до більш розподіленого.

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

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

централізованих служб, даних та алгоритмів . А саме, багато служб централізовано в тому сенсі, що вони реалізовані у вигляді єдиного процесу і можуть виконуватися лише на одному комп'ютері (сервері). Проблема такого підходу полягає в тому, що при збільшенні кількості користувачів або програм, які використовують цю службу, сервер, на якому вона виконується, стане вузьким місцем і обмежуватиме загальну продуктивність. Якщо навіть припустити можливість необмеженого збільшення потужності такого сервера (вертикальне масштабування), тоді обмежуючим фактором стане пропускна здатність ліній зв'язку, що з'єднують його з іншими компонентами розподіленої системи. Аналогічно, централізація даних вимагає централізованої обробки, призводячи до тих самих обмежень. Як приклад переваг децентралізованого підходу можна навести службу доменних імен (англ. Domain Name Service, DNS ), яка на сьогоднішній день є однією з найбільших розподілених систем іменування. Служба DNS використовується в першу чергу для пошуку IP-адрес по доменному імені та обробляє мільйони запитів з комп'ютерів по всьому світу. При цьому розподілена база даних DNS підтримується за допомогою ієрархії DNS-серверів, взаємодіють за певним протоколом. Якби всі дані DNS централізовано зберігалися на єдиному сервері, і кожен запит на інтерпретацію доменного імені передавався на цей сервер, скористатися такою системою в масштабах усього світу було б неможливо.

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

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

Відсутність знання глобального стану . Як уже було сказано,

централізовані алгоритми мають повну інформацію про стан всієї системи та визначають такі дії, виходячи

з її поточного стану. У свою чергу, кожен процес, що реалізує частину розподіленого алгоритму, має безпосередній доступ лише до свого стану, але не глобального стану всієї системи. Відповідно процеси приймають рішення тільки на основі своєї локальної інформації. Слід зазначити, що інформацію про стан інших процесів у розподіленій системі кожен процес може отримати тільки з повідомлень, що прийшли, і ця інформація може виявитися застарілою на момент отримання. Аналогічна ситуація має місце в астрономії: знання про об'єкт (зірку / галактику), що вивчається, формуються на підставі світлового та іншого електромагнітного випромінювання, і це випромінювання дає уявлення про стан об'єкта в минулому. Наприклад, знання про об'єкт, що знаходиться на відстані п'яти тисяч світлових років, є застарілими на п'ять тисяч років.

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

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

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

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

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

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

Інша складність забезпечення географічної масштабованості полягає в тому, що зв'язок у глобальних мережах за своєю природою ненадійний і взаємодія процесів практично завжди є двоточковим (англ. point-to-point). У свою чергу, зв'язок у локальних мережах є високонадійним і передбачає використання широкомовних повідомлень, що спрощує розробку розподілених додатків. Наприклад, якщо процесу потрібно виявити адресу іншого процесу, що надає певну службу, в локальних мережах йому достатньо розіслати широкомовне повідомлення з проханням для шуканого процесу відгукнутися на нього. Всі процеси отримують та обробляють це повідомлення. Але тільки процес, що надає необхідну службу, відповідає на отримане прохання, вказуючи свою адресу у повідомленні. Вочевидь, подібна взаємодія перевантажує мережу, і його у глобальних мережах неможливо.

Технології масштабування. У більшості випадків складності масштабування виявляються в проблемах з ефективністю функціонування розподілених систем, викликаних обмеженою продуктивністю окремих компонентів: серверів і мережевих з'єднань. Існує кілька основних технологій, що дозволяють зменшити навантаження на кожен компонент розподіленої системи. До таких технологій зазвичай відносять поширення(англ. distribution),

реплікацію (англ. replication) та кешування (англ. caching).

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

кожен файловий сервер обслуговує свій набір файлів із загального адресного простору. Іншим прикладом може бути вже згадувана служба доменних імен DNS, де весь простір DNS-імен розбивається на зони, і імена кожної зони обслуговуються окремим DNS-сервером.

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

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

Кешування покликане як знижувати навантаження на компоненти розподіленої системи, а й дозволяє приховувати від користувача затримки комунікації при зверненні до віддалених ресурсів. Подібні технології, що приховують затримки комунікації, є важливими для досягнення географічної масштабованості системи. До них, зокрема, ще можна віднести механізми асинхронного зв'язку (англ. asynchronous communication), в яких клієнт не блокується при зверненні до віддаленої служби, а отримує можливість продовжити свою роботу відразу після звернення. Пізніше, коли буде отримано відповідь, клієнтський процес зможе перерватися та викликати спеціальний обробник для завершення операції.

Однак асинхронний зв'язок застосовується не завжди. Наприклад, в інтерактивних програмах користувач змушений очікувати реакції системи. У таких випадках можна скористатися технологіями перенесення коду, коли частина коду програми завантажується на бік клієнта і виконується локально для забезпечення швидкого відгуку на дії користувача. Перевага подібних рішень полягає в тому, що вони дозволяють скоротити кількість мережевих взаємодій та знизити залежність роботи програми від випадкових затримок обміну повідомленнями через мережу. В даний час перенесення коду широко використовується в Інтернеті у формі аплетів Java та Javascript.

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

Почнемо?

Для початку має сенс визначитися з тим, про що ми взагалі говоритимемо. У цьому контексті перед веб-додатком ставляться три основні цілі:

  • масштабованість- здатність своєчасно реагувати на безперервне зростання навантаження та непередбачені напливи користувачів;
  • доступність- надання доступу до програми навіть у разі надзвичайних обставин;
  • продуктивність- навіть найменша затримка завантаження сторінки може залишити негативне враження у користувача.

Основною темою розмови буде, як не важко здогадатися, масштабованість, але й інші цілі не думаю, що залишаться осторонь. Відразу хочеться сказати пару слів про доступність, щоб не повертатися до цього пізніше, маючи на увазі як "звісно ж": будь-який сайт так чи інакше прагне до того, щоб функціонувати максимально стабільно, тобто бути доступним абсолютно всім своїм потенційним відвідувачам в кожен момент часу, але часом трапляються будь-які непередбачені ситуації, які можуть спричинити тимчасову недоступність. Для мінімізації потенційної шкоди доступності програми необхідно уникати наявності компонентів у системі, потенційний збій в яких призвів би до недоступності будь-якої функціональності або даних (або хоча б сайту в цілому). Таким чином, кожен сервер або будь-який інший компонент системи повинен мати хоча б одного дублера (не важливо в якому режимі вони будуть працювати: паралельно або один "підстраховує" інший, перебуваючи при цьому в пасивному режимі), а дані повинні бути репліковані як мінімум у двох примірниках (причому бажано не лише на рівні RAID, але в різних фізичних машинах). Зберігання кількох резервних копій даних десь окремо від основної системи (наприклад на спеціальних сервісах чи окремому кластері) також допоможе уникнути багатьох проблем, якщо щось піде негаразд. Не варто забувати і про фінансову сторону питання: підстрахування на випадок збоїв потребує додаткових суттєвих вкладень в обладнання, які мають сенс намагатися мінімізувати.

Масштабованість прийнято розділяти на два напрями:

Вертикальна масштабованістьЗбільшення продуктивності кожного компонента системи з метою підвищення загальної продуктивності. Горизонтальна масштабованістьРозбиття системи на більш дрібні структурні компоненти та рознесення їх по окремих фізичних машинах (або їх групах) та/або збільшення кількості серверів, що паралельно виконують одну і ту ж функцію.

Так чи інакше, при розробці стратегії зростання системи доводиться шукати компроміс між ціною, часом розробки, підсумковою продуктивністю, стабільністю та ще масою інших критеріїв. З фінансової точки зору вертикальна масштабованість є далеко не найпривабливішим рішенням, адже ціни на сервери з великою кількістю процесорів завжди зростають практично експонентно щодо кількості процесорів. Саме тому найбільш цікавий горизонтальний підхід, оскільки саме він використовується в більшості випадків. Але й вертикальна масштабованість часом має право на існування, особливо в ситуаціях, коли основну роль відіграє час і швидкість вирішення задачі, а не фінансове питання: адже купити ВЕЛИКИЙ сервер суттєво швидше, ніж практично заново розробляти програми, адаптуючи його до роботи на великій кількості паралельно працюючих серверів.

Закінчивши із загальними словами, давайте перейдемо до огляду потенційних проблем і варіантів їх вирішення при горизонтальному масштабуванні. Прохання особливо не критикувати - на абсолютну правильність і достовірність не претендую, просто "думки вголос", та й навіть згадати всі моменти цієї теми у мене виразно не вийде.

Сервери програм

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

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

Балансування навантаження

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

УстаткуванняМережеве обладнання, що дозволяє розподіляти навантаження між декількома серверами, зазвичай коштує досить значні суми, але серед інших варіантів зазвичай саме цей підхід пропонує найвищу продуктивність і стабільність (в основному завдяки якості плюс таке обладнання іноді поставляється парами, що працюють за принципом). У цій індустрії досить багато серйозних брендів, що пропонують свої рішення – є з чого вибрати: Cisco, Foundry, NetScalarта багато інших. Програмне забезпеченняУ цій галузі ще більша різноманітність можливих варіантів. Отримати програмно продуктивність порівнянну з апаратними рішеннями не так просто, та й HeartBeat доведеться забезпечувати програмно, зате обладнання для функціонування такого рішення є звичайним сервером (можливо не один). Таких програмних продуктів досить багато, зазвичай вони є просто HTTP-серверами, що перенаправляють запити своїм колегам на інших серверах замість відправки безпосередньо на обробку інтерпретатору мови програмування. Наприклад можна згадати, скажімо, з mod_proxy . Крім цього, мають місце більш екзотичні варіанти, засновані на DNS, тобто в процесі визначення клієнтом IP-адреси сервера з необхідним йому інтернет-ресурсів адреса видається з урахуванням навантаження на доступні сервери, а також деяких географічних міркувань.

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

Ресурсомісткі обчислення

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

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

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

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

Сесії

Практично всі веб-застосунки якимось чином взаємодіють зі своїми відвідувачами і в переважній більшості випадків у них є необхідність відстежувати переміщення користувачів по сторінках сайту. Для вирішення цього завдання зазвичай використовується механізм сесій, який полягає у присвоєнні кожному відвідувачу унікального ідентифікаційного номера, який йому передається для зберігання в cookies або, у разі їх відсутності, для постійного "тягання" за собою через GET. Отримавши від користувача певний ID разом з черговим HTTP-запитом, сервер може подивитися в список вже виданих номерів і однозначно визначити, хто його відправив. З кожним ID може асоціюватися якийсь набір даних, який веб-додаток може використовувати на свій розсуд, ці дані зазвичай за замовчуванням зберігаються у файлі в часовій директорії на сервері.

Здавалося б все просто, але... але запити відвідувачів одного і того ж сайту можуть обробляти відразу кілька серверів, як тоді визначити чи не було видано отриманий ID на іншому сервері і де взагалі зберігаються його дані?

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

Централізоване зберігання сесійІдея проста: створити для всіх серверів загальну "скарбничку", куди вони зможуть складати видані ними сесії та дізнаватися про сесії відвідувачів інших серверів. У ролі такої "скарбнички" теоретично може виступати і просто примонтована по мережі файлова система, але з деяких причин більш перспективним виглядає використання будь-якої СУБД, так як це позбавляє маси проблем, пов'язаних із зберіганням сесійних даних у файлах. Але у варіанті із загальною базою даних не варто забувати, що навантаження на нього неухильно зростатиме зі зростанням кількості відвідувачів, а також варто заздалегідь передбачити варіанти виходу із проблематичних ситуацій, пов'язаних з потенційними збоями в роботі сервера з цією СУБД. Децентралізоване зберігання сесійНаочний приклад - зберігання сесій в , спочатку розрахована на розподілене зберігання даних в оперативній пам'яті система дозволить отримувати всім серверам швидкий доступ до будь-яких сесійних даних, але при цьому (на відміну від попереднього способу) будь-який єдиний центр зберігання буде відсутній. Це дозволить уникнути вузьких місць з погляду продуктивності та стабільності у періоди підвищених навантажень.

В якості альтернативи сесіям іноді використовують схожі за призначенням механізми, побудовані на cookies, тобто всі необхідні додатку дані про користувача зберігаються на стороні клієнта (ймовірно в зашифрованому вигляді) і запитуються при необхідності. Але крім очевидних переваг, пов'язаних із відсутністю необхідності зберігати зайві дані на сервері, виникає низка проблем із безпекою. Дані, що зберігаються на стороні клієнта навіть у зашифрованому вигляді, є потенційною загрозою для функціонування багатьох додатків, оскільки будь-який бажаючий може спробувати модифікувати їх у своїх інтересах або з метою нашкодити додатку. Такий підхід хороший тільки якщо є впевненість, що абсолютно будь-які маніпуляції з даними, що зберігаються у даних, безпечні. Але чи можна бути впевненим на 100%?

Статичний контент

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

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

Можливо, такий варіант з якихось причин буде нереалізований, тоді доведеться "винаходити велосипед" для реалізації на рівні докладання принципів схожих із сегментуванням даних щодо СУБД, про які я ще згадаю далі. Цей варіант також цілком ефективний, але потребує модифікації логіки додатка, а отже, і виконання додаткової роботи розробниками.

Альтернативою цим підходам є використання так званих Content Delievery Network- зовнішніх сервісів, які забезпечують доступність Вашого контенту користувачам за певну матеріальну винагороду сервісу. Перевага очевидна - немає необхідності організовувати власну інфраструктуру для вирішення цього завдання, зате з'являється інша додаткова стаття витрат. Список таких сервісів наводити не буду, якщо комусь знадобиться – знайти буде не важко.

Кешування

Кешування має сенс проводити всіх етапах обробки даних, але у різних типах додатків найефективнішими є лише деякі методи кешування.

СУБДМайже всі сучасні СУБД надають вбудовані механізми для кешування результатів певних запитів. Цей метод досить ефективний, якщо Ваша система регулярно робить одні й ті ж вибірки даних, але також має ряд недоліків, основними з яких є інвалідування кешу всієї таблиці при найменшій її зміні, а також локальне розташування кешу, що неефективно за наявності кількох серверів у системі зберігання даних. ДодатокНа рівні програм зазвичай проводиться кешування об'єктів будь-якої мови програмування. Цей метод дозволяє уникнути істотної частини запитів до СУБД, сильно знижуючи навантаження на неї. Як і самі додатки такий кеш має бути незалежним від конкретного запиту та сервера, на якому він виконується, тобто бути доступним усім серверам додатків одночасно, а ще краще – бути розподіленим по кількох машинах для більш ефективної утилізації оперативної пам'яті. Лідером у цьому аспекті кешування по праву можна назвати, про яке я свого часу вже встиг. HTTP-серверБагато веб-серверів мають модулі для кешування як статичного контенту, так і результатів роботи скриптів. Якщо сторінка рідко оновлюється, то використання цього методу дозволяє без будь-яких видимих ​​для користувача змін уникати генерації сторінки у відповідь на більшу частину запитів. Reverse proxyПоставивши між користувачем та веб-сервером прозорий проксі-сервер, можна видавати користувачеві дані з кешу проксі (який може бути як в оперативній пам'яті, так і дисковим), не доводячи запити навіть до серверів HTTP. У більшості випадків цей підхід є актуальним лише для статичного контенту, в основному різних форм медіа-даних: зображень, відео тощо. Це дозволяє веб-серверам зосередитися лише на роботі із самими сторінками.

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

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

Бази даних

На закуску я залишив найцікавіше, адже цей невід'ємний компонент будь-якої веб-програми викликає більше проблем при зростанні навантажень, ніж решта разом узятих. Часом навіть може здатися, що варто взагалі відмовитися від горизонтального масштабування системи зберігання даних на користь вертикального - просто купити цей ВЕЛИКИЙ сервер за шести-або семизначну суму не-рублів і не забивати собі голову зайвими проблемами.

Але для багатьох проектів таке кардинальне рішення (і те, за великим рахунком, тимчасове) не підходить, а отже, перед ними залишилася лише одна дорога - горизонтальне масштабування. Про неї і поговоримо.

Шлях практично будь-якого веб-проекту з погляду баз даних починався з одного простого сервера, на якому працював весь проект цілком. Потім одного разу настає необхідність винести СУБД на окремий сервер, але і він з часом починає не впоратися з навантаженням. Детально зупинятися цих двох етапах сенсу особливого немає - усе відносно тривіально.

Наступним кроком зазвичай буває master-slaveз асинхронною реплікацією даних, як працює ця схема вже неодноразово згадувалося в блозі, але, мабуть, повторюся: при такому підході всі операції запису виконуються лише на одному сервері (master), а решта серверів (slave) отримують дані безпосередньо від "майстра", обробляючи у своїй лише запити читання даних. Як відомо, операції читання та запису будь-якого веб-проекту завжди зростають пропорційно до зростання навантаження, при цьому зберігається майже фіксованим співвідношення між обома типами запитів: на кожен запит на оновлення даних зазвичай припадає в середньому близько десятка запитів на читання. З часом навантаження зростає, а значить зростає і кількість операцій запису в одиницю часу, а сервер обробляє їх всього один, а потім він ще й забезпечує створення деякої кількості копій на інших серверах. Рано чи пізно витрати операцій реплікації даних будуть настільки високі, що цей процес займатиме дуже велику частину процесорного часу кожного сервера, а кожен slave зможе обробляти лише порівняно невелику кількість операцій читання, і, як наслідок, кожен додатковий slave-сервер почне збільшувати сумарну продуктивність лише незначно, теж займаючись здебільшого лише підтримкою своїх даних відповідно до "майстра".

Тимчасовим вирішенням цієї проблеми, можливо, може стати заміна master-сервера на продуктивніший, але так чи інакше не вийде нескінченно відкладати перехід на наступний "рівень" розвитку системи зберігання даних: "sharding", якому зовсім недавно присвятив . Так що дозволю собі зупинитися на ньому лише коротко: ідея полягає в тому, щоб розділити всі дані на частини за якоюсь ознакою та зберігати кожну частину на окремому сервері або кластері, таку частину даних у сукупності із системою зберігання даних, в якій вона знаходиться , і називають сегментом або shardТому. Такий підхід дозволяє уникнути витрат, пов'язаних з реплікуванням даних (або скоротити їх у багато разів), а отже суттєвозбільшити загальну продуктивність системи зберігання даних. Але, на жаль, перехід до цієї схеми організації даних вимагає безліч витрат іншого роду. Так як готового рішення для її реалізації не існує, доводиться модифікувати логіку програми або додавати додаткову "прошарку" між додатком та СУБД, причому все це найчастіше реалізується силами розробників проекту. Готові продукти здатні лише полегшити їхню роботу, надавши якийсь каркас для побудови основної архітектури системи зберігання даних та її взаємодії з іншими компонентами програми.

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

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

У цьому розділі варто згадати ще один, більш специфічний тип інтернет-проектів. Такі проекти оперують даними, які мають чітко формалізовану структуру, у таких ситуаціях використання реляційних СУБД як сховища даних, м'яко кажучи, недоцільно. У цих випадках зазвичай використовують менш суворі бази даних, з більш примітивною функціональністю в плані обробки даних, зате вони здатні обробляти величезні обсяги інформації, не чіпляючись до його якості та відповідності формату. В якості основи для такого сховища даних може служити кластерна файлова система, а для аналізу даних у такому випадку використовується механізм під назвою , принцип його роботи я розповім лише коротко, так як в повному своєму масштабі він дещо виходить за рамки даної розповіді.

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

MapОсновною метою даного етапу є уявлення довільних вхідних даних у вигляді проміжних пар ключ-значення, що мають певний зміст і формально оформлених. Результати піддаються сортуванню та групуванню по ключу, а потім передаються на наступний етап. ReduceОтримані після mapЗначення використовуються для фінального обчислення необхідних підсумкових даних.

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

Прикладом готового каркасу для реалізації роботи з даними за таким принципом є Opensource проект Apache Foundation під назвою , Про який я вже неодноразово розповідав раніше, та й написав свого часу.

Замість ув'язнення

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

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