From df010eb6757a808fad4d8f306daee4c688201d5f Mon Sep 17 00:00:00 2001 From: shramko Date: Sun, 30 Nov 2025 21:47:00 -0500 Subject: [PATCH] feat: add Ukrainian translation --- README-ja.md | 2 +- README-uk.md | 1839 +++++++++++++++++++++++++++++++++++++++++++++ README-zh-Hans.md | 2 +- README-zh-TW.md | 2 +- README.md | 2 +- TRANSLATIONS.md | 13 +- 6 files changed, 1849 insertions(+), 11 deletions(-) create mode 100644 README-uk.md diff --git a/README-ja.md b/README-ja.md index 74400bdd702..32966b6cf2f 100644 --- a/README-ja.md +++ b/README-ja.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) ∙ [Українська](README-uk.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # システム設計入門 diff --git a/README-uk.md b/README-uk.md new file mode 100644 index 00000000000..8772a4c0a4a --- /dev/null +++ b/README-uk.md @@ -0,0 +1,1839 @@ +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) ∙ [Українська](README-uk.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Додати переклад](https://github.com/donnemartin/system-design-primer/issues/28)* + +# Підручник з проектування систем + +

+ +
+

+ +## Мотивація + +> Навчіться проектувати великомасштабні системи. +> +> Підготуйтеся до співбесіди з проектування систем. + +### Навчіться проектувати великомасштабні системи + +Вивчення проектування масштабованих систем допоможе вам стати кращим інженером. + +Проектування систем — це широка тема. В інтернеті **розкидано величезну кількість ресурсів** про принципи проектування систем. + +Цей репозиторій є **організованою колекцією** ресурсів, які допоможуть вам навчитися створювати системи у великому масштабі. + +### Вчіться у спільноти відкритого коду + +Це проект з відкритим кодом, який постійно оновлюється. + +[Внески](#як-долучитися) вітаються! + +### Підготовка до співбесіди з проектування систем + +Окрім співбесід з програмування, проектування систем є **обов'язковим компонентом** **технічного процесу співбесіди** у багатьох технологічних компаніях. + +**Практикуйте типові питання співбесіди з проектування систем** та **порівнюйте** свої результати зі **зразками рішень**: обговорення, код та діаграми. + +Додаткові теми для підготовки до співбесіди: + +* [Навчальний посібник](#навчальний-посібник) +* [Як підходити до питань співбесіди з проектування систем](#як-підходити-до-питань-співбесіди-з-проектування-систем) +* [Питання співбесіди з проектування систем **з рішеннями**](#питання-співбесіди-з-проектування-систем-з-рішеннями) +* [Питання співбесіди з об'єктно-орієнтованого проектування **з рішеннями**](#питання-співбесіди-з-обєктно-орієнтованого-проектування-з-рішеннями) +* [Додаткові питання співбесіди з проектування систем](#додаткові-питання-співбесіди-з-проектування-систем) + +## Картки Anki + +

+ +
+

+ +Надані [набори карток Anki](https://apps.ankiweb.net/) використовують інтервальне повторення, щоб допомогти вам запам'ятати ключові концепції проектування систем. + +* [Набір карток з проектування систем](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/System%20Design.apkg) +* [Набір карток з вправ проектування систем](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/System%20Design%20Exercises.apkg) +* [Набір карток з вправ об'єктно-орієнтованого проектування](https://github.com/donnemartin/system-design-primer/tree/master/resources/flash_cards/OO%20Design.apkg) + +Чудово підходить для навчання в дорозі. + +### Ресурс для програмування: інтерактивні завдання + +Шукаєте ресурси для підготовки до [**співбесіди з програмування**](https://github.com/donnemartin/interactive-coding-challenges)? + +

+ +
+

+ +Перегляньте споріднений репозиторій [**Interactive Coding Challenges**](https://github.com/donnemartin/interactive-coding-challenges), який містить додатковий набір карток Anki: + +* [Набір карток з програмування](https://github.com/donnemartin/interactive-coding-challenges/tree/master/anki_cards/Coding.apkg) + +## Як долучитися + +> Вчіться у спільноти. + +Не соромтеся надсилати pull request для: + +* Виправлення помилок +* Покращення розділів +* Додавання нових розділів +* [Перекладу](https://github.com/donnemartin/system-design-primer/issues/28) + +Контент, який потребує доопрацювання, розміщено в розділі [у розробці](#у-розробці). + +Перегляньте [Правила внесення змін](CONTRIBUTING.md). + +## Зміст тем проектування систем + +> Огляд різних тем проектування систем, включаючи переваги та недоліки. **Все є компромісом**. +> +> Кожен розділ містить посилання на більш глибокі ресурси. + +

+ +
+

+ +* [Теми проектування систем: почніть тут](#теми-проектування-систем-почніть-тут) + * [Крок 1: Перегляньте відеолекцію про масштабованість](#крок-1-перегляньте-відеолекцію-про-масштабованість) + * [Крок 2: Прочитайте статтю про масштабованість](#крок-2-прочитайте-статтю-про-масштабованість) + * [Наступні кроки](#наступні-кроки) +* [Продуктивність vs масштабованість](#продуктивність-vs-масштабованість) +* [Затримка vs пропускна здатність](#затримка-vs-пропускна-здатність) +* [Доступність vs узгодженість](#доступність-vs-узгодженість) + * [Теорема CAP](#теорема-cap) + * [CP — узгодженість та стійкість до розділення](#cp--узгодженість-та-стійкість-до-розділення) + * [AP — доступність та стійкість до розділення](#ap--доступність-та-стійкість-до-розділення) +* [Патерни узгодженості](#патерни-узгодженості) + * [Слабка узгодженість](#слабка-узгодженість) + * [Eventual consistency (кінцева узгодженість)](#eventual-consistency-кінцева-узгодженість) + * [Сильна узгодженість](#сильна-узгодженість) +* [Патерни доступності](#патерни-доступності) + * [Відмовостійкість (Fail-over)](#відмовостійкість-fail-over) + * [Реплікація](#реплікація) + * [Доступність у цифрах](#доступність-у-цифрах) +* [Система доменних імен (DNS)](#система-доменних-імен-dns) +* [Мережа доставки контенту (CDN)](#мережа-доставки-контенту-cdn) + * [Push CDN](#push-cdn) + * [Pull CDN](#pull-cdn) +* [Балансувальник навантаження](#балансувальник-навантаження) + * [Активний-пасивний](#активний-пасивний) + * [Активний-активний](#активний-активний) + * [Балансування на рівні Layer 4](#балансування-на-рівні-layer-4) + * [Балансування на рівні Layer 7](#балансування-на-рівні-layer-7) + * [Горизонтальне масштабування](#горизонтальне-масштабування) +* [Зворотний проксі (веб-сервер)](#зворотний-проксі-веб-сервер) + * [Балансувальник навантаження vs зворотний проксі](#балансувальник-навантаження-vs-зворотний-проксі) +* [Прикладний рівень](#прикладний-рівень) + * [Мікросервіси](#мікросервіси) + * [Виявлення сервісів](#виявлення-сервісів) +* [База даних](#база-даних) + * [Реляційна СУБД (RDBMS)](#реляційна-субд-rdbms) + * [Реплікація master-slave](#реплікація-master-slave) + * [Реплікація master-master](#реплікація-master-master) + * [Федерація](#федерація) + * [Шардинг](#шардинг) + * [Денормалізація](#денормалізація) + * [Оптимізація SQL](#оптимізація-sql) + * [NoSQL](#nosql) + * [Сховище ключ-значення](#сховище-ключ-значення) + * [Документне сховище](#документне-сховище) + * [Сховище з широкими стовпцями](#сховище-з-широкими-стовпцями) + * [Графова база даних](#графова-база-даних) + * [SQL чи NoSQL](#sql-чи-nosql) +* [Кеш](#кеш) + * [Кешування на клієнті](#кешування-на-клієнті) + * [Кешування CDN](#кешування-cdn) + * [Кешування веб-сервера](#кешування-веб-сервера) + * [Кешування бази даних](#кешування-бази-даних) + * [Кешування додатку](#кешування-додатку) + * [Кешування на рівні запитів до БД](#кешування-на-рівні-запитів-до-бд) + * [Кешування на рівні об'єктів](#кешування-на-рівні-обєктів) + * [Коли оновлювати кеш](#коли-оновлювати-кеш) + * [Cache-aside](#cache-aside) + * [Write-through](#write-through) + * [Write-behind (write-back)](#write-behind-write-back) + * [Refresh-ahead](#refresh-ahead) +* [Асинхронність](#асинхронність) + * [Черги повідомлень](#черги-повідомлень) + * [Черги завдань](#черги-завдань) + * [Зворотний тиск (Back pressure)](#зворотний-тиск-back-pressure) +* [Комунікація](#комунікація) + * [Протокол TCP](#протокол-tcp) + * [Протокол UDP](#протокол-udp) + * [Віддалений виклик процедур (RPC)](#віддалений-виклик-процедур-rpc) + * [REST](#rest) +* [Безпека](#безпека) +* [Додаток](#додаток) + * [Таблиця степенів двійки](#таблиця-степенів-двійки) + * [Числа затримки, які має знати кожен програміст](#числа-затримки-які-має-знати-кожен-програміст) + * [Додаткові питання співбесіди з проектування систем](#додаткові-питання-співбесіди-з-проектування-систем) + * [Архітектури реального світу](#архітектури-реального-світу) + * [Архітектури компаній](#архітектури-компаній) + * [Інженерні блоги компаній](#інженерні-блоги-компаній) +* [У розробці](#у-розробці) +* [Подяки](#подяки) +* [Контактна інформація](#контактна-інформація) +* [Ліцензія](#ліцензія) + +## Навчальний посібник + +> Рекомендовані теми для вивчення залежно від часу підготовки (короткий, середній, довгий). + +![Imgur](images/OfVllex.png) + +**П: Чи потрібно мені знати все, що тут є, для співбесіди?** + +**В: Ні, вам не потрібно знати все, що тут є, для підготовки до співбесіди.** + +Що вас запитають на співбесіді, залежить від таких змінних: + +* Скільки у вас досвіду +* Яка ваша технічна спеціалізація +* На яку позицію ви проходите співбесіду +* В яких компаніях ви проходите співбесіду +* Удача + +Від більш досвідчених кандидатів зазвичай очікують більше знань про проектування систем. Від архітекторів чи тімлідів можуть очікувати більше, ніж від рядових розробників. Провідні технологічні компанії, ймовірно, проводять один або кілька раундів співбесіди з проектування. + +Почніть широко і заглибтесь у кілька областей. Корисно трохи знати про різні ключові теми проектування систем. Скоригуйте наступний посібник залежно від вашого часу, досвіду, позиції, на яку ви претендуєте, та компаній, в яких проходите співбесіду. + +* **Короткий термін** — прагніть до **широти** знань тем проектування систем. Практикуйтесь, розв'язуючи **деякі** питання співбесіди. +* **Середній термін** — прагніть до **широти** та **певної глибини** знань тем проектування систем. Практикуйтесь, розв'язуючи **багато** питань співбесіди. +* **Довгий термін** — прагніть до **широти** та **більшої глибини** знань тем проектування систем. Практикуйтесь, розв'язуючи **більшість** питань співбесіди. + +| | Короткий | Середній | Довгий | +|---|---|---|---| +| Прочитайте [теми проектування систем](#зміст-тем-проектування-систем), щоб отримати широке розуміння того, як працюють системи | :+1: | :+1: | :+1: | +| Прочитайте кілька статей з [інженерних блогів компаній](#інженерні-блоги-компаній), в яких ви проходите співбесіду | :+1: | :+1: | :+1: | +| Прочитайте кілька [архітектур реального світу](#архітектури-реального-світу) | :+1: | :+1: | :+1: | +| Перегляньте [Як підходити до питань співбесіди з проектування систем](#як-підходити-до-питань-співбесіди-з-проектування-систем) | :+1: | :+1: | :+1: | +| Пропрацюйте [питання співбесіди з проектування систем з рішеннями](#питання-співбесіди-з-проектування-систем-з-рішеннями) | Деякі | Багато | Більшість | +| Пропрацюйте [питання співбесіди з об'єктно-орієнтованого проектування з рішеннями](#питання-співбесіди-з-обєктно-орієнтованого-проектування-з-рішеннями) | Деякі | Багато | Більшість | +| Перегляньте [додаткові питання співбесіди з проектування систем](#додаткові-питання-співбесіди-з-проектування-систем) | Деякі | Багато | Більшість | + +## Як підходити до питань співбесіди з проектування систем + +> Як вирішувати питання співбесіди з проектування систем. + +Співбесіда з проектування систем — це **відкрита розмова**. Від вас очікують, що ви будете вести її. + +Ви можете використовувати наступні кроки для керування обговоренням. Щоб закріпити цей процес, пропрацюйте розділ [питання співбесіди з проектування систем з рішеннями](#питання-співбесіди-з-проектування-систем-з-рішеннями), використовуючи ці кроки. + +### Крок 1: Окресліть сценарії використання, обмеження та припущення + +Зберіть вимоги та визначте обсяг проблеми. Ставте питання для уточнення сценаріїв використання та обмежень. Обговоріть припущення. + +* Хто буде це використовувати? +* Як вони будуть це використовувати? +* Скільки користувачів? +* Що робить система? +* Які вхідні та вихідні дані системи? +* Який обсяг даних ми очікуємо обробляти? +* Скільки запитів на секунду ми очікуємо? +* Яке очікуване співвідношення читання до запису? + +### Крок 2: Створіть високорівневий дизайн + +Накресліть високорівневий дизайн з усіма важливими компонентами. + +* Накресліть основні компоненти та з'єднання +* Обґрунтуйте свої ідеї + +### Крок 3: Спроектуйте основні компоненти + +Заглибтесь у деталі кожного основного компонента. Наприклад, якщо вас попросили [спроектувати сервіс скорочення URL](solutions/system_design/pastebin/README.md), обговоріть: + +* Генерування та зберігання хешу повного URL + * [MD5](solutions/system_design/pastebin/README.md) та [Base62](solutions/system_design/pastebin/README.md) + * Колізії хешів + * SQL чи NoSQL + * Схема бази даних +* Перетворення хешованого URL назад у повний URL + * Пошук у базі даних +* API та об'єктно-орієнтований дизайн + +### Крок 4: Масштабуйте дизайн + +Визначте та усуньте вузькі місця, враховуючи обмеження. Наприклад, чи потрібні вам наступні компоненти для вирішення проблем масштабованості? + +* Балансувальник навантаження +* Горизонтальне масштабування +* Кешування +* Шардинг бази даних + +Обговоріть потенційні рішення та компроміси. Все є компромісом. Для усунення вузьких місць використовуйте [принципи масштабованого проектування систем](#зміст-тем-проектування-систем). + +### Розрахунки «на серветці» + +Вас можуть попросити зробити деякі оцінки вручну. Зверніться до [Додатку](#додаток) для наступних ресурсів: + +* [Використовуйте розрахунки «на серветці»](http://highscalability.com/blog/2011/1/26/google-pro-tip-use-back-of-the-envelope-calculations-to-choo.html) +* [Таблиця степенів двійки](#таблиця-степенів-двійки) +* [Числа затримки, які має знати кожен програміст](#числа-затримки-які-має-знати-кожен-програміст) + +### Джерела та додаткове читання + +Перегляньте наступні посилання, щоб краще зрозуміти, чого очікувати: + +* [Як пройти співбесіду з проектування систем](https://web.archive.org/web/20210505130322/https://www.palantir.com/2011/10/how-to-rock-a-systems-design-interview/) +* [Співбесіда з проектування систем](http://www.hiredintech.com/system-design) +* [Вступ до співбесід з архітектури та проектування систем](https://www.youtube.com/watch?v=ZgdS0EUmn70) +* [Шаблон проектування систем](https://leetcode.com/discuss/career/229177/My-System-Design-Template) + +## Питання співбесіди з проектування систем з рішеннями + +> Типові питання співбесіди з проектування систем зі зразками обговорень, кодом та діаграмами. +> +> Рішення пов'язані з контентом у папці `solutions/`. + +| Питання | | +|---|---| +| Спроектуйте Pastebin.com (або Bit.ly) | [Рішення](solutions/system_design/pastebin/README.md) | +| Спроектуйте стрічку Twitter (або стрічку Facebook) | [Рішення](solutions/system_design/twitter/README.md) | +| Спроектуйте веб-краулер | [Рішення](solutions/system_design/web_crawler/README.md) | +| Спроектуйте Mint.com | [Рішення](solutions/system_design/mint/README.md) | +| Спроектуйте структури даних для соціальної мережі | [Рішення](solutions/system_design/social_graph/README.md) | +| Спроектуйте сховище ключ-значення для пошукової системи | [Рішення](solutions/system_design/query_cache/README.md) | +| Спроектуйте рейтинг продажів Amazon за категоріями | [Рішення](solutions/system_design/sales_rank/README.md) | +| Спроектуйте систему, яка масштабується до мільйонів користувачів на AWS | [Рішення](solutions/system_design/scaling_aws/README.md) | +| Додати питання з проектування систем | [Долучитися](#як-долучитися) | + +### Спроектуйте Pastebin.com (або Bit.ly) + +[Переглянути завдання та рішення](solutions/system_design/pastebin/README.md) + +![Imgur](images/4edXG0T.png) + +### Спроектуйте стрічку та пошук Twitter (або Facebook) + +[Переглянути завдання та рішення](solutions/system_design/twitter/README.md) + +![Imgur](images/jrUBAF7.png) + +### Спроектуйте веб-краулер + +[Переглянути завдання та рішення](solutions/system_design/web_crawler/README.md) + +![Imgur](images/bWxPtQA.png) + +### Спроектуйте Mint.com + +[Переглянути завдання та рішення](solutions/system_design/mint/README.md) + +![Imgur](images/V5q57vU.png) + +### Спроектуйте структури даних для соціальної мережі + +[Переглянути завдання та рішення](solutions/system_design/social_graph/README.md) + +![Imgur](images/cdCv5g7.png) + +### Спроектуйте сховище ключ-значення для пошукової системи + +[Переглянути завдання та рішення](solutions/system_design/query_cache/README.md) + +![Imgur](images/4j99mhe.png) + +### Спроектуйте рейтинг продажів Amazon за категоріями + +[Переглянути завдання та рішення](solutions/system_design/sales_rank/README.md) + +![Imgur](images/MzExP06.png) + +### Спроектуйте систему, яка масштабується до мільйонів користувачів на AWS + +[Переглянути завдання та рішення](solutions/system_design/scaling_aws/README.md) + +![Imgur](images/jj3A5N8.png) + +## Питання співбесіди з об'єктно-орієнтованого проектування з рішеннями + +> Типові питання співбесіди з об'єктно-орієнтованого проектування зі зразками обговорень, кодом та діаграмами. +> +> Рішення пов'язані з контентом у папці `solutions/`. + +>**Примітка: Цей розділ у розробці** + +| Питання | | +|---|---| +| Спроектуйте хеш-таблицю | [Рішення](solutions/object_oriented_design/hash_table/hash_map.ipynb) | +| Спроектуйте LRU кеш | [Рішення](solutions/object_oriented_design/lru_cache/lru_cache.ipynb) | +| Спроектуйте кол-центр | [Рішення](solutions/object_oriented_design/call_center/call_center.ipynb) | +| Спроектуйте колоду карт | [Рішення](solutions/object_oriented_design/deck_of_cards/deck_of_cards.ipynb) | +| Спроектуйте парковку | [Рішення](solutions/object_oriented_design/parking_lot/parking_lot.ipynb) | +| Спроектуйте чат-сервер | [Рішення](solutions/object_oriented_design/online_chat/online_chat.ipynb) | +| Спроектуйте циклічний масив | [Долучитися](#як-долучитися) | +| Додати питання з об'єктно-орієнтованого проектування | [Долучитися](#як-долучитися) | + +## Теми проектування систем: почніть тут + +Новачок у проектуванні систем? + +Спочатку вам потрібно базове розуміння загальних принципів, вивчення того, що вони собою являють, як використовуються, їх переваги та недоліки. + +### Крок 1: Перегляньте відеолекцію про масштабованість + +[Лекція про масштабованість у Гарварді](https://www.youtube.com/watch?v=-W9F__D3oY4) + +* Теми: + * Вертикальне масштабування + * Горизонтальне масштабування + * Кешування + * Балансування навантаження + * Реплікація бази даних + * Партиціонування бази даних + +### Крок 2: Прочитайте статтю про масштабованість + +[Масштабованість](https://web.archive.org/web/20221030091841/http://www.lecloud.net/tagged/scalability/chrono) + +* Теми: + * [Клони](https://web.archive.org/web/20220530193911/https://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) + * [Бази даних](https://web.archive.org/web/20220602114024/https://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) + * [Кеші](https://web.archive.org/web/20230126233752/https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) + * [Асинхронність](https://web.archive.org/web/20220926171507/https://www.lecloud.net/post/9699762917/scalability-for-dummies-part-4-asynchronism) + +### Наступні кроки + +Далі ми розглянемо високорівневі компроміси: + +* **Продуктивність** vs **масштабованість** +* **Затримка** vs **пропускна здатність** +* **Доступність** vs **узгодженість** + +Пам'ятайте, що **все є компромісом**. + +Потім ми заглибимось у більш конкретні теми, такі як DNS, CDN та балансувальники навантаження. + +## Продуктивність vs масштабованість + +Сервіс є **масштабованим**, якщо він призводить до підвищення **продуктивності** пропорційно доданим ресурсам. Загалом, підвищення продуктивності означає обслуговування більшої кількості одиниць роботи, але це також може означати обробку більших одиниць роботи, наприклад, коли набори даних зростають.1 + +Інший спосіб поглянути на продуктивність vs масштабованість: + +* Якщо у вас проблема з **продуктивністю**, ваша система повільна для одного користувача. +* Якщо у вас проблема з **масштабованістю**, ваша система швидка для одного користувача, але повільна під великим навантаженням. + +### Джерела та додаткове читання + +* [Слово про масштабованість](http://www.allthingsdistributed.com/2006/03/a_word_on_scalability.html) +* [Масштабованість, доступність, стабільність, патерни](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) + +## Затримка vs пропускна здатність + +**Затримка** — це час для виконання певної дії або отримання результату. + +**Пропускна здатність** — це кількість таких дій або результатів за одиницю часу. + +Загалом, слід прагнути до **максимальної пропускної здатності** при **прийнятній затримці**. + +### Джерела та додаткове читання + +* [Розуміння затримки vs пропускної здатності](https://community.cadence.com/cadence_blogs_8/b/fv/posts/understanding-latency-vs-throughput) + +## Доступність vs узгодженість + +### Теорема CAP + +

+ +
+ Джерело: CAP theorem revisited +

+ +У розподіленій комп'ютерній системі ви можете підтримувати лише дві з наступних трьох гарантій: + +* **Узгодженість (Consistency)** — кожне читання отримує найостанніший запис або помилку +* **Доступність (Availability)** — кожен запит отримує відповідь, без гарантії, що вона містить найактуальнішу версію інформації +* **Стійкість до розділення (Partition Tolerance)** — система продовжує працювати, незважаючи на довільне розділення через мережеві збої + +*Мережі ненадійні, тому вам потрібно підтримувати стійкість до розділення. Вам доведеться робити програмний компроміс між узгодженістю та доступністю.* + +#### CP — узгодженість та стійкість до розділення + +Очікування відповіді від розділеного вузла може призвести до помилки тайм-ауту. CP — хороший вибір, якщо ваші бізнес-вимоги потребують атомарних читань та записів. + +#### AP — доступність та стійкість до розділення + +Відповіді повертають найбільш доступну версію даних на будь-якому вузлі, яка може бути не найактуальнішою. Записи можуть зайняти деякий час для поширення після вирішення розділення. + +AP — хороший вибір, якщо бізнес-потреби дозволяють [кінцеву узгодженість](#eventual-consistency-кінцева-узгодженість) або коли система повинна продовжувати працювати, незважаючи на зовнішні помилки. + +### Джерела та додаткове читання + +* [CAP theorem revisited](https://robertgreiner.com/cap-theorem-revisited/) +* [Простий вступ до теореми CAP англійською](http://ksat.me/a-plain-english-introduction-to-cap-theorem) +* [CAP FAQ](https://github.com/henryr/cap-faq) +* [Теорема CAP](https://www.youtube.com/watch?v=k-Yaq8AHlFA) + +## Патерни узгодженості + +Маючи кілька копій одних і тих самих даних, ми стикаємось з варіантами їх синхронізації, щоб клієнти мали узгоджене уявлення про дані. Згадайте визначення узгодженості з [теореми CAP](#теорема-cap) — кожне читання отримує найостанніший запис або помилку. + +### Слабка узгодженість + +Після запису читання може побачити або не побачити його. Використовується підхід найкращих зусиль. + +Цей підхід використовується в системах, таких як memcached. Слабка узгодженість добре працює в реальному часі, наприклад, у VoIP, відеочатах та багатокористувацьких іграх у реальному часі. Наприклад, якщо ви розмовляєте по телефону і втрачаєте зв'язок на кілька секунд, коли з'єднання відновлюється, ви не чуєте того, що було сказано під час втрати з'єднання. + +### Eventual consistency (кінцева узгодженість) + +Після запису читання з часом побачить його (зазвичай протягом мілісекунд). Дані реплікуються асинхронно. + +Цей підхід використовується в системах, таких як DNS та електронна пошта. Кінцева узгодженість добре працює у високодоступних системах. + +### Сильна узгодженість + +Після запису читання побачить його. Дані реплікуються синхронно. + +Цей підхід використовується у файлових системах та РСУБД. Сильна узгодженість добре працює в системах, які потребують транзакцій. + +### Джерела та додаткове читання + +* [Транзакції між дата-центрами](http://snarfed.org/transactions_across_datacenters_io.html) + +## Патерни доступності + +Існує два взаємодоповнюючі патерни для підтримки високої доступності: **відмовостійкість** та **реплікація**. + +### Відмовостійкість (Fail-over) + +#### Активний-пасивний + +При активно-пасивній відмовостійкості heartbeat-сигнали надсилаються між активним та пасивним сервером у режимі очікування. Якщо heartbeat переривається, пасивний сервер перебирає IP-адресу активного і відновлює роботу. + +Тривалість простою визначається тим, чи працює пасивний сервер у «гарячому» режимі очікування, чи потрібен «холодний» запуск. Трафік обробляє лише активний сервер. + +Активно-пасивну відмовостійкість також називають master-slave відмовостійкістю. + +#### Активний-активний + +При активно-активній конфігурації обидва сервери обробляють трафік, розподіляючи навантаження між собою. + +Якщо сервери є публічними, DNS повинен знати публічні IP обох серверів. Якщо сервери є внутрішніми, логіка додатку повинна знати про обидва сервери. + +Активно-активну відмовостійкість також називають master-master відмовостійкістю. + +### Недоліки: відмовостійкість + +* Відмовостійкість додає більше обладнання та додаткову складність. +* Існує потенційна втрата даних, якщо активна система виходить з ладу до того, як нові записані дані можуть бути реплікувані на пасивну. + +### Реплікація + +#### Master-slave та master-master + +Ця тема детальніше обговорюється в розділі [База даних](#база-даних): + +* [Реплікація master-slave](#реплікація-master-slave) +* [Реплікація master-master](#реплікація-master-master) + +### Доступність у цифрах + +Доступність часто визначається часом безвідмовної роботи (або простою) як відсоток часу, протягом якого сервіс доступний. Доступність зазвичай вимірюється кількістю дев'яток — сервіс з доступністю 99,99% описується як такий, що має чотири дев'ятки. + +#### Доступність 99,9% — три дев'ятки + +| Тривалість | Допустимий простій | +|---|---| +| Простій на рік | 8 год 45 хв 57 с | +| Простій на місяць | 43 хв 49,7 с | +| Простій на тиждень | 10 хв 4,8 с | +| Простій на день | 1 хв 26,4 с | + +#### Доступність 99,99% — чотири дев'ятки + +| Тривалість | Допустимий простій | +|---|---| +| Простій на рік | 52 хв 35,7 с | +| Простій на місяць | 4 хв 23 с | +| Простій на тиждень | 1 хв 5 с | +| Простій на день | 8,6 с | + +#### Доступність паралельно vs послідовно + +Якщо сервіс складається з кількох компонентів, схильних до відмов, загальна доступність сервісу залежить від того, чи компоненти з'єднані послідовно чи паралельно. + +###### Послідовно + +Загальна доступність зменшується, коли два компоненти з доступністю < 100% з'єднані послідовно: + +``` +Доступність (Загальна) = Доступність (Foo) * Доступність (Bar) +``` + +Якщо `Foo` та `Bar` мають по 99,9% доступності, їхня загальна доступність послідовно буде 99,8%. + +###### Паралельно + +Загальна доступність збільшується, коли два компоненти з доступністю < 100% з'єднані паралельно: + +``` +Доступність (Загальна) = 1 - (1 - Доступність (Foo)) * (1 - Доступність (Bar)) +``` + +Якщо `Foo` та `Bar` мають по 99,9% доступності, їхня загальна доступність паралельно буде 99,9999%. + +## Система доменних імен (DNS) + +

+ +
+ Джерело: DNS security presentation +

+ +Система доменних імен (DNS) перетворює доменне ім'я, таке як www.example.com, на IP-адресу. + +DNS є ієрархічною, з кількома авторитетними серверами на верхньому рівні. Ваш роутер або ISP надає інформацію про те, до якого DNS-сервера звертатися при пошуку. DNS-сервери нижчого рівня кешують відображення, які можуть застаріти через затримки поширення DNS. Результати DNS також можуть кешуватися вашим браузером або ОС протягом певного періоду часу, визначеного [часом життя (TTL)](https://en.wikipedia.org/wiki/Time_to_live). + +* **NS запис (name server)** — визначає DNS-сервери для вашого домену/піддомену. +* **MX запис (mail exchange)** — визначає поштові сервери для прийому повідомлень. +* **A запис (address)** — вказує ім'я на IP-адресу. +* **CNAME (canonical)** — вказує ім'я на інше ім'я або `CNAME` (example.com на www.example.com) або на `A` запис. + +Такі сервіси, як [CloudFlare](https://www.cloudflare.com/dns/) та [Route 53](https://aws.amazon.com/route53/), надають керовані DNS-сервіси. Деякі DNS-сервіси можуть маршрутизувати трафік різними методами: + +* [Зважений round robin](https://www.jscape.com/blog/load-balancing-algorithms) + * Запобігає трафіку на сервери в режимі обслуговування + * Балансує між кластерами різного розміру + * A/B тестування +* [На основі затримки](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-latency.html) +* [На основі геолокації](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-geo.html) + +### Недоліки: DNS + +* Доступ до DNS-сервера вносить невелику затримку, хоча це пом'якшується кешуванням, описаним вище. +* Управління DNS-серверами може бути складним і зазвичай здійснюється [урядами, ISP та великими компаніями](http://superuser.com/questions/472695/who-controls-the-dns-servers/472729). +* DNS-сервіси нещодавно зазнали [DDoS-атаки](http://dyn.com/blog/dyn-analysis-summary-of-friday-october-21-attack/), що не дозволяло користувачам отримати доступ до Twitter без знання IP-адреси Twitter. + +### Джерела та додаткове читання + +* [Архітектура DNS](https://technet.microsoft.com/en-us/library/dd197427(v=ws.10).aspx) +* [Wikipedia](https://en.wikipedia.org/wiki/Domain_Name_System) +* [Статті про DNS](https://support.dnsimple.com/categories/dns/) + +## Мережа доставки контенту (CDN) + +

+ +
+ Джерело: Why use a CDN +

+ +Мережа доставки контенту (CDN) — це глобально розподілена мережа проксі-серверів, що обслуговує контент з локацій, ближчих до користувача. Зазвичай статичні файли, такі як HTML/CSS/JS, фото та відео, обслуговуються з CDN, хоча деякі CDN, такі як Amazon CloudFront, підтримують динамічний контент. DNS-резолюція сайту повідомляє клієнтам, до якого сервера звертатися. + +Обслуговування контенту з CDN може значно покращити продуктивність двома способами: + +* Користувачі отримують контент з дата-центрів, розташованих ближче до них +* Ваші сервери не повинні обслуговувати запити, які виконує CDN + +### Push CDN + +Push CDN отримують новий контент кожного разу, коли на вашому сервері відбуваються зміни. Ви берете повну відповідальність за надання контенту, завантаження безпосередньо на CDN та переписування URL для вказівки на CDN. Ви можете налаштувати, коли контент закінчується та коли оновлюється. Контент завантажується лише коли він новий або змінений, мінімізуючи трафік, але максимізуючи зберігання. + +Сайти з невеликим трафіком або контентом, який не часто оновлюється, добре працюють з push CDN. Контент розміщується на CDN один раз, замість регулярного повторного отримання. + +### Pull CDN + +Pull CDN отримують новий контент з вашого сервера, коли перший користувач запитує контент. Ви залишаєте контент на своєму сервері та переписуєте URL для вказівки на CDN. Це призводить до повільнішого запиту, поки контент не буде кешовано на CDN. + +[Time-to-live (TTL)](https://en.wikipedia.org/wiki/Time_to_live) визначає, як довго контент кешується. Pull CDN мінімізують простір зберігання на CDN, але можуть створювати надлишковий трафік, якщо файли закінчуються та отримуються повторно до того, як вони фактично змінилися. + +Сайти з великим трафіком добре працюють з pull CDN, оскільки трафік розподіляється більш рівномірно, і лише нещодавно запитаний контент залишається на CDN. + +### Недоліки: CDN + +* Витрати на CDN можуть бути значними залежно від трафіку, хоча це слід зважувати з додатковими витратами, які ви понесете без використання CDN. +* Контент може застаріти, якщо він оновлюється до закінчення TTL. +* CDN вимагають зміни URL для статичного контенту для вказівки на CDN. + +### Джерела та додаткове читання + +* [Глобально розподілена доставка контенту](https://figshare.com/articles/Globally_distributed_content_delivery/6605972) +* [Різниця між push та pull CDN](http://www.travelblogadvice.com/technical/the-differences-between-push-and-pull-cdns/) +* [Wikipedia](https://en.wikipedia.org/wiki/Content_delivery_network) + +## Балансувальник навантаження + +

+ +
+ Джерело: Scalable system design patterns +

+ +Балансувальники навантаження розподіляють вхідні клієнтські запити на обчислювальні ресурси, такі як сервери додатків та бази даних. У кожному випадку балансувальник навантаження повертає відповідь від обчислювального ресурсу відповідному клієнту. Балансувальники навантаження ефективні для: + +* Запобігання запитам до несправних серверів +* Запобігання перевантаженню ресурсів +* Допомоги в усуненні єдиної точки відмови + +Балансувальники навантаження можуть бути реалізовані за допомогою обладнання (дороге) або програмного забезпечення, такого як HAProxy. + +Додаткові переваги включають: + +* **SSL termination** — розшифрування вхідних запитів та шифрування відповідей сервера, щоб бекенд-сервери не виконували ці потенційно дорогі операції + * Усуває потребу встановлювати [сертифікати X.509](https://en.wikipedia.org/wiki/X.509) на кожному сервері +* **Постійність сесії** — видача cookie та маршрутизація запитів конкретного клієнта до того самого екземпляру, якщо веб-додатки не відстежують сесії + +Для захисту від відмов прийнято налаштовувати кілька балансувальників навантаження в режимі [активний-пасивний](#активний-пасивний) або [активний-активний](#активний-активний). + +Балансувальники навантаження можуть маршрутизувати трафік на основі різних метрик, включаючи: + +* Випадковий +* Найменш завантажений +* Сесія/cookie +* [Round robin або зважений round robin](https://www.g33kinfo.com/info/round-robin-vs-weighted-round-robin-lb) +* [Layer 4](#балансування-на-рівні-layer-4) +* [Layer 7](#балансування-на-рівні-layer-7) + +### Балансування на рівні Layer 4 + +Балансувальники навантаження Layer 4 дивляться на інформацію на [транспортному рівні](#комунікація), щоб вирішити, як розподілити запити. Зазвичай це включає IP-адреси джерела та призначення, порти в заголовку, але не вміст пакета. Балансувальники навантаження Layer 4 пересилають мережеві пакети до та від upstream-сервера, виконуючи [Network Address Translation (NAT)](https://www.nginx.com/resources/glossary/layer-4-load-balancing/). + +### Балансування на рівні Layer 7 + +Балансувальники навантаження Layer 7 дивляться на [прикладний рівень](#комунікація), щоб вирішити, як розподілити запити. Це може включати вміст заголовка, повідомлення та cookie. Балансувальники навантаження Layer 7 завершують мережевий трафік, читають повідомлення, приймають рішення про балансування, потім відкривають з'єднання з обраним сервером. Наприклад, балансувальник навантаження Layer 7 може направити відео-трафік на сервери, які хостять відео, одночасно направляючи більш чутливий трафік білінгу користувачів на сервери з посиленою безпекою. + +Ціною гнучкості, балансування Layer 4 вимагає менше часу та обчислювальних ресурсів, ніж Layer 7, хоча вплив на продуктивність може бути мінімальним на сучасному commodity-обладнанні. + +### Горизонтальне масштабування + +Балансувальники навантаження також можуть допомогти з горизонтальним масштабуванням, покращуючи продуктивність та доступність. Масштабування шляхом додавання commodity-машин є більш економічно ефективним і забезпечує вищу доступність, ніж масштабування одного сервера на дорожчому обладнанні, що називається **вертикальним масштабуванням**. Також легше наймати таланти для роботи з commodity-обладнанням, ніж зі спеціалізованими корпоративними системами. + +#### Недоліки: горизонтальне масштабування + +* Горизонтальне масштабування вносить складність і включає клонування серверів + * Сервери повинні бути stateless: вони не повинні містити жодних даних, пов'язаних з користувачем, таких як сесії або фотографії профілю + * Сесії можуть зберігатися в централізованому сховищі даних, такому як [база даних](#база-даних) (SQL, NoSQL) або постійний [кеш](#кеш) (Redis, Memcached) +* Downstream-сервери, такі як кеші та бази даних, повинні обробляти більше одночасних з'єднань, коли upstream-сервери масштабуються + +### Недоліки: балансувальник навантаження + +* Балансувальник навантаження може стати вузьким місцем продуктивності, якщо не має достатніх ресурсів або неправильно налаштований. +* Введення балансувальника навантаження для усунення єдиної точки відмови призводить до збільшення складності. +* Один балансувальник навантаження є єдиною точкою відмови, налаштування кількох балансувальників ще більше збільшує складність. + +### Джерела та додаткове читання + +* [Архітектура NGINX](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +* [Посібник з архітектури HAProxy](http://www.haproxy.org/download/1.2/doc/architecture.txt) +* [Масштабованість](https://web.archive.org/web/20220530193911/https://www.lecloud.net/post/7295452622/scalability-for-dummies-part-1-clones) +* [Wikipedia](https://en.wikipedia.org/wiki/Load_balancing_(computing)) +* [Балансування навантаження Layer 4](https://www.nginx.com/resources/glossary/layer-4-load-balancing/) +* [Балансування навантаження Layer 7](https://www.nginx.com/resources/glossary/layer-7-load-balancing/) +* [Конфігурація ELB listener](http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html) + +## Зворотний проксі (веб-сервер) + +

+ +
+ Джерело: Wikipedia +
+

+ +Зворотний проксі — це веб-сервер, який централізує внутрішні сервіси та надає уніфіковані інтерфейси для зовнішнього світу. Запити від клієнтів пересилаються на сервер, який може їх виконати, перш ніж зворотний проксі поверне відповідь сервера клієнту. + +Додаткові переваги включають: + +* **Підвищена безпека** — приховування інформації про бекенд-сервери, внесення IP до чорного списку, обмеження кількості з'єднань на клієнта +* **Підвищена масштабованість та гнучкість** — клієнти бачать лише IP зворотного проксі, що дозволяє масштабувати сервери або змінювати їх конфігурацію +* **SSL termination** — розшифрування вхідних запитів та шифрування відповідей сервера, щоб бекенд-сервери не виконували ці потенційно дорогі операції + * Усуває потребу встановлювати [сертифікати X.509](https://en.wikipedia.org/wiki/X.509) на кожному сервері +* **Стиснення** — стиснення відповідей сервера +* **Кешування** — повернення відповіді для кешованих запитів +* **Статичний контент** — обслуговування статичного контенту безпосередньо + * HTML/CSS/JS + * Фото + * Відео + * Тощо + +### Балансувальник навантаження vs зворотний проксі + +* Розгортання балансувальника навантаження корисне, коли у вас є кілька серверів. Часто балансувальники навантаження маршрутизують трафік на набір серверів, які виконують однакові функції. +* Зворотні проксі можуть бути корисними навіть з одним веб-сервером або сервером додатків, відкриваючи переваги, описані в попередньому розділі. +* Рішення, такі як NGINX та HAProxy, можуть підтримувати як Layer 7 reverse proxy, так і балансування навантаження. + +### Недоліки: зворотний проксі + +* Введення зворотного проксі призводить до збільшення складності. +* Один зворотний проксі є єдиною точкою відмови, налаштування кількох зворотних проксі (тобто [failover](https://en.wikipedia.org/wiki/Failover)) ще більше збільшує складність. + +### Джерела та додаткове читання + +* [Зворотний проксі vs балансувальник навантаження](https://www.nginx.com/resources/glossary/reverse-proxy-vs-load-balancer/) +* [Архітектура NGINX](https://www.nginx.com/blog/inside-nginx-how-we-designed-for-performance-scale/) +* [Посібник з архітектури HAProxy](http://www.haproxy.org/download/1.2/doc/architecture.txt) +* [Wikipedia](https://en.wikipedia.org/wiki/Reverse_proxy) + +## Прикладний рівень + +

+ +
+ Джерело: Intro to architecting systems for scale +

+ +Відокремлення веб-рівня від прикладного рівня (також відомого як платформний рівень) дозволяє масштабувати та налаштовувати обидва рівні незалежно. Додавання нового API призводить до додавання серверів додатків без обов'язкового додавання додаткових веб-серверів. **Принцип єдиної відповідальності** виступає за малі та автономні сервіси, які працюють разом. Невеликі команди з невеликими сервісами можуть більш агресивно планувати швидке зростання. + +Workers на прикладному рівні також допомагають забезпечити [асинхронність](#асинхронність). + +### Мікросервіси + +Пов'язаними з цим обговоренням є [мікросервіси](https://en.wikipedia.org/wiki/Microservices), які можна описати як набір незалежно розгортуваних, малих, модульних сервісів. Кожен сервіс запускає унікальний процес і взаємодіє через чітко визначений, легкий механізм для досягнення бізнес-цілі. 1 + +Наприклад, Pinterest може мати наступні мікросервіси: профіль користувача, підписники, стрічка, пошук, завантаження фото тощо. + +### Виявлення сервісів + +Системи, такі як [Consul](https://www.consul.io/docs/index.html), [Etcd](https://coreos.com/etcd/docs/latest) та [Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper), можуть допомогти сервісам знаходити один одного, відстежуючи зареєстровані імена, адреси та порти. [Health checks](https://www.consul.io/intro/getting-started/checks.html) допомагають перевірити цілісність сервісу і часто виконуються за допомогою [HTTP](#протокол-http) endpoint. Consul та Etcd мають вбудоване [сховище ключ-значення](#сховище-ключ-значення), яке може бути корисним для зберігання конфігураційних значень та інших спільних даних. + +### Недоліки: прикладний рівень + +* Додавання прикладного рівня зі слабко зв'язаними сервісами вимагає іншого підходу з архітектурної, операційної та процесної точки зору (порівняно з монолітною системою). +* Мікросервіси можуть додати складності в плані розгортання та операцій. + +### Джерела та додаткове читання + +* [Вступ до архітектури систем для масштабування](http://lethain.com/introduction-to-architecting-systems-for-scale) +* [Crack the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) +* [Сервіс-орієнтована архітектура](https://en.wikipedia.org/wiki/Service-oriented_architecture) +* [Вступ до Zookeeper](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) +* [Ось що потрібно знати про побудову мікросервісів](https://cloudncode.wordpress.com/2016/07/22/msa-getting-started/) + +## База даних + +

+ +
+ Джерело: Scaling up to your first 10 million users +

+ +### Реляційна СУБД (RDBMS) + +Реляційна база даних, така як SQL, — це колекція елементів даних, організованих у таблиці. + +**ACID** — це набір властивостей [транзакцій](https://en.wikipedia.org/wiki/Database_transaction) реляційної бази даних. + +* **Атомарність (Atomicity)** — кожна транзакція або виконується повністю, або не виконується взагалі +* **Узгодженість (Consistency)** — будь-яка транзакція переведе базу даних з одного допустимого стану в інший +* **Ізольованість (Isolation)** — паралельне виконання транзакцій дає такий самий результат, як якби транзакції виконувались послідовно +* **Довговічність (Durability)** — після фіксації транзакції вона залишається зафіксованою + +Існує багато технік для масштабування реляційної бази даних: **реплікація master-slave**, **реплікація master-master**, **федерація**, **шардинг**, **денормалізація** та **оптимізація SQL**. + +#### Реплікація master-slave + +Master обслуговує читання та запис, реплікуючи записи на один або кілька slave, які обслуговують лише читання. Slave також можуть реплікуватись на додаткові slave деревоподібним чином. Якщо master виходить з ладу, система може продовжувати працювати в режимі лише читання, поки slave не буде підвищено до master або не буде наданий новий master. + +

+ +
+ Джерело: Scalability, availability, stability, patterns +

+ +##### Недоліки: реплікація master-slave + +* Потрібна додаткова логіка для підвищення slave до master. +* Див. [Недоліки: реплікація](#недоліки-реплікація) для пунктів, що стосуються **обох** master-slave та master-master. + +#### Реплікація master-master + +Обидва master обслуговують читання та запис і координуються між собою при записах. Якщо будь-який master виходить з ладу, система може продовжувати працювати як з читанням, так і з записом. + +

+ +
+ Джерело: Scalability, availability, stability, patterns +

+ +##### Недоліки: реплікація master-master + +* Вам потрібен балансувальник навантаження або зміни в логіці додатку, щоб визначити, куди писати. +* Більшість систем master-master або мають слабку узгодженість (порушуючи ACID), або мають збільшену затримку запису через синхронізацію. +* Вирішення конфліктів стає більш актуальним при додаванні більшої кількості вузлів запису та збільшенні затримки. +* Див. [Недоліки: реплікація](#недоліки-реплікація) для пунктів, що стосуються **обох** master-slave та master-master. + +##### Недоліки: реплікація + +* Існує потенційна втрата даних, якщо master виходить з ладу до того, як нові записані дані можуть бути репліковані на інші вузли. +* Записи відтворюються на read-репліках. Якщо записів багато, read-репліки можуть зависнути на відтворенні записів і не виконувати стільки читань. +* Чим більше read-slave, тим більше потрібно реплікувати, що призводить до більшого відставання реплікації. +* В деяких системах запис на master може породжувати кілька потоків для паралельного запису, тоді як read-репліки підтримують лише послідовний запис одним потоком. +* Реплікація додає більше обладнання та додаткову складність. + +##### Джерела та додаткове читання: реплікація + +* [Масштабованість, доступність, стабільність, патерни](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +* [Мульти-master реплікація](https://en.wikipedia.org/wiki/Multi-master_replication) + +#### Федерація + +

+ +
+ Джерело: Scaling up to your first 10 million users +

+ +Федерація (або функціональне партиціонування) розділяє бази даних за функціями. Наприклад, замість однієї монолітної бази даних ви можете мати три бази даних: **форуми**, **користувачі** та **продукти**, що призводить до меншого трафіку читання та запису до кожної бази даних і, отже, меншого відставання реплікації. Менші бази даних означають більше даних, які можуть поміститися в пам'яті, що, в свою чергу, призводить до більшої кількості попадань у кеш через покращену локальність кешу. Без єдиного центрального master, що серіалізує записи, ви можете писати паралельно, збільшуючи пропускну здатність. + +##### Недоліки: федерація + +* Федерація неефективна, якщо ваша схема вимагає величезних функцій або таблиць. +* Вам потрібно оновити логіку додатку, щоб визначити, яку базу даних читати та писати. +* Об'єднання даних з двох баз даних є складнішим за допомогою [server link](http://stackoverflow.com/questions/5145637/querying-data-by-joining-two-tables-in-two-database-on-different-servers). +* Федерація додає більше обладнання та додаткову складність. + +##### Джерела та додаткове читання: федерація + +* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=kKjm4ehYiMs) + +#### Шардинг + +

+ +
+ Джерело: Scalability, availability, stability, patterns +

+ +Шардинг розподіляє дані між різними базами даних так, що кожна база даних може керувати лише підмножиною даних. Беручи базу даних користувачів як приклад, при збільшенні кількості користувачів до кластера додаються нові шарди. + +Подібно до переваг [федерації](#федерація), шардинг призводить до меншого трафіку читання та запису, меншої реплікації та більшої кількості попадань у кеш. Розмір індексу також зменшується, що зазвичай покращує продуктивність та прискорює запити. Якщо один шард виходить з ладу, інші шарди все ще працюють, хоча вам потрібно додати якусь форму реплікації, щоб уникнути втрати даних. Як і федерація, без єдиного центрального master ви можете писати паралельно, збільшуючи пропускну здатність. + +Поширені способи шардингу таблиці користувачів — за першою літерою прізвища користувача або за географічним розташуванням користувача. + +##### Недоліки: шардинг + +* Вам потрібно оновити логіку додатку для роботи з шардами, що може призвести до складних SQL-запитів. +* Розподіл даних може стати нерівномірним у шарді. Наприклад, набір активних користувачів на шарді може призвести до збільшеного навантаження на цей шард порівняно з іншими. + * Перебалансування додає додаткової складності. Функція шардингу на основі [consistent hashing](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) може зменшити кількість переданих даних. +* Об'єднання даних з кількох шардів є складнішим. +* Шардинг додає більше обладнання та додаткову складність. + +##### Джерела та додаткове читання: шардинг + +* [Прихід шардів](http://highscalability.com/blog/2009/8/6/an-unorthodox-approach-to-database-design-the-coming-of-the.html) +* [Архітектура шардованої бази даних](https://en.wikipedia.org/wiki/Shard_(database_architecture)) +* [Consistent hashing](http://www.paperplanes.de/2011/12/9/the-magic-of-consistent-hashing.html) + +#### Денормалізація + +Денормалізація намагається покращити продуктивність читання за рахунок деякої продуктивності запису. Надлишкові копії даних записуються в кілька таблиць, щоб уникнути дорогих join-ів. Деякі РСУБД, такі як [PostgreSQL](https://en.wikipedia.org/wiki/PostgreSQL) та Oracle, підтримують [materialized views](https://en.wikipedia.org/wiki/Materialized_view), які обробляють роботу зі зберіганням надлишкової інформації та підтримкою узгодженості надлишкових копій. + +Коли дані стають розподіленими за допомогою таких технік, як [федерація](#федерація) та [шардинг](#шардинг), управління join-ами між дата-центрами ще більше збільшує складність. Денормалізація може обійти потребу в таких складних join-ах. + +У більшості систем читання може значно переважати записи у співвідношенні 100:1 або навіть 1000:1. Читання, що призводить до складного join бази даних, може бути дуже дорогим, витрачаючи значний час на дискові операції. + +##### Недоліки: денормалізація + +* Дані дублюються. +* Обмеження можуть допомогти тримати надлишкові копії інформації синхронізованими, що збільшує складність дизайну бази даних. +* Денормалізована база даних під великим навантаженням запису може працювати гірше, ніж її нормалізований аналог. + +###### Джерела та додаткове читання: денормалізація + +* [Денормалізація](https://en.wikipedia.org/wiki/Denormalization) + +#### Оптимізація SQL + +Оптимізація SQL — це широка тема, і багато [книг](https://www.amazon.com/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=sql+tuning) написано як довідники. + +Важливо **бенчмаркувати** та **профілювати** для симуляції та виявлення вузьких місць. + +* **Бенчмарк** — симуляція високонавантажених ситуацій за допомогою інструментів, таких як [ab](http://httpd.apache.org/docs/2.2/programs/ab.html). +* **Профіль** — увімкнення інструментів, таких як [slow query log](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html), для відстеження проблем продуктивності. + +Бенчмаркування та профілювання можуть вказати вам на наступні оптимізації. + +##### Обмежте схему + +* MySQL скидає на диск у суміжних блоках для швидкого доступу. +* Використовуйте `CHAR` замість `VARCHAR` для полів фіксованої довжини. + * `CHAR` ефективно дозволяє швидкий випадковий доступ, тоді як з `VARCHAR` потрібно знайти кінець рядка, перш ніж переходити до наступного. +* Використовуйте `TEXT` для великих блоків тексту, таких як пости блогу. `TEXT` також дозволяє булевий пошук. Використання поля `TEXT` призводить до зберігання вказівника на диску, який використовується для знаходження текстового блоку. +* Використовуйте `INT` для більших чисел до 2^32 або 4 мільярди. +* Використовуйте `DECIMAL` для валюти, щоб уникнути помилок представлення з плаваючою комою. +* Уникайте зберігання великих `BLOBS`, зберігайте натомість розташування, де отримати об'єкт. +* `VARCHAR(255)` — це найбільша кількість символів, яку можна порахувати 8-бітним числом, часто максимізуючи використання байта в деяких РСУБД. +* Встановлюйте обмеження `NOT NULL` там, де це можливо, для [покращення продуктивності пошуку](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search). + +##### Використовуйте хороші індекси + +* Стовпці, за якими ви робите запити (`SELECT`, `GROUP BY`, `ORDER BY`, `JOIN`), можуть бути швидшими з індексами. +* Індекси зазвичай представлені як самобалансуючі [B-дерева](https://en.wikipedia.org/wiki/B-tree), які тримають дані відсортованими і дозволяють пошук, послідовний доступ, вставки та видалення за логарифмічний час. +* Розміщення індексу може тримати дані в пам'яті, вимагаючи більше місця. +* Записи також можуть бути повільнішими, оскільки індекс також потрібно оновлювати. +* При завантаженні великих обсягів даних може бути швидше вимкнути індекси, завантажити дані, потім перебудувати індекси. + +##### Уникайте дорогих join-ів + +* [Денормалізуйте](#денормалізація) там, де цього вимагає продуктивність. + +##### Партиціонування таблиць + +* Розбийте таблицю, помістивши гарячі точки в окрему таблицю, щоб тримати її в пам'яті. + +##### Налаштування кешу запитів + +* В деяких випадках [кеш запитів](https://dev.mysql.com/doc/refman/5.7/en/query-cache.html) може призвести до [проблем з продуктивністю](https://www.percona.com/blog/2016/10/12/mysql-5-7-performance-tuning-immediately-after-installation/). + +##### Джерела та додаткове читання: оптимізація SQL + +* [Поради з оптимізації запитів MySQL](http://aiddroid.com/10-tips-optimizing-mysql-queries-dont-suck/) +* [Чому VARCHAR(255) так часто використовується?](http://stackoverflow.com/questions/1217466/is-there-a-good-reason-i-see-varchar255-used-so-often-as-opposed-to-another-l) +* [Як null-значення впливають на продуктивність?](http://stackoverflow.com/questions/1017239/how-do-null-values-affect-performance-in-a-database-search) +* [Slow query log](http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html) + +### NoSQL + +NoSQL — це колекція елементів даних, представлених у **сховищі ключ-значення**, **документному сховищі**, **сховищі з широкими стовпцями** або **графовій базі даних**. Дані денормалізовані, і join-и зазвичай виконуються в коді додатку. Більшість NoSQL-сховищ не мають справжніх ACID-транзакцій і віддають перевагу [кінцевій узгодженості](#eventual-consistency-кінцева-узгодженість). + +**BASE** часто використовується для опису властивостей баз даних NoSQL. Порівняно з [теоремою CAP](#теорема-cap), BASE вибирає доступність замість узгодженості. + +* **Basically available (базова доступність)** — система гарантує доступність. +* **Soft state (м'який стан)** — стан системи може змінюватися з часом, навіть без введення. +* **Eventual consistency (кінцева узгодженість)** — система стане узгодженою через певний період часу, за умови, що система не отримує введення протягом цього періоду. + +На додаток до вибору між [SQL чи NoSQL](#sql-чи-nosql), корисно розуміти, який тип NoSQL-бази даних найкраще підходить для вашого випадку використання. Ми розглянемо **сховища ключ-значення**, **документні сховища**, **сховища з широкими стовпцями** та **графові бази даних** у наступному розділі. + +#### Сховище ключ-значення + +> Абстракція: хеш-таблиця + +Сховище ключ-значення зазвичай дозволяє читання та запис O(1) і часто підтримується пам'яттю або SSD. Сховища даних можуть підтримувати ключі в [лексикографічному порядку](https://en.wikipedia.org/wiki/Lexicographical_order), дозволяючи ефективне отримання діапазонів ключів. Сховища ключ-значення можуть дозволяти зберігання метаданих разом зі значенням. + +Сховища ключ-значення забезпечують високу продуктивність і часто використовуються для простих моделей даних або для даних, що швидко змінюються, таких як рівень кешу в пам'яті. Оскільки вони пропонують лише обмежений набір операцій, складність переноситься на рівень додатку, якщо потрібні додаткові операції. + +Сховище ключ-значення є основою для більш складних систем, таких як документне сховище, і в деяких випадках графова база даних. + +##### Джерела та додаткове читання: сховище ключ-значення + +* [База даних ключ-значення](https://en.wikipedia.org/wiki/Key-value_database) +* [Недоліки сховищ ключ-значення](http://stackoverflow.com/questions/4056093/what-are-the-disadvantages-of-using-a-key-value-table-over-nullable-columns-or) +* [Архітектура Redis](http://qnimate.com/overview-of-redis-architecture/) +* [Архітектура Memcached](https://adayinthelifeof.nl/2011/02/06/memcache-internals/) + +#### Документне сховище + +> Абстракція: сховище ключ-значення з документами як значеннями + +Документне сховище зосереджене навколо документів (XML, JSON, binary тощо), де документ зберігає всю інформацію для даного об'єкта. Документні сховища надають API або мову запитів для запитів на основі внутрішньої структури самого документа. *Примітка: багато сховищ ключ-значення включають функції для роботи з метаданими значення, розмиваючи межі між цими двома типами сховищ.* + +На основі базової реалізації документи організовані за колекціями, тегами, метаданими або каталогами. Хоча документи можуть бути організовані або згруповані разом, документи можуть мати поля, які повністю відрізняються один від одного. + +Деякі документні сховища, такі як [MongoDB](https://www.mongodb.com/mongodb-architecture) та [CouchDB](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/), також надають SQL-подібну мову для виконання складних запитів. [DynamoDB](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) підтримує як ключ-значення, так і документи. + +Документні сховища забезпечують високу гнучкість і часто використовуються для роботи з даними, що час від часу змінюються. + +##### Джерела та додаткове читання: документне сховище + +* [Документо-орієнтована база даних](https://en.wikipedia.org/wiki/Document-oriented_database) +* [Архітектура MongoDB](https://www.mongodb.com/mongodb-architecture) +* [Архітектура CouchDB](https://blog.couchdb.org/2016/08/01/couchdb-2-0-architecture/) +* [Архітектура Elasticsearch](https://www.elastic.co/blog/found-elasticsearch-from-the-bottom-up) + +#### Сховище з широкими стовпцями + +

+ +
+ Джерело: SQL & NoSQL, a brief history +

+ +> Абстракція: вкладена мапа `ColumnFamily>` + +Базовою одиницею даних сховища з широкими стовпцями є стовпець (пара ім'я/значення). Стовпець може бути згрупований у сімейства стовпців (аналогічно SQL-таблиці). Суперсімейства стовпців додатково групують сімейства стовпців. Ви можете отримати доступ до кожного стовпця незалежно за допомогою ключа рядка, а стовпці з однаковим ключем рядка утворюють рядок. Кожне значення містить мітку часу для версіонування та вирішення конфліктів. + +Google представив [Bigtable](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) як перше сховище з широкими стовпцями, яке вплинуло на open-source [HBase](https://www.edureka.co/blog/hbase-architecture/), часто використовуваний в екосистемі Hadoop, та [Cassandra](http://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html) від Facebook. Сховища, такі як BigTable, HBase та Cassandra, підтримують ключі в лексикографічному порядку, дозволяючи ефективне отримання вибіркових діапазонів ключів. + +Сховища з широкими стовпцями пропонують високу доступність та високу масштабованість. Вони часто використовуються для дуже великих наборів даних. + +##### Джерела та додаткове читання: сховище з широкими стовпцями + +* [SQL & NoSQL, коротка історія](http://blog.grio.com/2015/11/sql-nosql-a-brief-history.html) +* [Архітектура Bigtable](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) +* [Архітектура HBase](https://www.edureka.co/blog/hbase-architecture/) +* [Архітектура Cassandra](http://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html) + +#### Графова база даних + +

+ +
+ Джерело: Graph database +

+ +> Абстракція: граф + +У графовій базі даних кожен вузол є записом, а кожна дуга є зв'язком між двома вузлами. Графові бази даних оптимізовані для представлення складних зв'язків з багатьма зовнішніми ключами або зв'язками багато-до-багатьох. + +Графові бази даних пропонують високу продуктивність для моделей даних зі складними зв'язками, таких як соціальна мережа. Вони відносно нові і ще не широко використовуються; може бути складніше знайти інструменти розробки та ресурси. Багато графів можна отримати лише через [REST API](#rest). + +##### Джерела та додаткове читання: граф + +* [Графова база даних](https://en.wikipedia.org/wiki/Graph_database) +* [Neo4j](https://neo4j.com/) +* [FlockDB](https://blog.twitter.com/2010/introducing-flockdb) + +#### Джерела та додаткове читання: NoSQL + +* [Пояснення термінології BASE](http://stackoverflow.com/questions/3342497/explanation-of-base-terminology) +* [NoSQL бази даних: огляд та керівництво з вибору](https://medium.com/baqend-blog/nosql-databases-a-survey-and-decision-guidance-ea7823a822d#.wskogqenq) +* [Масштабованість](https://web.archive.org/web/20220602114024/https://www.lecloud.net/post/7994751381/scalability-for-dummies-part-2-database) +* [Вступ до NoSQL](https://www.youtube.com/watch?v=qI_g07C_Q5I) +* [Патерни NoSQL](http://horicky.blogspot.com/2009/11/nosql-patterns.html) + +### SQL чи NoSQL + +

+ +
+ Джерело: Transitioning from RDBMS to NoSQL +

+ +Причини для вибору **SQL**: + +* Структуровані дані +* Сувора схема +* Реляційні дані +* Потреба у складних join-ах +* Транзакції +* Чіткі патерни масштабування +* Більш зріла: розробники, спільнота, код, інструменти тощо +* Пошук за індексом дуже швидкий + +Причини для вибору **NoSQL**: + +* Напівструктуровані дані +* Динамічна або гнучка схема +* Нереляційні дані +* Немає потреби у складних join-ах +* Зберігання багатьох ТБ (або ПБ) даних +* Дуже інтенсивне робоче навантаження даних +* Дуже висока пропускна здатність для IOPS + +Зразки даних, які добре підходять для NoSQL: + +* Швидке отримання clickstream та log-даних +* Дані таблиці лідерів або scoring +* Тимчасові дані, такі як кошик покупок +* Часто доступні ('гарячі') таблиці +* Метадані/lookup-таблиці + +##### Джерела та додаткове читання: SQL чи NoSQL + +* [Scaling up to your first 10 million users](https://www.youtube.com/watch?v=kKjm4ehYiMs) +* [Різниця між SQL та NoSQL](https://www.sitepoint.com/sql-vs-nosql-differences/) + +## Кеш + +

+ +
+ Джерело: Scalable system design patterns +

+ +Кешування покращує час завантаження сторінок і може зменшити навантаження на ваші сервери та бази даних. У цій моделі диспетчер спочатку перевіряє, чи був запит зроблений раніше, і намагається знайти попередній результат для повернення, щоб зекономити фактичне виконання. + +Бази даних часто виграють від рівномірного розподілу читань та записів по своїх партиціях. Популярні елементи можуть спотворити розподіл, викликаючи вузькі місця. Розміщення кешу перед базою даних може допомогти поглинути нерівномірні навантаження та сплески трафіку. + +### Кешування на клієнті + +Кеші можуть бути розташовані на стороні клієнта (ОС або браузер), [на стороні сервера](#зворотний-проксі-веб-сервер) або в окремому рівні кешу. + +### Кешування CDN + +[CDN](#мережа-доставки-контенту-cdn) вважаються типом кешу. + +### Кешування веб-сервера + +[Зворотні проксі](#зворотний-проксі-веб-сервер) та кеші, такі як [Varnish](https://www.varnish-cache.org/), можуть обслуговувати статичний та динамічний контент безпосередньо. Веб-сервери також можуть кешувати запити, повертаючи відповіді без необхідності звертатися до серверів додатків. + +### Кешування бази даних + +Ваша база даних зазвичай включає деякий рівень кешування в конфігурації за замовчуванням, оптимізований для загального випадку використання. Налаштування цих параметрів для конкретних патернів використання може ще більше підвищити продуктивність. + +### Кешування додатку + +Кеші в пам'яті, такі як Memcached та Redis, є сховищами ключ-значення між вашим додатком та сховищем даних. Оскільки дані зберігаються в RAM, це набагато швидше, ніж типові бази даних, де дані зберігаються на диску. RAM більш обмежена, ніж диск, тому алгоритми [інвалідації кешу](https://en.wikipedia.org/wiki/Cache_algorithms), такі як [least recently used (LRU)](https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU)), можуть допомогти інвалідувати 'холодні' записи та зберігати 'гарячі' дані в RAM. + +Redis має наступні додаткові функції: + +* Опція персистентності +* Вбудовані структури даних, такі як відсортовані множини та списки + +Є кілька рівнів кешування, які потрапляють у дві загальні категорії: **запити до бази даних** та **об'єкти**: + +* Рівень рядків +* Рівень запитів +* Повністю сформовані серіалізовані об'єкти +* Повністю відрендерений HTML + +Загалом, слід уникати файлового кешування, оскільки воно ускладнює клонування та автомасштабування. + +### Кешування на рівні запитів до БД + +Кожного разу, коли ви запитуєте базу даних, хешуйте запит як ключ і зберігайте результат у кеші. Цей підхід страждає від проблем закінчення терміну: + +* Важко видалити кешований результат зі складними запитами +* Якщо одна частина даних змінюється, наприклад комірка таблиці, потрібно видалити всі кешовані запити, які можуть включати змінену комірку + +### Кешування на рівні об'єктів + +Розглядайте свої дані як об'єкт, подібно до того, як ви робите з кодом додатку. Нехай ваш додаток збирає набір даних з бази даних в екземпляр класу або структуру даних: + +* Видаляйте об'єкт з кешу, якщо його базові дані змінилися +* Дозволяє асинхронну обробку: workers збирають об'єкти, споживаючи останній кешований об'єкт + +Що кешувати: + +* Сесії користувачів +* Повністю відрендерені веб-сторінки +* Стрічки активності +* Дані графа користувачів + +### Коли оновлювати кеш + +Оскільки ви можете зберігати лише обмежену кількість даних у кеші, вам потрібно визначити, яка стратегія оновлення кешу найкраще підходить для вашого випадку використання. + +#### Cache-aside + +

+ +
+ Джерело: From cache to in-memory data grid +

+ +Додаток відповідає за читання та запис зі сховища. Кеш не взаємодіє зі сховищем безпосередньо. Додаток виконує наступне: + +* Шукає запис у кеші, що призводить до промаху кешу +* Завантажує запис з бази даних +* Додає запис до кешу +* Повертає запис + +```python +def get_user(self, user_id): + user = cache.get("user.{0}", user_id) + if user is None: + user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id) + if user is not None: + key = "user.{0}".format(user_id) + cache.set(key, json.dumps(user)) + return user +``` + +[Memcached](https://memcached.org/) зазвичай використовується таким чином. + +Подальші читання даних, доданих до кешу, є швидкими. Cache-aside також називають ледачим завантаженням. Кешуються лише запитані дані, що дозволяє уникнути заповнення кешу даними, які не запитуються. + +##### Недоліки: cache-aside + +* Кожен промах кешу призводить до трьох звернень, що може викликати помітну затримку. +* Дані можуть застаріти, якщо вони оновлюються в базі даних. Ця проблема пом'якшується встановленням time-to-live (TTL), який примусово оновлює запис кешу, або використанням write-through. +* Коли вузол виходить з ладу, він замінюється новим, порожнім вузлом, збільшуючи затримку. + +#### Write-through + +

+ +
+ Джерело: Scalability, availability, stability, patterns +

+ +Додаток використовує кеш як основне сховище даних, читаючи та записуючи до нього, тоді як кеш відповідає за читання та запис до бази даних: + +* Додаток додає/оновлює запис у кеші +* Кеш синхронно записує запис до сховища даних +* Повертає + +Код додатку: + +```python +set_user(12345, {"foo":"bar"}) +``` + +Код кешу: + +```python +def set_user(user_id, values): + user = db.query("UPDATE Users WHERE id = {0}", user_id, values) + cache.set(user_id, user) +``` + +Write-through — це повільна загальна операція через операцію запису, але подальші читання щойно записаних даних є швидкими. Користувачі зазвичай більш толерантні до затримки при оновленні даних, ніж при читанні. Дані в кеші не застарівають. + +##### Недоліки: write through + +* Коли створюється новий вузол через відмову або масштабування, новий вузол не кешуватиме записи, поки запис не буде оновлено в базі даних. Cache-aside у поєднанні з write through може пом'якшити цю проблему. +* Більшість записаних даних може ніколи не читатися, що можна мінімізувати за допомогою TTL. + +#### Write-behind (write-back) + +

+ +
+ Джерело: Scalability, availability, stability, patterns +

+ +У write-behind додаток виконує наступне: + +* Додає/оновлює запис у кеші +* Асинхронно записує запис до сховища даних, покращуючи продуктивність запису + +##### Недоліки: write-behind + +* Може бути втрата даних, якщо кеш виходить з ладу до того, як його вміст потрапить до сховища даних. +* Складніше реалізувати write-behind, ніж cache-aside або write-through. + +#### Refresh-ahead + +

+ +
+ Джерело: From cache to in-memory data grid +

+ +Ви можете налаштувати кеш на автоматичне оновлення будь-якого нещодавно доступного запису кешу до закінчення його терміну. + +Refresh-ahead може призвести до зменшення затримки порівняно з read-through, якщо кеш може точно передбачити, які елементи, ймовірно, знадобляться в майбутньому. + +##### Недоліки: refresh-ahead + +* Неточне передбачення того, які елементи, ймовірно, знадобляться в майбутньому, може призвести до зниження продуктивності порівняно з відсутністю refresh-ahead. + +### Недоліки: кеш + +* Потрібно підтримувати узгодженість між кешами та джерелом істини, таким як база даних, через [інвалідацію кешу](https://en.wikipedia.org/wiki/Cache_algorithms). +* Інвалідація кешу — складна проблема, є додаткова складність, пов'язана з тим, коли оновлювати кеш. +* Потрібні зміни в додатку, такі як додавання Redis або memcached. + +### Джерела та додаткове читання + +* [From cache to in-memory data grid](http://www.slideshare.net/tmatyashovsky/from-cache-to-in-memory-data-grid-introduction-to-hazelcast) +* [Патерни дизайну масштабованих систем](http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html) +* [Вступ до архітектури систем для масштабування](http://lethain.com/introduction-to-architecting-systems-for-scale/) +* [Масштабованість, доступність, стабільність, патерни](http://www.slideshare.net/jboner/scalability-availability-stability-patterns/) +* [Масштабованість](https://web.archive.org/web/20230126233752/https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache) +* [Стратегії AWS ElastiCache](http://docs.aws.amazon.com/AmazonElastiCache/latest/UserGuide/Strategies.html) +* [Wikipedia](https://en.wikipedia.org/wiki/Cache_(computing)) + +## Асинхронність + +

+ +
+ Джерело: Intro to architecting systems for scale +

+ +Асинхронні робочі процеси допомагають зменшити час запиту для дорогих операцій, які інакше виконувались би inline. Вони також можуть допомогти, виконуючи трудомістку роботу заздалегідь, наприклад періодичну агрегацію даних. + +### Черги повідомлень + +Черги повідомлень отримують, зберігають та доставляють повідомлення. Якщо операція занадто повільна для inline-виконання, ви можете використовувати чергу повідомлень з наступним робочим процесом: + +* Додаток публікує завдання в чергу, потім повідомляє користувача про статус завдання +* Worker забирає завдання з черги, обробляє його, потім сигналізує про завершення завдання + +Користувач не блокується, і завдання обробляється у фоновому режимі. Протягом цього часу клієнт може опціонально виконати невелику кількість обробки, щоб здавалось, що завдання виконано. Наприклад, при публікації твіта твіт може миттєво з'явитися у вашій стрічці, але може знадобитися деякий час, перш ніж ваш твіт буде фактично доставлений усім вашим підписникам. + +**[Redis](https://redis.io/)** корисний як простий брокер повідомлень, але повідомлення можуть бути втрачені. + +**[RabbitMQ](https://www.rabbitmq.com/)** популярний, але вимагає адаптації до протоколу 'AMQP' та управління власними вузлами. + +**[Amazon SQS](https://aws.amazon.com/sqs/)** — хостинговий, але може мати високу затримку та можливість подвійної доставки повідомлень. + +### Черги завдань + +Черги завдань отримують завдання та пов'язані з ними дані, виконують їх, потім повертають результати. Вони можуть підтримувати планування та можуть використовуватися для виконання обчислювально інтенсивних завдань у фоновому режимі. + +**[Celery](https://docs.celeryproject.org/en/stable/)** має підтримку планування і переважно підтримує Python. + +### Зворотний тиск (Back pressure) + +Якщо черги починають значно зростати, розмір черги може стати більшим за пам'ять, що призведе до промахів кешу, читань з диска та ще повільнішої продуктивності. [Back pressure](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) може допомогти, обмежуючи розмір черги, тим самим підтримуючи високу швидкість пропускання та хороший час відповіді для завдань, які вже є в черзі. Коли черга заповнюється, клієнти отримують код статусу server busy або HTTP 503, щоб спробувати пізніше. Клієнти можуть повторити запит пізніше, можливо з [експоненціальною затримкою](https://en.wikipedia.org/wiki/Exponential_backoff). + +### Недоліки: асинхронність + +* Випадки використання, такі як недорогі обчислення та робочі процеси реального часу, можуть краще підходити для синхронних операцій, оскільки введення черг може додати затримки та складності. + +### Джерела та додаткове читання + +* [It's all a numbers game](https://www.youtube.com/watch?v=1KRYH75wgy4) +* [Застосування back pressure при перевантаженні](http://mechanical-sympathy.blogspot.com/2012/05/apply-back-pressure-when-overloaded.html) +* [Little's law](https://en.wikipedia.org/wiki/Little%27s_law) +* [Яка різниця між чергою повідомлень та чергою завдань?](https://www.quora.com/What-is-the-difference-between-a-message-queue-and-a-task-queue-Why-would-a-task-queue-require-a-message-broker-like-RabbitMQ-Redis-Celery-or-IronMQ-to-function) + +## Комунікація + +

+ +
+ Джерело: OSI 7 layer model +

+ +### Протокол HTTP + +HTTP — це метод кодування та транспортування даних між клієнтом та сервером. Це протокол запит/відповідь: клієнти надсилають запити, а сервери видають відповіді з відповідним контентом та інформацією про статус завершення запиту. HTTP є самодостатнім, дозволяючи запитам і відповідям проходити через багато проміжних маршрутизаторів і серверів, які виконують балансування навантаження, кешування, шифрування та стиснення. + +Базовий HTTP-запит складається з дієслова (методу) та ресурсу (endpoint). Нижче наведено поширені HTTP-дієслова: + +| Дієслово | Опис | Ідемпотентний* | Безпечний | Кешований | +|---|---|---|---|---| +| GET | Читає ресурс | Так | Так | Так | +| POST | Створює ресурс або запускає процес обробки даних | Ні | Ні | Так, якщо відповідь містить інформацію про свіжість | +| PUT | Створює або замінює ресурс | Так | Ні | Ні | +| PATCH | Частково оновлює ресурс | Ні | Ні | Так, якщо відповідь містить інформацію про свіжість | +| DELETE | Видаляє ресурс | Так | Ні | Ні | + +*Може бути викликаний багато разів без різних результатів. + +HTTP — це протокол прикладного рівня, який спирається на протоколи нижчого рівня, такі як **TCP** та **UDP**. + +#### Джерела та додаткове читання: HTTP + +* [Що таке HTTP?](https://www.nginx.com/resources/glossary/http/) +* [Різниця між HTTP та TCP](https://www.quora.com/What-is-the-difference-between-HTTP-protocol-and-TCP-protocol) +* [Різниця між PUT та PATCH](https://laracasts.com/discuss/channels/general-discussion/whats-the-differences-between-put-and-patch?page=1) + +### Протокол TCP + +

+ +
+ Джерело: How to make a multiplayer game +

+ +TCP — це орієнтований на з'єднання протокол поверх [IP-мережі](https://en.wikipedia.org/wiki/Internet_Protocol). З'єднання встановлюється та завершується за допомогою [handshake](https://en.wikipedia.org/wiki/Handshaking). Усі надіслані пакети гарантовано досягають пункту призначення в початковому порядку та без пошкоджень через: + +* Порядкові номери та [поля контрольної суми](https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Checksum_computation) для кожного пакета +* [Підтвердження](https://en.wikipedia.org/wiki/Acknowledgement_(data_networks)) пакетів та автоматичну повторну передачу + +Якщо відправник не отримує правильну відповідь, він повторно надсилає пакети. Якщо є кілька тайм-аутів, з'єднання розривається. TCP також реалізує [керування потоком](https://en.wikipedia.org/wiki/Flow_control_(data)) та [керування перевантаженням](https://en.wikipedia.org/wiki/Network_congestion#Congestion_control). Ці гарантії викликають затримки і зазвичай призводять до менш ефективної передачі, ніж UDP. + +Для забезпечення високої пропускної здатності веб-сервери можуть тримати велику кількість відкритих TCP-з'єднань, що призводить до високого використання пам'яті. Може бути дорого мати велику кількість відкритих з'єднань між потоками веб-сервера та, скажімо, сервером [memcached](https://memcached.org/). [Пул з'єднань](https://en.wikipedia.org/wiki/Connection_pool) може допомогти, а також перехід на UDP там, де це можливо. + +TCP корисний для додатків, які вимагають високої надійності, але менш критичні до часу. Деякі приклади включають веб-сервери, інформацію баз даних, SMTP, FTP та SSH. + +Використовуйте TCP замість UDP, коли: + +* Вам потрібно, щоб усі дані надійшли без пошкоджень +* Ви хочете автоматично робити найкращу оцінку використання пропускної здатності мережі + +### Протокол UDP + +

+ +
+ Джерело: How to make a multiplayer game +

+ +UDP є без з'єднання. Датаграми (аналогічні пакетам) гарантуються лише на рівні датаграми. Датаграми можуть досягати пункту призначення не в порядку або не досягати взагалі. UDP не підтримує керування перевантаженням. Без гарантій, які підтримує TCP, UDP зазвичай є більш ефективним. + +UDP може транслювати, надсилаючи датаграми на всі пристрої в підмережі. Це корисно для [DHCP](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol), оскільки клієнт ще не отримав IP-адресу, що не дозволяє TCP передавати потік без IP-адреси. + +UDP менш надійний, але добре працює в реальному часі, наприклад, у VoIP, відеочатах, стрімінгу та багатокористувацьких іграх у реальному часі. + +Використовуйте UDP замість TCP, коли: + +* Вам потрібна найнижча затримка +* Пізні дані гірші, ніж втрата даних +* Ви хочете реалізувати власну корекцію помилок + +#### Джерела та додаткове читання: TCP та UDP + +* [Мережа для ігрового програмування](http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/) +* [Ключові відмінності між протоколами TCP та UDP](http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/) +* [Різниця між TCP та UDP](http://stackoverflow.com/questions/5970383/difference-between-tcp-and-udp) +* [Transmission control protocol](https://en.wikipedia.org/wiki/Transmission_Control_Protocol) +* [User datagram protocol](https://en.wikipedia.org/wiki/User_Datagram_Protocol) +* [Масштабування memcache у Facebook](http://www.cs.bu.edu/~jappavoo/jappavoo.github.com/451/papers/memcache-fb.pdf) + +### Віддалений виклик процедур (RPC) + +

+ +
+ Джерело: Crack the system design interview +

+ +У RPC клієнт викликає виконання процедури в іншому адресному просторі, зазвичай на віддаленому сервері. Процедура кодується так, ніби це локальний виклик процедури, абстрагуючи деталі того, як спілкуватися з сервером, від клієнтської програми. Віддалені виклики зазвичай повільніші та менш надійні, ніж локальні виклики, тому корисно розрізняти RPC-виклики від локальних викликів. Популярні RPC-фреймворки включають [Protobuf](https://developers.google.com/protocol-buffers/), [Thrift](https://thrift.apache.org/) та [Avro](https://avro.apache.org/docs/current/). + +RPC — це протокол запит-відповідь: + +* **Клієнтська програма** — викликає клієнтську stub-процедуру. Параметри поміщуються в стек, як при локальному виклику процедури. +* **Клієнтська stub-процедура** — маршалізує (пакує) id процедури та аргументи в повідомлення запиту. +* **Клієнтський модуль комунікації** — ОС надсилає повідомлення від клієнта на сервер. +* **Серверний модуль комунікації** — ОС передає вхідні пакети серверній stub-процедурі. +* **Серверна stub-процедура** — розмаршалізує результати, викликає серверну процедуру, що відповідає id процедури, і передає задані аргументи. +* Відповідь сервера повторює кроки вище у зворотному порядку. + +Зразки RPC-викликів: + +``` +GET /someoperation?data=anId + +POST /anotheroperation +{ + "data":"anId"; + "anotherdata": "another value" +} +``` + +RPC зосереджений на експонуванні поведінки. RPC часто використовуються з міркувань продуктивності для внутрішніх комунікацій, оскільки ви можете вручну створювати нативні виклики, щоб краще відповідати вашим випадкам використання. + +Вибирайте нативну бібліотеку (aka SDK), коли: + +* Ви знаєте свою цільову платформу. +* Ви хочете контролювати, як отримується доступ до вашої «логіки». +* Ви хочете контролювати, як відбувається обробка помилок поза вашою бібліотекою. +* Продуктивність та досвід кінцевого користувача є вашою основною турботою. + +HTTP API, що дотримуються **REST**, зазвичай частіше використовуються для публічних API. + +#### Недоліки: RPC + +* Клієнти RPC стають тісно пов'язаними з реалізацією сервісу. +* Новий API потрібно визначати для кожної нової операції або випадку використання. +* RPC може бути важко налагоджувати. +* Ви можете не мати можливості використовувати існуючі технології з коробки. Наприклад, може знадобитися додаткові зусилля, щоб забезпечити [належне кешування RPC-викликів](https://web.archive.org/web/20170608193645/http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) на серверах кешування, таких як [Squid](http://www.squid-cache.org/). + +### REST + +REST — це архітектурний стиль, що впроваджує модель клієнт/сервер, де клієнт діє на набір ресурсів, керованих сервером. Сервер надає представлення ресурсів та дій, які можуть або маніпулювати, або отримувати нове представлення ресурсів. Вся комунікація має бути stateless та кешованою. + +Є чотири якості RESTful-інтерфейсу: + +* **Ідентифікація ресурсів (URI в HTTP)** — використовуйте той самий URI незалежно від будь-якої операції. +* **Зміна через представлення (Дієслова в HTTP)** — використовуйте дієслова, заголовки та тіло. +* **Самоописувальне повідомлення про помилку (відповідь статусу в HTTP)** — використовуйте коди статусу, не винаходьте велосипед. +* **[HATEOAS](http://restcookbook.com/Basics/hateoas/) (HTML-інтерфейс для HTTP)** — ваш веб-сервіс повинен бути повністю доступним у браузері. + +Зразки REST-викликів: + +``` +GET /someresources/anId + +PUT /someresources/anId +{"anotherdata": "another value"} +``` + +REST зосереджений на експонуванні даних. Він мінімізує зв'язаність між клієнтом/сервером і часто використовується для публічних HTTP API. REST використовує більш загальний та уніфікований метод експонування ресурсів через URI, [представлення через заголовки](https://github.com/for-GET/know-your-http-well/blob/master/headers.md) та дії через дієслова, такі як GET, POST, PUT, DELETE та PATCH. Будучи stateless, REST чудово підходить для горизонтального масштабування та партиціонування. + +#### Недоліки: REST + +* Оскільки REST зосереджений на експонуванні даних, він може не підходити, якщо ресурси не організовані природно або не доступні в простій ієрархії. Наприклад, повернення всіх оновлених записів за останню годину, що відповідають певному набору подій, нелегко виразити як шлях. З REST це, ймовірно, буде реалізовано через комбінацію шляху URI, параметрів запиту та, можливо, тіла запиту. +* REST зазвичай спирається на кілька дієслів (GET, POST, PUT, DELETE та PATCH), які іноді не відповідають вашому випадку використання. Наприклад, переміщення прострочених документів до папки архіву може не вписуватися чітко в ці дієслова. +* Отримання складних ресурсів з вкладеними ієрархіями вимагає кількох звернень між клієнтом і сервером для рендерингу одного відображення, наприклад, отримання вмісту запису блогу та коментарів до цього запису. Для мобільних додатків, що працюють у змінних мережевих умовах, ці кілька звернень вкрай небажані. +* З часом до відповіді API можуть додаватися нові поля, і старі клієнти будуть отримувати всі нові поля даних, навіть ті, які їм не потрібні, що збільшує розмір payload та призводить до більших затримок. + +### Порівняння викликів RPC та REST + +| Операція | RPC | REST | +|---|---|---| +| Реєстрація | **POST** /signup | **POST** /persons | +| Звільнення | **POST** /resign
{
"personid": "1234"
} | **DELETE** /persons/1234 | +| Читання особи | **GET** /readPerson?personid=1234 | **GET** /persons/1234 | +| Читання списку елементів особи | **GET** /readUsersItemsList?personid=1234 | **GET** /persons/1234/items | +| Додавання елемента до елементів особи | **POST** /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
} | **POST** /persons/1234/items
{
"itemid": "456"
} | +| Оновлення елемента | **POST** /modifyItem
{
"itemid": "456";
"key": "value"
} | **PUT** /items/456
{
"key": "value"
} | +| Видалення елемента | **POST** /removeItem
{
"itemid": "456"
} | **DELETE** /items/456 | + +

+ Джерело: Do you really know why you prefer REST over RPC +

+ +#### Джерела та додаткове читання: REST та RPC + +* [Do you really know why you prefer REST over RPC](https://apihandyman.io/do-you-really-know-why-you-prefer-rest-over-rpc/) +* [When are RPC-ish approaches more appropriate than REST?](http://programmers.stackexchange.com/a/181186) +* [REST vs JSON-RPC](http://stackoverflow.com/questions/15056878/rest-vs-json-rpc) +* [Debunking the myths of RPC and REST](https://web.archive.org/web/20170608193645/http://etherealbits.com/2012/12/debunking-the-myths-of-rpc-rest/) +* [What are the drawbacks of using REST](https://www.quora.com/What-are-the-drawbacks-of-using-RESTful-APIs) +* [Crack the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) +* [Thrift](https://code.facebook.com/posts/1468950976659943/) +* [Why REST for internal use and not RPC](http://arstechnica.com/civis/viewtopic.php?t=1190508) + +## Безпека + +Цей розділ потребує оновлення. Розгляньте можливість [долучитися](#як-долучитися)! + +Безпека — це широка тема. Якщо у вас немає значного досвіду, досвіду в сфері безпеки або ви не претендуєте на позицію, яка вимагає знань безпеки, вам, ймовірно, не потрібно знати більше, ніж основи: + +* Шифрування при передачі та зберіганні. +* Санітизація всіх даних користувача або будь-яких вхідних параметрів, відкритих для користувача, для запобігання [XSS](https://en.wikipedia.org/wiki/Cross-site_scripting) та [SQL injection](https://en.wikipedia.org/wiki/SQL_injection). +* Використовуйте параметризовані запити для запобігання SQL injection. +* Використовуйте принцип [найменших привілеїв](https://en.wikipedia.org/wiki/Principle_of_least_privilege). + +### Джерела та додаткове читання + +* [Чек-лист безпеки API](https://github.com/shieldfy/API-Security-Checklist) +* [Посібник з безпеки для розробників](https://github.com/FallibleInc/security-guide-for-developers) +* [OWASP top ten](https://www.owasp.org/index.php/OWASP_Top_Ten_Cheat_Sheet) + +## Додаток + +Іноді вас попросять робити розрахунки «на серветці». Наприклад, вам може знадобитися визначити, скільки часу потрібно для генерування 100 мініатюр зображень з диска або скільки пам'яті займе структура даних. **Таблиця степенів двійки** та **Числа затримки, які має знати кожен програміст** є зручними довідниками. + +### Таблиця степенів двійки + +``` +Степінь Точне значення Приблизно Байти +--------------------------------------------------------------- +7 128 +8 256 +10 1024 1 тисяча 1 KB +16 65,536 64 KB +20 1,048,576 1 мільйон 1 MB +30 1,073,741,824 1 мільярд 1 GB +32 4,294,967,296 4 GB +40 1,099,511,627,776 1 трильйон 1 TB +``` + +#### Джерела та додаткове читання + +* [Степені двійки](https://en.wikipedia.org/wiki/Power_of_two) + +### Числа затримки, які має знати кожен програміст + +``` +Порівняння чисел затримки +-------------------------- +Посилання на L1 кеш 0.5 нс +Помилка передбачення гілки 5 нс +Посилання на L2 кеш 7 нс 14x L1 кеш +Блокування/розблокування мьютекса 25 нс +Посилання на основну пам'ять 100 нс 20x L2 кеш, 200x L1 кеш +Стиснення 1K байт за допомогою Zippy 10,000 нс 10 мкс +Надсилання 1 KB через 1 Gbps мережу 10,000 нс 10 мкс +Випадкове читання 4 KB з SSD* 150,000 нс 150 мкс ~1GB/сек SSD +Послідовне читання 1 MB з пам'яті 250,000 нс 250 мкс +Round trip в межах одного дата-центру 500,000 нс 500 мкс +Послідовне читання 1 MB з SSD* 1,000,000 нс 1,000 мкс 1 мс ~1GB/сек SSD, 4X пам'ять +Пошук HDD 10,000,000 нс 10,000 мкс 10 мс 20x roundtrip дата-центру +Послідовне читання 1 MB з 1 Gbps 10,000,000 нс 10,000 мкс 10 мс 40x пам'ять, 10X SSD +Послідовне читання 1 MB з HDD 30,000,000 нс 30,000 мкс 30 мс 120x пам'ять, 30X SSD +Відправка пакета CA->Нідерланди->CA 150,000,000 нс 150,000 мкс 150 мс + +Примітки +-------- +1 нс = 10^-9 секунд +1 мкс = 10^-6 секунд = 1,000 нс +1 мс = 10^-3 секунд = 1,000 мкс = 1,000,000 нс +``` + +Корисні метрики на основі наведених вище чисел: + +* Послідовне читання з HDD зі швидкістю 30 MB/с +* Послідовне читання з 1 Gbps Ethernet зі швидкістю 100 MB/с +* Послідовне читання з SSD зі швидкістю 1 GB/с +* Послідовне читання з основної пам'яті зі швидкістю 4 GB/с +* 6-7 world-wide round trips на секунду +* 2,000 round trips на секунду в межах дата-центру + +#### Візуалізація чисел затримки + +![](https://camo.githubusercontent.com/77f72259e1eb58596b564d1ad823af1853bc60a3/687474703a2f2f692e696d6775722e636f6d2f6b307431652e706e67) + +#### Джерела та додаткове читання + +* [Числа затримки, які має знати кожен програміст - 1](https://gist.github.com/jboner/2841832) +* [Числа затримки, які має знати кожен програміст - 2](https://gist.github.com/hellerbarde/2843375) +* [Проектування, уроки та поради з побудови великих розподілених систем](http://www.cs.cornell.edu/projects/ladis2009/talks/dean-keynote-ladis2009.pdf) +* [Поради з програмної інженерії з побудови великомасштабних розподілених систем](https://static.googleusercontent.com/media/research.google.com/en//people/jeff/stanford-295-talk.pdf) + +### Додаткові питання співбесіди з проектування систем + +> Типові питання співбесіди з проектування систем з посиланнями на ресурси про те, як їх розв'язати. + +| Питання | Посилання | +|---|---| +| Спроектуйте сервіс синхронізації файлів, як Dropbox | [youtube.com](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| Спроектуйте пошукову систему, як Google | [queue.acm.org](http://queue.acm.org/detail.cfm?id=988407)
[stackexchange.com](http://programmers.stackexchange.com/questions/38324/interview-question-how-would-you-implement-google-search)
[ardendertat.com](http://www.ardendertat.com/2012/01/11/implementing-search-engines/)
[stanford.edu](http://infolab.stanford.edu/~backrub/google.html) | +| Спроектуйте масштабований веб-краулер, як у Google | [quora.com](https://www.quora.com/How-can-I-build-a-web-crawler-from-scratch) | +| Спроектуйте Google Docs | [code.google.com](https://code.google.com/p/google-mobwrite/)
[neil.fraser.name](https://neil.fraser.name/writing/sync/) | +| Спроектуйте сховище ключ-значення, як Redis | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) | +| Спроектуйте систему кешування, як Memcached | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| Спроектуйте систему рекомендацій, як у Amazon | [hulu.com](https://web.archive.org/web/20170406065247/http://tech.hulu.com/blog/2011/09/19/recommendation-system.html)
[ijcai13.org](http://ijcai13.org/files/tutorial_slides/td3.pdf) | +| Спроектуйте систему tinyurl, як Bitly | [n00tc0d3r.blogspot.com](http://n00tc0d3r.blogspot.com/) | +| Спроектуйте чат-додаток, як WhatsApp | [highscalability.com](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) +| Спроектуйте систему обміну фото, як Instagram | [highscalability.com](http://highscalability.com/flickr-architecture)
[highscalability.com](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html) | +| Спроектуйте функцію стрічки новин Facebook | [quora.com](http://www.quora.com/What-are-best-practices-for-building-something-like-a-News-Feed)
[quora.com](http://www.quora.com/Activity-Streams/What-are-the-scaling-issues-to-keep-in-mind-while-developing-a-social-network-feed)
[slideshare.net](http://www.slideshare.net/danmckinley/etsy-activity-feeds-architecture) | +| Спроектуйте функцію timeline Facebook | [facebook.com](https://www.facebook.com/note.php?note_id=10150468255628920)
[highscalability.com](http://highscalability.com/blog/2012/1/23/facebook-timeline-brought-to-you-by-the-power-of-denormaliza.html) | +| Спроектуйте функцію чату Facebook | [erlang-factory.com](http://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf)
[facebook.com](https://www.facebook.com/note.php?note_id=14218138919&id=9445547199&index=0) | +| Спроектуйте функцію graph search, як у Facebook | [facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-building-out-the-infrastructure-for-graph-search/10151347573598920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-indexing-and-ranking-in-graph-search/10151361720763920)
[facebook.com](https://www.facebook.com/notes/facebook-engineering/under-the-hood-the-natural-language-interface-of-graph-search/10151432733048920) | +| Спроектуйте мережу доставки контенту, як CloudFlare | [figshare.com](https://figshare.com/articles/Globally_distributed_content_delivery/6605972) | +| Спроектуйте систему трендових тем, як у Twitter | [michael-noll.com](http://www.michael-noll.com/blog/2013/01/18/implementing-real-time-trending-topics-in-storm/)
[snikolov.wordpress.com](http://snikolov.wordpress.com/2012/11/14/early-detection-of-twitter-trends/) | +| Спроектуйте систему генерації випадкових ID | [blog.twitter.com](https://blog.twitter.com/2010/announcing-snowflake)
[github.com](https://github.com/twitter/snowflake/) | +| Поверніть топ k запитів за часовий інтервал | [cs.ucsb.edu](https://www.cs.ucsb.edu/sites/default/files/documents/2005-23.pdf)
[wpi.edu](http://davis.wpi.edu/xmdv/docs/EDBT11-diyang.pdf) | +| Спроектуйте систему, яка обслуговує дані з кількох дата-центрів | [highscalability.com](http://highscalability.com/blog/2009/8/24/how-google-serves-data-from-multiple-datacenters.html) | +| Спроектуйте онлайн багатокористувацьку карткову гру | [indieflashblog.com](https://web.archive.org/web/20180929181117/http://www.indieflashblog.com/how-to-create-an-asynchronous-multiplayer-game.html)
[buildnewgames.com](http://buildnewgames.com/real-time-multiplayer/) | +| Спроектуйте систему збирання сміття | [stuffwithstuff.com](http://journal.stuffwithstuff.com/2013/12/08/babys-first-garbage-collector/)
[washington.edu](http://courses.cs.washington.edu/courses/csep521/07wi/prj/rick.pdf) | +| Спроектуйте API rate limiter | [stripe.com](https://stripe.com/blog/rate-limiters) | +| Спроектуйте біржу (як NASDAQ або Binance) | [Jane Street](https://youtu.be/b1e4t2k2KJY)
[Реалізація на Golang](https://around25.com/blog/building-a-trading-engine-for-a-crypto-exchange/)
[Реалізація на Go](http://bhomnick.net/building-a-simple-limit-order-in-go/) | +| Додати питання з проектування систем | [Долучитися](#як-долучитися) | + +### Архітектури реального світу + +> Статті про те, як проектуються реальні системи. + +

+ +
+ Джерело: Twitter timelines at scale +

+ +**Не зосереджуйтесь на дрібних деталях у наступних статтях, натомість:** + +* Визначте спільні принципи, загальні технології та патерни в цих статтях +* Вивчіть, які проблеми вирішує кожен компонент, де він працює, де не працює +* Перегляньте отримані уроки + +| Тип | Система | Посилання | +|---|---|---| +| Обробка даних | **MapReduce** - розподілена обробка даних від Google | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/mapreduce-osdi04.pdf) | +| Обробка даних | **Spark** - розподілена обробка даних від Databricks | [slideshare.net](http://www.slideshare.net/AGrishchenko/apache-spark-architecture) | +| Обробка даних | **Storm** - розподілена обробка даних від Twitter | [slideshare.net](http://www.slideshare.net/previa/storm-16094009) | +| | | | +| Сховище даних | **Bigtable** - розподілена колонко-орієнтована база даних від Google | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/chang06bigtable.pdf) | +| Сховище даних | **HBase** - open-source реалізація Bigtable | [slideshare.net](http://www.slideshare.net/alexbaranau/intro-to-hbase) | +| Сховище даних | **Cassandra** - розподілена колонко-орієнтована база даних від Facebook | [slideshare.net](http://www.slideshare.net/planetcassandra/cassandra-introduction-features-30103666) +| Сховище даних | **DynamoDB** - документо-орієнтована база даних від Amazon | [harvard.edu](http://www.read.seas.harvard.edu/~kohler/class/cs239-w08/decandia07dynamo.pdf) | +| Сховище даних | **MongoDB** - документо-орієнтована база даних | [slideshare.net](http://www.slideshare.net/mdirolf/introduction-to-mongodb) | +| Сховище даних | **Spanner** - глобально розподілена база даних від Google | [research.google.com](http://research.google.com/archive/spanner-osdi2012.pdf) | +| Сховище даних | **Memcached** - розподілена система кешування в пам'яті | [slideshare.net](http://www.slideshare.net/oemebamo/introduction-to-memcached) | +| Сховище даних | **Redis** - розподілена система кешування в пам'яті з персистентністю та типами значень | [slideshare.net](http://www.slideshare.net/dvirsky/introduction-to-redis) | +| | | | +| Файлова система | **Google File System (GFS)** - розподілена файлова система | [research.google.com](http://static.googleusercontent.com/media/research.google.com/zh-CN/us/archive/gfs-sosp2003.pdf) | +| Файлова система | **Hadoop File System (HDFS)** - open-source реалізація GFS | [apache.org](http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html) | +| | | | +| Різне | **Chubby** - сервіс блокування для слабко зв'язаних розподілених систем від Google | [research.google.com](http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/archive/chubby-osdi06.pdf) | +| Різне | **Dapper** - інфраструктура трасування розподілених систем | [research.google.com](http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36356.pdf) +| Різне | **Kafka** - черга повідомлень pub/sub від LinkedIn | [slideshare.net](http://www.slideshare.net/mumrah/kafka-talk-tri-hug) | +| Різне | **Zookeeper** - централізована інфраструктура та сервіси для синхронізації | [slideshare.net](http://www.slideshare.net/sauravhaloi/introduction-to-apache-zookeeper) | +| | Додати архітектуру | [Долучитися](#як-долучитися) | + +### Архітектури компаній + +| Компанія | Посилання | +|---|---| +| Amazon | [Amazon architecture](http://highscalability.com/amazon-architecture) | +| Cinchcast | [Producing 1,500 hours of audio every day](http://highscalability.com/blog/2012/7/16/cinchcast-architecture-producing-1500-hours-of-audio-every-d.html) | +| DataSift | [Realtime datamining at 120,000 tweets per second](http://highscalability.com/blog/2011/11/29/datasift-architecture-realtime-datamining-at-120000-tweets-p.html) | +| Dropbox | [How we've scaled Dropbox](https://www.youtube.com/watch?v=PE4gwstWhmc) | +| ESPN | [Operating at 100,000 duh nuh nuhs per second](http://highscalability.com/blog/2013/11/4/espns-architecture-at-scale-operating-at-100000-duh-nuh-nuhs.html) | +| Google | [Google architecture](http://highscalability.com/google-architecture) | +| Instagram | [14 million users, terabytes of photos](http://highscalability.com/blog/2011/12/6/instagram-architecture-14-million-users-terabytes-of-photos.html)
[What powers Instagram](http://instagram-engineering.tumblr.com/post/13649370142/what-powers-instagram-hundreds-of-instances) | +| Justin.tv | [Justin.Tv's live video broadcasting architecture](http://highscalability.com/blog/2010/3/16/justintvs-live-video-broadcasting-architecture.html) | +| Facebook | [Scaling memcached at Facebook](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/key-value/fb-memcached-nsdi-2013.pdf)
[TAO: Facebook's distributed data store for the social graph](https://cs.uwaterloo.ca/~brecht/courses/854-Emerging-2014/readings/data-store/tao-facebook-distributed-datastore-atc-2013.pdf)
[Facebook's photo storage](https://www.usenix.org/legacy/event/osdi10/tech/full_papers/Beaver.pdf)
[How Facebook Live Streams to 800,000 simultaneous viewers](http://highscalability.com/blog/2016/6/27/how-facebook-live-streams-to-800000-simultaneous-viewers.html) | +| Flickr | [Flickr architecture](http://highscalability.com/flickr-architecture) | +| Mailbox | [From 0 to one million users in 6 weeks](http://highscalability.com/blog/2013/6/18/scaling-mailbox-from-0-to-one-million-users-in-6-weeks-and-1.html) | +| Netflix | [A 360 Degree View of the Entire Netflix Stack](http://highscalability.com/blog/2015/11/9/a-360-degree-view-of-the-entire-netflix-stack.html)
[Netflix: What Happens When You Press Play?](http://highscalability.com/blog/2017/12/11/netflix-what-happens-when-you-press-play.html) | +| Pinterest | [From 0 to 10s of billions of page views a month](http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html)
[18 million visitors, 10x growth, 12 employees](http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html) | +| Playfish | [50 million monthly users and growing](http://highscalability.com/blog/2010/9/21/playfishs-social-gaming-architecture-50-million-monthly-user.html) | +| PlentyOfFish | [PlentyOfFish architecture](http://highscalability.com/plentyoffish-architecture) | +| Salesforce | [How they handle 1.3 billion transactions a day](http://highscalability.com/blog/2013/9/23/salesforce-architecture-how-they-handle-13-billion-transacti.html) | +| Stack Overflow | [Stack Overflow architecture](http://highscalability.com/blog/2009/8/5/stack-overflow-architecture.html) | +| TripAdvisor | [40M visitors, 200M dynamic page views, 30TB data](http://highscalability.com/blog/2011/6/27/tripadvisor-architecture-40m-visitors-200m-dynamic-page-view.html) | +| Tumblr | [15 billion page views a month](http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html) | +| Twitter | [Making Twitter 10000 percent faster](http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster)
[Storing 250 million tweets a day using MySQL](http://highscalability.com/blog/2011/12/19/how-twitter-stores-250-million-tweets-a-day-using-mysql.html)
[150M active users, 300K QPS, a 22 MB/S firehose](http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html)
[Timelines at scale](https://www.infoq.com/presentations/Twitter-Timeline-Scalability)
[Big and small data at Twitter](https://www.youtube.com/watch?v=5cKTP36HVgI)
[Operations at Twitter: scaling beyond 100 million users](https://www.youtube.com/watch?v=z8LU0Cj6BOU)
[How Twitter Handles 3,000 Images Per Second](http://highscalability.com/blog/2016/4/20/how-twitter-handles-3000-images-per-second.html) | +| Uber | [How Uber scales their real-time market platform](http://highscalability.com/blog/2015/9/14/how-uber-scales-their-real-time-market-platform.html)
[Lessons Learned From Scaling Uber To 2000 Engineers, 1000 Services, And 8000 Git Repositories](http://highscalability.com/blog/2016/10/12/lessons-learned-from-scaling-uber-to-2000-engineers-1000-ser.html) | +| WhatsApp | [The WhatsApp architecture Facebook bought for $19 billion](http://highscalability.com/blog/2014/2/26/the-whatsapp-architecture-facebook-bought-for-19-billion.html) | +| YouTube | [YouTube scalability](https://www.youtube.com/watch?v=w5WVu624fY8)
[YouTube architecture](http://highscalability.com/youtube-architecture) | + +### Інженерні блоги компаній + +> Архітектури компаній, в яких ви проходите співбесіду. +> +> Питання, з якими ви стикнетесь, можуть бути з тієї ж області. + +* [Airbnb Engineering](http://nerds.airbnb.com/) +* [Atlassian Developers](https://developer.atlassian.com/blog/) +* [AWS Blog](https://aws.amazon.com/blogs/aws/) +* [Bitly Engineering Blog](http://word.bitly.com/) +* [Box Blogs](https://blog.box.com/blog/category/engineering) +* [Cloudera Developer Blog](http://blog.cloudera.com/) +* [Dropbox Tech Blog](https://tech.dropbox.com/) +* [Engineering at Quora](https://www.quora.com/q/quoraengineering) +* [Ebay Tech Blog](http://www.ebaytechblog.com/) +* [Evernote Tech Blog](https://blog.evernote.com/tech/) +* [Etsy Code as Craft](http://codeascraft.com/) +* [Facebook Engineering](https://www.facebook.com/Engineering) +* [Flickr Code](http://code.flickr.net/) +* [Foursquare Engineering Blog](http://engineering.foursquare.com/) +* [GitHub Engineering Blog](https://github.blog/category/engineering) +* [Google Research Blog](http://googleresearch.blogspot.com/) +* [Groupon Engineering Blog](https://engineering.groupon.com/) +* [Heroku Engineering Blog](https://engineering.heroku.com/) +* [Hubspot Engineering Blog](http://product.hubspot.com/blog/topic/engineering) +* [High Scalability](http://highscalability.com/) +* [Instagram Engineering](http://instagram-engineering.tumblr.com/) +* [Intel Software Blog](https://software.intel.com/en-us/blogs/) +* [Jane Street Tech Blog](https://blogs.janestreet.com/category/ocaml/) +* [LinkedIn Engineering](http://engineering.linkedin.com/blog) +* [Microsoft Engineering](https://engineering.microsoft.com/) +* [Microsoft Python Engineering](https://blogs.msdn.microsoft.com/pythonengineering/) +* [Netflix Tech Blog](http://techblog.netflix.com/) +* [Paypal Developer Blog](https://medium.com/paypal-engineering) +* [Pinterest Engineering Blog](https://medium.com/@Pinterest_Engineering) +* [Reddit Blog](http://www.redditblog.com/) +* [Salesforce Engineering Blog](https://developer.salesforce.com/blogs/engineering/) +* [Slack Engineering Blog](https://slack.engineering/) +* [Spotify Labs](https://labs.spotify.com/) +* [Stripe Engineering Blog](https://stripe.com/blog/engineering) +* [Twilio Engineering Blog](http://www.twilio.com/engineering) +* [Twitter Engineering](https://blog.twitter.com/engineering/) +* [Uber Engineering Blog](http://eng.uber.com/) +* [Yahoo Engineering Blog](http://yahooeng.tumblr.com/) +* [Yelp Engineering Blog](http://engineeringblog.yelp.com/) +* [Zynga Engineering Blog](https://www.zynga.com/blogs/engineering) + +#### Джерела та додаткове читання + +Хочете додати блог? Щоб уникнути дублювання роботи, розгляньте можливість додавання блогу вашої компанії до наступного репозиторію: + +* [kilimchoi/engineering-blogs](https://github.com/kilimchoi/engineering-blogs) + +## У розробці + +Зацікавлені в додаванні розділу або допомозі в завершенні того, що в процесі? [Долучайтесь](#як-долучитися)! + +* Розподілені обчислення з MapReduce +* Consistent hashing +* Scatter gather +* [Долучитися](#як-долучитися) + +## Подяки + +Подяки та джерела наведені по всьому репозиторію. + +Особлива подяка: + +* [Hired in tech](http://www.hiredintech.com/system-design/the-system-design-process/) +* [Cracking the coding interview](https://www.amazon.com/dp/0984782850/) +* [High scalability](http://highscalability.com/) +* [checkcheckzz/system-design-interview](https://github.com/checkcheckzz/system-design-interview) +* [shashank88/system_design](https://github.com/shashank88/system_design) +* [mmcgrana/services-engineering](https://github.com/mmcgrana/services-engineering) +* [System design cheat sheet](https://gist.github.com/vasanthk/485d1c25737e8e72759f) +* [A distributed systems reading list](http://dancres.github.io/Pages/) +* [Cracking the system design interview](http://www.puncsky.com/blog/2016-02-13-crack-the-system-design-interview) + +## Контактна інформація + +Не соромтеся звертатися для обговорення будь-яких питань, запитань або коментарів. + +Мою контактну інформацію можна знайти на моїй [сторінці GitHub](https://github.com/donnemartin). + +## Ліцензія + +*Я надаю код та ресурси в цьому репозиторії вам під ліцензією open source. Оскільки це мій особистий репозиторій, ліцензія, яку ви отримуєте на мій код та ресурси, надходить від мене, а не від мого роботодавця (Facebook).* + + Copyright 2017 Donne Martin + + Creative Commons Attribution 4.0 International License (CC BY 4.0) + + http://creativecommons.org/licenses/by/4.0/ + + diff --git a/README-zh-Hans.md b/README-zh-Hans.md index 93284d0ae70..46212a23c4d 100644 --- a/README-zh-Hans.md +++ b/README-zh-Hans.md @@ -3,7 +3,7 @@ > * 译者:[XatMassacrE](https://github.com/XatMassacrE)、[L9m](https://github.com/L9m)、[Airmacho](https://github.com/Airmacho)、[xiaoyusilen](https://github.com/xiaoyusilen)、[jifaxu](https://github.com/jifaxu)、[根号三](https://github.com/sqrthree) > * 这个 [链接](https://github.com/xitu/system-design-primer/compare/master...donnemartin:master) 用来查看本翻译与英文版是否有差别(如果你没有看到 README.md 发生变化,那就意味着这份翻译文档是最新的)。 -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) ∙ [Українська](README-uk.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # 系统设计入门 diff --git a/README-zh-TW.md b/README-zh-TW.md index b51b0e7be7c..0311ced9931 100644 --- a/README-zh-TW.md +++ b/README-zh-TW.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) ∙ [Українська](README-uk.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* # 系統設計入門 diff --git a/README.md b/README.md index f2a1fa3c0f4..2cecd581723 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* +*[English](README.md) ∙ [日本語](README-ja.md) ∙ [简体中文](README-zh-Hans.md) ∙ [繁體中文](README-zh-TW.md) ∙ [Українська](README-uk.md) | [العَرَبِيَّة‎](https://github.com/donnemartin/system-design-primer/issues/170) ∙ [বাংলা](https://github.com/donnemartin/system-design-primer/issues/220) ∙ [Português do Brasil](https://github.com/donnemartin/system-design-primer/issues/40) ∙ [Deutsch](https://github.com/donnemartin/system-design-primer/issues/186) ∙ [ελληνικά](https://github.com/donnemartin/system-design-primer/issues/130) ∙ [עברית](https://github.com/donnemartin/system-design-primer/issues/272) ∙ [Italiano](https://github.com/donnemartin/system-design-primer/issues/104) ∙ [한국어](https://github.com/donnemartin/system-design-primer/issues/102) ∙ [فارسی](https://github.com/donnemartin/system-design-primer/issues/110) ∙ [Polski](https://github.com/donnemartin/system-design-primer/issues/68) ∙ [русский язык](https://github.com/donnemartin/system-design-primer/issues/87) ∙ [Español](https://github.com/donnemartin/system-design-primer/issues/136) ∙ [ภาษาไทย](https://github.com/donnemartin/system-design-primer/issues/187) ∙ [Türkçe](https://github.com/donnemartin/system-design-primer/issues/39) ∙ [tiếng Việt](https://github.com/donnemartin/system-design-primer/issues/127) ∙ [Français](https://github.com/donnemartin/system-design-primer/issues/250) | [Add Translation](https://github.com/donnemartin/system-design-primer/issues/28)* **Help [translate](TRANSLATIONS.md) this guide!** diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md index 584c3e2ebac..54c0aa83bb0 100644 --- a/TRANSLATIONS.md +++ b/TRANSLATIONS.md @@ -38,6 +38,12 @@ Languages are grouped by status and are listed in alphabetical order. * Maintainer(s): [@kevingo](https://github.com/kevingo) 👏 * Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/88 +### 🎉 Ukrainian + +* [README-uk.md](README-uk.md) +* Maintainer(s): [@shramko-serhii](https://github.com/shramkoweb) 👏 +* Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/248 + ## In Progress ### ⏳ Korean @@ -144,13 +150,6 @@ Languages are grouped by status and are listed in alphabetical order. * Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/39 * Translation Fork: https://github.com/donnemartin/system-design-primer/pull/239 -### ❗ Ukrainian - -* Maintainer(s): **Help Wanted** ✋ - * Previous Maintainer(s): [@Kietzmann](https://github.com/Kietzmann), [@Acarus](https://github.com/Acarus) -* Discussion Thread: https://github.com/donnemartin/system-design-primer/issues/248 -* Translation Fork: https://github.com/Acarus/system-design-primer - ### ❗ Vietnamese * Maintainer(s): **Help Wanted** ✋