kamyshev.code
1.94K subscribers
40 photos
565 links
Архитектура, код, софт-скиллы и всё остальное. Вопросы, пожелания, комментарии — @igorkamyshev

https://kamyshev.me
Download Telegram
Начал читать новую книгу — Высоко-нагруженные приложения.

Она в основном о приложениях, нагруженных данными — data-intensive applications. Это когда основная проблема в приложении — качество данных, их сложность или скорость обновления. Главные качества DIA — надёжность, масштабируемость и удобство сопровождения.

Как обычно, буду публиковать сюда конспекты (не часто, читаю очень неспешно).

#dia
Надёжность

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

#dia
Большую часть аппаратных сбоев можно решить избыточностью компонентов (RAID-массивы дисков, дизельные генераторы для резервного питания, и так далее). Но сейчас все чаще создаются приложения, которые просто готовы к потере целого сервера. Это достигается созданием распределённых систем, где отдельные узлы дублируют друг друга.

#dia
Программные сбои намного сложнее контролировать. Во-первых, они часто затрагивают многие сервера одновременно (например, зависание Linux-серверов 30 июня 2012 года из-за ошибки в ядре). Во-вторых, такие сбои могут нести каскадный эффект — один вышедший из строя сервис убивает другой и так вся система рушится как домино. Простых решений нет — нужно тестировать программы, обеспечивать независимость компонентов, содавать системы мониторинга и оповещений.

#dia
Чтобы избегать ошибок людей, эксплуатирующих системы, нужно максимально ограничивать воздействие живых людей на приложение. Все что можно автоматизировать, должно быть автоматизировано. Кроме того, стоит проработать сценарии восстановления после ошибок операторов. Например, предоставить систему быстрого и простого отката изменений в конфигурации.

#dia
Масштабируемость

Готовность приложения к решению проблем возникающих при росте нагрузки.

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

После описания нагрузки, нужно выяснить: как повлияет на систему увеличение нагрузки? насколько нужно увеличить аппаратные мощности чтобы справиться с нагрузкой?

Для веб-сервисов самые важные метрики производительности — время ожидания и время отклика. Часто смотрят на медиану, 95-й перцентиль, 99-перцентиль и 99.9-й перцентиль.

> Измерять время отклика внутри приложения не стоит, это даёт недостоверные результаты. Лучше замерять на клиенте.

Масштабировать приложение можно вертикально — перейти на более мощный сервер. А можно горизонтально — распределить нагрузку на несколько менее мощных серверов. Для горизонтального масштабирования необходимо строить архитектуру, не предусматривающую разделения ресурсов. На практике часто совмещают два подхода и используют много очень мощных серверов.

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

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

#dia
Удобство сопровождения

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

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

+ удобство эксплуатации (мониторинг, автоматизация, документация, разумные дефолты, возможность самовосстановления, принцип наименьшего удивления, независимость от среды исполнения);

+ простота понимания (хорошие абстракции, явные зависимости, низкое сцепление модулей);

+ возможность развития на уровне всей системы.

#dia
Реляционная модель vs документноориентированная модель

Большая часть приложений работает с объектами, которые не очень хорошо ложатся на реляционную модель — это называют рассогласованием (impedance mismatch). Часто это проблема решает через ORM, но фигово.

С другой стороны, если структура данных представляет собой независимый документ, то ее удобно сохранить в документноориентированную БД (MongoDB, RethinkDB, CouchDB, Espresso) в виде JSON.

Такой подход упрощает создание связей «один-ко-многим», все «многие» хранятся просто внутри «одного». В итоге весь документ можно извлечь одним запросом. Но связи «многие-к-одному» и «многие-ко-многим» плохо вписываются в концепцию документноориентированных БД. А поддержка ссылок в таких базах обычно слабее чем в реляционных, часто приходится решать эту проблему на уровне приложения.

> По мере развития приложения, количество связей внутри модели данных обычно увеличивается.

В документноориентированных БД используется schema-on-read — схема данных неявная и их интерпретация происходит при чтении. В реляционных — schema-on-write, то есть схема данных проверяется при записи и все данные в базе гарантированно ей соответсвуют.

> Если в одной коллекции может храниться много разных типов объектов, или структура данных определяется внешним поставщиком — обычно удобнее использовать неявную схему.

Основные доводы в пользу документной модели данных — гибкость схемы, лучшая производительность вследствие локальности и большая близость к применяемым структурам данных (для некоторых приложений). Реляционная модель отвечает на это лучшей поддержкой соединений, а также связей «многие-к-одному» и «многие-ко-многим».

Похоже, что реляционные и документноориентированные БД становятся все более схожими и в итоге их модели дополняют друг друга. Вероятно, будущее за гибридными моделями.

#dia
Языки запросов для данных

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

Многие документные базы данных поддерживают некоторые подмножества модели программирования MapReduce. Это такой симбиоз декларативного и императивного API для обработки больших объемов данных.

Из-за того, что оптимизировать декларативные проще оптимизировать автоматически, во многие документные базы добавляют поддержку своих декларативных языков запросов. Например, так в MongoDB 2.2 добавили aggregation pipeline.

#dia