[00:02] хранить миллиарды фотографий или Google индексировать триллионы веб-страниц? В этом видео мы рассмотрим важнейшие концепции управления данными и масштабируемости, лежащие в основе современных распределенных систем. Эти шаблоны [00:15] позволяют высокомасштабным системам эффективно обрабатывать огромные объемы данных. Давайте посмотрим. Разделение данных на сегменты позволяет разбить набор данных на более мелкие и удобные для управления части, оптимизируя производительность и масштабируемость. Существует два основных [00:30] подхода к разделению данных. Вертикальное секционирование разделяет таблицу по столбцам на основе шаблонов доступа и характеристик данных. Такой подход позволяет хранить часто используемые данные отдельно от редко используемых [00:44] кодовых данных. Большие текстовые поля и бинарные объекты можно отделить от структурированных данных для оптимизации шаблонов ввода-вывода при хранении . Например, в таблице профиля пользователя основная информация может храниться в одном разделе, а подробный биографический текст — в [01:00] другом. Горизонтальное секционирование разделяет таблицы по строкам, обычно используя ключ секционирования для определения того, какие строки относятся к какой секции. Этот подход хорошо работает, когда данные можно четко разделить на основе определенного атрибута, [01:16] такого как ценовые диапазоны или географические регионы. Например, таблица транзакций может быть разделена по месяцам, что позволит запросам за определенные периоды времени обращаться только к соответствующим разделам. Правильно реализованное [01:30] разделение данных может уменьшить количество операций ввода-вывода для смешанных рабочих нагрузок за счет согласования размещения данных с шаблонами доступа. Повышение производительности достигается за счет более эффективного использования памяти и сокращения объема сканирования данных во время выполнения запросов. [01:46] Шардинг базы данных расширяет возможности горизонтального разделения данных, позволяя распределять их между несколькими независимыми экземплярами базы данных или серверами. В то время как разделение данных на разделы обычно происходит внутри одной базы данных, сегментирование охватывает несколько баз данных, часто расположенных [02:01] на отдельных физических машинах. Шардинг распределяет данные с использованием ключей разделов и стратегий шардинга. Хэш- шардинг применяет хэш-функцию к короткому ключу, равномерно распределяя данные, но делая запросы к диапазону неэффективными. [02:16] Сегментирование на основе диапазонов назначает строки сегментам на основе диапазонов ключей, что оптимизирует запросы к диапазонам, но может создавать «горячие точки». При сегментировании на основе каталогов используется служба поиска для сопоставления ключей с сегментами. Это обеспечивает большую [02:31] гибкость за счет дополнительной сложности. Влияние сегментирования на производительность существенно. Основные платформы используют сегментирование данных для обработки огромных объемов данных и нагрузок на запись, которые могли бы перегрузить [02:43] отдельный экземпляр базы данных. Они могут достичь почти линейной масштабируемости, распределяя данные по сотням физических серверов посредством логического сегментирования. Одной из существенных проблем при сегментировании является обработка операций, [02:57] охватывающих несколько коротких сегментов. Перекрестные запросы и транзакции усложняют процесс, поскольку требуют координации между отдельными экземплярами базы данных. Это может повлиять на производительность и усложнить [03:13] вспомогательные структуры данных, которые оптимизируют шаблоны запросов за счет увеличения объема памяти и накладных расходов на запись. Современные базы данных реализуют различные типы индексов. B-дерево индексов представляет собой сбалансированное дерево, поддерживающее отсортированные данные для [03:27] запросов диапазона и точечного поиска. Хэш-индексы обеспечивают прямой поиск по ключу и местоположению, но не поддерживают запросы по диапазону. Битовые индексы эффективны для столбцов с низкой кардальностью, таких как логические флаги или коды состояния. Инвертированные индексы сопоставляют содержимое с [03:44] записями. Они предоставляют возможности полнотекстового поиска . Правильно расположенный индекс может превратить полное сканирование таблицы, занимающее минуты, в обход таблицы B3, завершающийся за миллисекунды. Однако каждый дополнительный индекс влечет за собой определенные [03:58] накладные расходы, поскольку база данных должна поддерживать эти структуры во время операций вставки и обновления. Это представляет собой прямой компромисс в проектировании баз данных, который инженеры должны учитывать. Репликация обеспечивает наличие копий данных на нескольких узлах для повышения [04:14] масштабируемости и отказоустойчивости. Давайте поговорим о том, как работает репликация на практике. Существует три основных подхода. При репликации с одним лидером все права принадлежат одному лидеру . После того как ведущий узел обработает [04:26] данные и сохранит их, он принудительно внесет эти изменения во все узлы-реплики. Это обеспечивает четкую и последовательную последовательность действий. Многократная репликация позволяет подтвердить права доступа нескольким ведущим узлам. Каждый лидер сообщает о своих [04:41] изменениях другим лидерам. Это повышает доступность прав, но создает проблему обработки конфликтующих обновлений, что требует сложных механизмов разрешения конфликтов для систем без лидера. [04:54] Для обеспечения согласованности несколько узлов могут принимать права доступа . В этих системах реализованы кворумы, при которых операции завершаются успешно, если их подтверждают минимальное количество узлов, а также механизмы восстановления данных, которые исправляют устаревшие данные во время [05:08] операций чтения. Когда данные записываются на ведущую реплику, но еще не достигли всех реплик, это называется задержкой репликации. В асинхронных системах эта задержка обычно составляет от миллисекунд до секунд в зависимости от состояния сети. [05:23] Во многих производственных системах используется компромиссный вариант, называемый полусинхронной репликацией. Запись считается успешной, если хотя бы одна реплика подтверждает получение. Такой подход позволяет достичь баланса между производительностью и надежностью данных. [05:38] Кэшируемые хранилища часто обращаются к данным на уровнях быстрого доступа, чтобы уменьшить задержку и нагрузку на бэкэнд. Разница в производительности между доступом к кэшу e-memory и данным доступом остается существенной. Современные системы реализуют [05:52] несколько ключевых стратегий кэширования. Помимо кэширования, также называемого отложенной загрузкой, приложение сначала проверяет наличие кэша. Если данные не найдены, они извлекаются из базы данных и заполняют кэш для будущих запросов. Кэширование с непрерывной записью [06:07] синхронно обновляет как кэш, так и базу данных при изменении данных. Это обеспечивает согласованность между кэшем и хранилищем, но увеличивает задержку справа, поскольку каждая операция должна завершиться в обеих системах. Сразу после кэширования или обратной записи [06:22] кэш обновляется немедленно, но изменения в базе данных записываются асинхронно. Это повышает производительность, но создает риск потери данных при сбоях до их сохранения. Сети доставки контента ( [06:37] CDN) доставляют контент с серверов, расположенных в непосредственной близости от конечных пользователей, чтобы минимизировать задержку в сети. Основной принцип работы CDN — географическое распределение с интеллектуальной маршрутизацией. Когда пользователь запрашивает контент, CDN [06:52] перенаправляет его на оптимальный S-сервер одним из нескольких способов. Anycast, одним из нескольких способов. Anycast, перенаправление DNS-пространства или HTTP-перенаправления. Разница в производительности существенная. Современные CDN обеспечивают [07:05] время отклика для содержимого кэша от 30 до 50 миллисекунд по сравнению с 200–500 миллисекундами для всех запросов к регионам. Масштабируемость измеряет, как изменяется производительность системы при добавлении новых ресурсов. Линейное масштабирование — это идеальный [07:21] сценарий. Удвоение ресурсов удваивает производительность. На практике это случается редко . В большинстве систем наблюдается сублинейное масштабирование из-за двух факторов. Штрафы за разногласия и за несогласованность. Конфликты возникают, когда компоненты [07:36] конкурируют за совместно используемые ресурсы, такие как блокировки или сетевые соединения. Проблемы с согласованностью данных возникают из-за накладных расходов на поддержание согласованности данных в нескольких местах. Обсужденные нами методы управления данными помогают свести к минимуму эти [07:50] ограничения. При внедрении этих концепций управления данными и масштабируемости следует учитывать следующие инженерные принципы. Начните с самого простого варианта реализации, отвечающего текущим потребностям. Тщательно изучите инструментарий, чтобы [08:04] выявить реальные узкие места, прежде чем усложнять систему. Принимайте во внимание как эксплуатационные издержки, так и преимущества в производительности, а также оценивайте влияние каждого проектного решения на согласованность, доступность и задержку . [08:19] Если вам нравятся наши видео, вам может понравиться и наша рассылка по системному проектированию. Издание освещает темы и тенденции в проектировании крупномасштабных систем и пользуется доверием миллиона system design, trusted by 1 million readers. Subscribe at blog.biteby.com.