flowchart LR A[User] --> B((Internet)) B --> C[Servise] C --> D((Network)) D --> E[(Storage)] style A fill:#5cb85c style B fill:#5bc0de style C fill:#d9534f style D fill:#5bc0de style E fill:#428bca
Конструювання програмного забезпечення
КНУ імені Тараса Шевченка, ФІТ
ihor.miroshnychenko@kneu.ua
Як долучитися?
Примітка
Клас буде активний з 11 жовтня 2023 року до 11 квітня 2023 року, після чого буде буде відкрито наступний потік. Слідкуйте за оновленнями.
Оскільки задача проєктування систем майже завжди формується у відкритій формі, нам потрібно окреслити функціонал та визначити вимоги до системи.
Функціональні вимоги - це можливості, які система надає користувачеві.
Наприклад, для соціальних мереж це:
Для цього варто виписати найвідоміші властивості системи в порядку важливості та вказати, над якими ми плануємо сконцентруватися надалі.
Потім, залежно від спрямованості соціальної мережі, можемо представити такі функції, як:
Якісь соцмережі можуть підтримувати всі напрямки і додаткові можливості, на кшталт додавання геотегів, пошуку контенту, рекомендацій тощо.
Нефункціональні вимоги - це те, як має поводитися система в роботі.
Типові запитання, на які хочемо відповісти:
На перший погляд всі ці питання можуть виглядати дивними — чому б не зробити систему якомога швидшою та надійнішою? Але відповіді на них допоможуть нам зрозуміти, які компроміси ми готові робити.
Наприклад, CAP-теорема говорить, що система не може одночасно бути:
Тому в залежності від вимог до системи ми можемо вибрати, які з цих властивостей нам важливіші.
Для соціальної мережі важливо, щоб вона завжди була доступною.
Соціальна мережа також розділена, маючи користувачів по всьому світу (і сервери, відповідно).
Однак, якщо користувач публікує пост, можливо, ми не одразу його побачимо.
Нічого страшного, якщо станеться затримка, рано чи пізно він все одно стане доступним для всіх користувачів. Тобто, консистентність не така критична.
У випадку з банківським додатком успішно проведена грошова транзакція повинна означати надходження і видимість коштів на рахунку адресата, ніяк інакше.
Ціною цьому може бути недоступність застосунку якийсь час.
Щоб перетворювати довгі посилання на короткі, зручні для обміну.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: збір аналітики, API для розробників.
Щоб ділитися кодом і шукати в ньому помилки разом.
Функціональні вимоги:
Нефункціональні вимоги:
Щоб при введенні перших букв запиту пропонувалися варіанти доповнення.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: враховувати минулу історію запитів, профіль користувача, контекст тощо.
Щоб зберігати файли в хмарі та мати до них доступ з різних пристроїв.
Функціональні вимоги:
Нефункціональні вимоги:
Щоб ділитися фотографіями їжі та себе у дзеркалі.
Функціональні вимоги:
Нефункціональні вимоги:
Щоб від спілкування Вас відволікали роботою.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: стікери, групові чати, сторіз 🙈, тощо
Щоб почитати чергову маячню Маска і що з цього приводу думає цивілізований світ.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: пошук, реплаї, гарячі теми, повідомлення, рекомендації, аватарки з NFT мавпами.
Щоб подивитися Гаррі Поттера перед Різдвом.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: жанри, популярне, вибране, списки на подивитися потім.
Щоб не їсти їжу з жовтих сумок.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: фільтри за категоріями, рекомендації нових закладів.
Щоб не їздити на маршрутках.
Функціональні вимоги:
Нефункціональні вимоги:
Бонус: оцінки водіям, оцінки пасажирам, пояснення ціноутворення.
Після збору первинних вимог до системи дуже важливо оцінити необхідну інфраструктуру для розгортання і підтримки системи, а також вартість усього обладнання і процесів.
Від того, наскільки точно зробити розрахунок, залежатиме успіх проєкту і його життєздатність, а найголовніше - чи вистачить у замовника матеріальних ресурсів, щоб втілити всі сформульовані побажання і вимоги до системи.
Оцінка дасть змогу скоригувати очікування від продукту.
На цій стадії проєктування ми оцінюємо з різних сторін яке навантаження може бути на систему.
Чи є якісь перекоси у бік читання або запису і яке залізо або інтернет-канал може знадобитися для передачі необхідної кількості даних.
flowchart LR A[User] --> B((Internet)) B --> C[Servise] C --> D((Network)) D --> E[(Storage)] style A fill:#5cb85c style B fill:#5bc0de style C fill:#d9534f style D fill:#5bc0de style E fill:#428bca
Щоб розрахувати необхідний обсяг трафіку, потрібно оцінити потенційну аудиторію системи та підрахувати загальну кількість користувачів.
Якщо це якась закрита система для внутрішнього користування організації - кількість користувачів, виходячи з поточного штатного розкладу, обов’язків співробітників. Також можна закласти відсоток розширення персоналу, щоб врахувати приріст користувачів у майбутньому.
Якщо майбутня система це загальнодоступний ресурс - соціальна мережа або інший сервіс, тоді для приблизної оцінки можна проаналізувати метрики найближчих конкурентів.
Виходячи з кількості потенційних користувачів, далі можна оцінити час роботи користувачів у системі на день/місяць, оцінити обсяг контенту, що генерується і споживається під час роботи, а також обсяг місця на жорстких дисках під зберігання цього контенту.
Мережеве навантаження складається з утримуваних з’єднань в одну одиницю часу і загального обсягу трафіку, який може пройти через мережу за одиницю часу.
З мережевого навантаження на сервіс можна вивести загальну вартість трафіку.
Хмарні провайдери, наприклад, оцінюють 1Gb трафіку в місяць в середньому від $0.01 до $0.1.
Під обчислювальним навантаженням зазвичай мається на увазі обчислення кількості одночасних запитів користувачів до сервісу. Цей показник обчислюється в RPS (requests per second).
Залежно від операції, з якою користувач звертається до сервісу, обчислювальне навантаження помітно різниться, тому показники рахують для групи операцій, наприклад, окремо для операції на отримання текстових даних, окремо для читання з БД і окремо для запису в БД.
Обчислювальне навантаження на старті, звісно, оцінити найскладніше.
Природним чином воно залежатиме від складності створюваної нами системи. Але на якийсь порядок цифр для простих сценаріїв можна орієнтуватися за бенчмарками TechEmpower Web Framework Benchmarks
За грубою оцінкою можна виходити з того, що в простих сценаріях у хмарі ми зможемо витримувати навантаження в 100k RPS для текстових даних і 10k RPS і 1k RPS під час читання і запису в БД.
За наявності потужних фізичних серверів у тих самих сценаріях можна прикидати ймовірне навантаження в 500k RPS для текстових даних і 50k RPS і 5k RPS під час читання і запису в БД.
Реальні характеристики системи, звісно ж, виявлятимуться вже під час тестувань
Оцінивши кількість створюваного контенту з боку користувачів, ми можемо прикинути скільки місця він займатиме, який постійний приріст при цьому очікується і, відповідно, скільки того чи іншого заліза нам знадобиться для нашої системи.
Найпоширеніші види сховищ і значення показників їхньої швидкості обробки даних, а також вартість зберігання даних:
Найпоширеніші види сховищ і значення показників їхньої швидкості обробки даних, а також вартість зберігання даних:
У середньому зберігання 1 ТБ обійдеться приблизно в $10000 в RAM, $300 на SSD і $30 на HDD.
Можна прикидати, що в одному сервері буде до 1 ТБ RAM, 50 ТБ SSD або 200ТБ HDD.
Якщо дисків багато, у гру вступає і середня кількість відмов за рік (AFR) у розмірі 1%.
Один з важливих факторів для системи — це час/затримка відповіді або latency.
В деяких сценаріях вона буде визначатися швидкістю мережі/диску, але можуть бути й інші причини.
У 2011 році відомий інженер Jeff Dean з Google опублікував статтю зі своїми спостереженнями щодо часу виконання різних операцій на різних пристроях:
0.5 ns
5 ns
7 ns
100 ns
100 ns
10 000 ns
20 000 ns
250 000 ns
500 000 ns
10 000 000 ns
10 000 000 ns
0 000 000 ns
150,000,000 ns
Примітка
Те саме, але графічно:
На які показники варто орієнтуватися під час розрахунків навантаження на систему:
В одну машину можна поставити 1 TB RAM, 50 TB SSD або 200 TB HDD.
Звернень до сервісу в місяць: 100 * 100М = 10Млрд.
Навантаження на створення записів: 100М / (30 * 86400) ≈ 40 RPS. На читання: x100 = 4K RPS.
Якщо кожен запис займає 1 КБ, ми будемо генерувати трафік у 32 Мбит/сек1.
На горизонті 5 років ми будемо зберігати 100М * 5 * 12 = 6Млрд записів або 6 ТБ даних.
У підсумку, для таких користувачів достатньо і однієї робочої станції за декілька тисяч доларів.
Звернень до сервісу в місяць: 30 * 10 * 1М = 300 млн.
Навантаження на створення записів: 1М / (86400) ≈ 12 RPS. На читання: x10 = 120 RPS.
Якщо кожен запис займає 10 КБ, ми будемо генерувати трафік у 10 Мбит/сек.
На горизонті 5 років ми будемо зберігати 30М * 5 * 12 = 1.8 Млрд записів або 18 ТБ даних.
У підсумку, для таких користувачів достатньо і однієї робочої станції за декілька тисяч доларів.
Маємо: 50 символів на запит в середньому, тобто в 200 байт точно поміститься.
Всього на збереження всіх запитів за день піде: 10 млн. * 200 байт = 2 ГБ.
Якщо припустити, що кожен день з’являється 5% нових унікальних запитів, то на горизонті 5 років ми будемо зберігати індекс розміром 2 ГБ * 365 * 5 * 1.05 = 3.8 ТБ.
У підсумку, для таких користувачів достатньо і однієї робочої станції за декілька тисяч доларів.
Мережа: на оновлення 100 млн. * 100 кБ = 10 ТБ трафіку в день, 10 ТБ * 86 400 сек ≈ 1 Gbps, 1 Gbps * ≈ 2 тис. днів ≈ 20 PB за 5 років, відкрито 10 тис. з’єднань.
Обчислення: необхідно писати 100 млн. записів в день = 1 тис. RPS з записами до БД.
Сховище: всього зберігаємо 1 млрд. * 100 * 100 кБ = 10 PB, тобто 50 серверів з 200 TB HDD кожен.
Вартість: 20 PB трафіку обійдеться у $2 млн., на зберігання 10 PB HDD потрібно $300 тис.
На датаноди нам знадобиться до 100 серверів, з’єднання і трафік витримає і один сервер, але краще більше.
Підтримка всій системи обійдеться в декілька млн. доларів на горизонті 5 років.
Мережа: - завантаження фото 100 млн. / 100 тис. = 1 тис. RPS, 1 тис. * 100 кБ = 1 Gbps і ≈ 200 PB за 5 років - читання 100 тис. RPS / 100 Gbps, С100k
Обчислення: 1 тис. RPS на запис фото, 100 тис. RPS на читання
Сховище: всього зберігаємо 20 PB фото, тобто 100 серверів з 200 TB HDD кожен.
Вартість: 200 PB трафіку обійдеться у $2 млн., на зберігання 20 PB HDD потрібно $600 тис.
На датаноди нам знадобиться до 100 серверів, з’єднання з трафіком та читання БД треба ще десятки.
Підтримка всій системи обійдеться в декілька млн. доларів на горизонті 5 років.
Мережа: - завантаження повідомлень 100 млн. * 100 / 86400 ≈ 100 тис. RPS, 100 тис. * 1 кБ = 1 Gbps і ≈ 200 PB за 5 років - читання 1 млн. RPS / 100 Gbps, С1М
Обчислення: 100 тис. RPS на запис повідомлень, 1 млн. RPS на читання
Сховище: всього зберігаємо 20 PB повідомлень, тобто 100 серверів з 200 TB HDD кожен.
Вартість: 200 PB трафіку обійдеться у $2 млн., на зберігання 20 PB HDD потрібно $600 тис.
На датаноди нам знадобиться сотні серверів і для датанод, і дня підтримки з’єднань, і для записів в БД.
Підтримка всій системи обійдеться в декілька млн. доларів на горизонті 5 років.
Мережа: - завантаження повідомлень 100 млн. * 1 / 86400 ≈ 1 тис. RPS, 1 тис. * 100 кБ = 100 Mbps і ≈ 2 PB за 5 років - читання 1 тис. RPS / 1 Gbps, С10k
Обчислення: 1 тис. RPS на запис повідомлень, 10 тис. RPS на читання + JOIN та алгоритмічна стрічка.
Сховище: всього зберігаємо 2 PB повідомлень, тобто 10 серверів з 200 TB HDD кожен.
Вартість: 2 PB трафіку обійдеться у $200 тис., на зберігання 2 PB HDD потрібно $60 тис.
На датаноди нам знадобиться десятки серверів + сервери для обчислень і допоміжні сервери.
Підтримка всій системи обійдеться в межах 1 млн. доларів на горизонті 5 років.
Мережа: відео 1080p займає 5 MBps, трафік 10 млн. * 4000 * 5 MBps = 20 Pbps (20 000 000 Gbps 😧).
Обчислення: 10 млн. * 10 переглядів / 100 000 сек. = 1 тис. RPS на отримання метаданих між серіями.
Сховище: 20 000 найменувань по 10 годин (фільми, але і серіали) 20 тис. * 10 * 4000 * 10 Mbps ≈ 1 EB = 1 млн. TB.
Вартість: На сховище необхідно витратити десятки мільйонів доларів, на мережу — мільярди 😮.
За трафік по стандартному прайсу розплатитися неможливо, тому Netflix має власні CDN (мережі дистрибуції контенту).
ihor.miroshnychenko@kneu.ua