∏⌀♰ʯԞ.ʯ⌀

Высоконагруженные приложения. Программирование, масштабирование, поддержка

Клеппман Мартин
Eng: Designing Data-Intensive Applications pdf

Чем интересна

Легендарная книга с Кабанчиком. Рассматриваются всякие бекенд штуки: внутреннее устройство бд, паттерны использования бд. Полезна для собесов и для работы.

Саммари

Основы информационных систем

Надежность, масштабируемость, удобство

Чтобы система была устройства к сбоям, и чтобы это не переходило в отказ, нужно постоянно тестировать систему, искусственно вызывая сбои (например что-то отключать, и проверять, что система работает)

Виды сбоев:

Важно понимать что нагрузка возросла. Для этого используются параметры нагрузки

Примеры параметров нагрузки: запросы в секунду, соотношение операций записи и чтения

Способы чтения на примере тви:

Время ответа хорошо трекать с помощью перцентилей:

Виды масштабирования:

Универсальной архитектуры не существует, всегда все зависит от параметров нагрузки, хотя есть паттерны масштабирования

Удобство сопровождения - когда мало Легаси; также включает в себя эксплуатацию, простоту и расширяемость

Модели данных и языки запросов

Причины появления NoSQL:

Связи «многие-к-одному» и «многие-ко-многим»-

Можно хранить повторяющиеся данные (напр. должность) текстом, можно ФК на табличку использовать:

Поначалу может показаться что делать строки это просто и удобно, но потом текст может разразрастись до сущности ( название компании > сущность компания) - так появляется связь многие ко многим

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

Динамическая и строгая схемы данных
Декларативный и императивный подходы
Графовые модели данных

Графы свойств

Графы хороши тем что их можно расширять:

Cypher - язык запросов для графов (neo4j), там все стрелочками отписывается, плюс он декларативный, что хорошо

Все это можно реализовать как 2 таблицы - таблица вершин и таблица ребер, и использовать обычный SQL, но запрос будет больше и сложнее для понимания, так что своей задаче - свой инструмент

Тройные кортежи = Turtle формат = N3 (notation 3)

Подсистемы хранения и извлечения данных

Структуры данных SQL = подсистемы хранения = Log-structured и page-oriented

Log-structured подход и Индексы

Хеш-индекс

Типовые проблемы и решения при таком подходе:

Ss-таблицы и lsm-деревья
B-деревья

Усовершенствования b-деревьев:

Сравнение b-tree и lsm-tree:

Минусы LSM
Еще про индексы
OLAP

Кодирование и эволюция

Совместимость:

Сериализация

Данные приложения могут быть в двух состояниях: в виде объектов и структур данных в оперативе, либо в виде последовательности байтов (Напр. Json) при передаче данных по сети или хранении на диске

Процесс перевода данных из формата оперативы в формат для передачи называется encoding=serialization=marshalling, а обратный процесс - deciding=deserialization=parsing=demarshaling

Языки программирования предоставляют свой способ сериализации данных, напр pickle в Python, но это работает только в рамках одного языка, не очень безопасно, контроль версий хромает, и производительность тоже может хромать

Json, xml, csv - популярные, человеко-читаемые текстовые форматы данных. Но у них есть некоторые проблемы: отсутствие возможности указания точности чисел и больших чисел, отсутствие возможности передавать двоичные данные (но обходится с помощью base64 кодирования, но и увеличивает размер данных), в коже приходится зашивать логику парсинга, и csv довольно хрупкий формат

Бинарные форматы

Двоичное кодирование имеет смысл когда данных много

Для json и xml есть свои бинарные аналоги, типа messagepack, bson, wbxml, хотя они не сильно экономят место

Thrift и Protocol Buffers - либы двоичного кодирования, обе работают на основе схемы (на своем языке), по этой схеме можно генерировать код. Суть кодирования в применении тегов полей - вместо хранения названия поля, просто храним цифру. Совместимость обеспечивается за счёт того что новые добавляемые поля - необязательны

Avro - ещё один двоичный формат, применяемый в Hadoop, там все завязано на порядке полей. Есть два типа схем, схема чтения (та что в коде), схема записи (мб в файле с данными, в бд, при согласовании при отправке по сети), и они могут не совпадать, таким образом можно осуществлять эволюцию схемы. Ещё плюсом Avro является возможность генерировать схему на лету, например из схемы бд, и забекапить бд в двоичном формате

Кодогенарция для бинарных форматов актуальна только для статически типизированных языков, также есть специальный язык обработки данных Apache Pig

Передача данных

Данные передаются на разных уровнях: на уровне бд, на уровне сети, при асинхронном общении

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

И ещё раз нужно быть аккуратнее с миграцией данных, когда старые данные обновляются на новый лад, это тяжёлая операция

Сервис - то что предоставляет апи

Сервис-ориентироаанная арх= микросервиснач арх - когда у сервиса своя задача, напр сервер работает с бд

Веб-сервис - сервис использующий хттп

Rest и soap - 2 подхода к написанию веб сервисов

Rest(ful) подход: применение урла для доступа к ресурсам, активное использование возможностей хттп: аутентификация, кешироаание, часто используется json, с помощью которого можно генерить доку и код (openapi, swagger)

Soap - xml подход, не использует возможности хттп, а свои спеки, описываемые с помощью wsdl. Этот подход сильно завязывается на спец утилитах, так что где-то интеграцию с соап сделать сложно