3.4

Смотреть на английском

3.4 Архитектура данных и хранение

Обзор и мотивация

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

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

Эта глава охватывает основные парадигмы хранения и когда использовать каждую, дисциплину полиглотной персистентности, моделирование данных и часто недооцениваемую проблему эволюции и миграции схем, кэширование и CDN (сети доставки контента) с пресловуто трудной проблемой инвалидации и то, как транзакции, блокировки и конкурентность ведут себя при доведении до масштаба. Сквозная линия проста: универсальной базы данных нет. Есть компромиссы, и хорошая архитектура данных означает их сознательный выбор, нагрузка за нагрузкой.

Ключевые принципы

  • Моделируйте данные под шаблоны доступа, а не наоборот. Проектируйте хранение вокруг того, как данные будут читаться и записываться, а не вокруг абстрактной «правильной» модели.
  • Нет одной базы данных, правящей всеми. Разным нагрузкам нужны разные механизмы; полиглотная персистентность в масштабе норма.
  • Корректность прежде всего для систем записи. Для авторитетных данных долговечность и согласованность не обсуждаются; оптимизируйте производительность вокруг них, а не за их счёт.
  • Схема будет меняться, поэтому планируйте это. Миграции это первоклассная непрерывная инженерная деятельность, а не разовая.
  • Владейте своими данными за границей сервиса. Каждый ограниченный контекст (самодостаточная модель предметной области с явной границей) владеет своими данными; общая база данных сцепляет команды и разрушает автономию.
  • Кэширование это проблема корректности, замаскированная под выигрыш производительности. Каждый кэш вносит устарелость и риск инвалидации; воспринимайте его намеренно.
  • Денормализация это размен, а не грех. Дублирование данных ради производительности чтения законно, если вы владеете последствиями для согласованности.
  • Согласованность и масштаб обмениваются. Чем сильнее транзакционная гарантия, тем труднее её распределить; покупайте только то, что нужно нагрузке.

Рекомендации

Выбирайте парадигму хранения по нагрузке

Сопоставьте каждую нагрузку с моделью, которая ей подходит. Реляционные базы данных дают сильную согласованность, соединения и зрелые транзакции; они умолчание для систем записи и всего со сложными правилами целостности. Документные хранилища подходят иерархическим, гибким по схеме данным, читаемым целиком (весь заказ, весь профиль). Ключ-значение хранилища дают крайнюю скорость для простых поисков (сессии, переключатели функций, кэши). Графовые базы данных блистают там, где отношения и есть запрос (кольца мошенников, оргструктуры, права, цепочки поставок). Колоночные хранилища питают аналитические запросы, просматривающие немного столбцов по миллиардам строк (хранилища данных, отчётность). Временных рядов базы данных оптимизированы под данные с преобладанием добавления и временными метками (метрики, телеметрия, датчики интернета вещей (IoT), рыночные данные). Сопротивляйтесь желанию заставить один механизм делать любую работу. Использование реляционной базы данных как очереди или документного хранилища как главной книги приглашает боль.

Принимайте полиглотную персистентность намеренно

Большие системы законно используют несколько хранилищ: реляционную систему записи, поисковый индекс, кэш, аналитическое хранилище и, возможно, графовый механизм или механизм временных рядов. Это полиглотная персистентность, и это правильный шаблон, когда нагрузки действительно различаются. Цена эксплуатационная, потому что теперь у вас больше механизмов для запуска, защиты, резервного копирования и укомплектования. Управляйте этой ценой, считая каждое хранилище принадлежащим сервису, стандартизируя эксплуатационные инструменты и ограничивая число технологий теми, что заслужили место. Остерегайтесь принимать новую базу данных для каждой мелкой нужды. Каждая постоянное эксплуатационное обязательство.

Моделируйте данные и воспринимайте эволюцию схемы как непрерывную

Заранее вкладывайтесь в моделирование данных для систем записи. Нормализуйте, чтобы защитить целостность, затем выборочно денормализуйте для доказанных горячих точек чтения. Какой бы ни была модель, схема эволюционирует вечно, поэтому делайте миграции безопасными и рутинными. Используйте версионированные автоматизированные односторонние скрипты миграции, хранимые в системе контроля исходного кода и применяемые через конвейер развёртывания. Для изменений без простоя на больших таблицах используйте шаблон расширить-сузить (параллельное изменение): добавьте новый столбец или таблицу, заполните и пишите в обе, переведите читателей, затем уберите старую форму. Никогда не одно ломающее изменение. Делайте изменения схемы обратно совместимыми между развёртываниями, чтобы старый и новый код работали одновременно. В событийно-хранимых и основанных на сообщениях системах явно версионируйте схемы событий и сообщений и поддерживайте повышение старых событий (преобразование их в текущую схему при чтении).

Проектируйте кэширование и инвалидацию с открытыми глазами

Кэширование и CDN самые рычажные инструменты производительности. CDN отдаёт статический и кэшируемый контент с края рядом с пользователями, а кэши приложений избавляют базу данных от повторных чтений. Но трудная часть инвалидация: знание, когда кэшированные данные устарели. Выбирайте стратегию по случаю. Используйте истечение по времени (TTL), где небольшая устарелость приемлема и проще всего. Используйте явную инвалидацию или сквозную запись, где важна свежесть. Используйте cache-aside, где приложение управляет наполнением. Задавайте TTL сознательно, защищайтесь от лавин кэша (много клиентов одновременно перестраивают одну и ту же истёкшую запись) блокировкой или объединением запросов и предотвращайте стадо на холодных кэшах. Никогда не кэшируйте данные, чья устарелость может вызвать отказ корректности или соответствия (права, балансы, согласие), без явного протестированного пути инвалидации. Воспринимайте ключи кэша, TTL и инвалидацию как спроектированные артефакты, а не случайную конфигурацию.

Управляйте транзакциями, блокировками и конкурентностью для масштаба

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

Компромиссы: плюсы и минусы

Тип хранилищаЛучше всего дляСильные стороныСлабые стороны
РеляционноеСистем записи, сложной целостностиACID, соединения, зрелые инструментыТруднее горизонтально масштабировать запись
ДокументноеАгрегатных чтений, гибкой схемыБыстрое чтение/запись целого объекта, гибкостьСлабые междокументные соединения/транзакции
Ключ-значениеСессий, кэшей, простых поисковКрайняя скорость и масштабНет запросов кроме ключа
ГрафовоеЗапросов, насыщенных отношениямиБыстрые обходы, выразительностьНишевые эксплуатационные навыки, пределы масштабирования
КолоночноеАналитики, отчётностиБыстрые агрегатные сканирования, сжатиеПлохо для построчных транзакционных записей
Временных рядовМетрик, телеметрии, IoTЭффективные добавление и временные запросыУзкое назначение

Доминирующий компромисс это согласованность и богатые запросы против горизонтальной масштабируемости и скорости. Реляционные системы дают сильнейшие гарантии и самые гибкие запросы, но труднее всего масштабируют запись на многие машины. Семейства NoSQL (нереляционных) ослабляют соединения, транзакции или схему ради масштаба и скорости. Кэширование меняет свежесть на задержку. Шардирование меняет межраздельные транзакции на пропускную способность записи. Ничто из этого не универсально верно. Искусство в том, чтобы поместить каждую нагрузку в точку кривой, которой её потребности в корректности и производительности действительно требуют.

Вопросы для обсуждения с командой

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

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

  3. Где пользователь может прочитать устаревшее значение с реплики сразу после собственной записи и нарушает ли это обещание, которое вы ему дали? Реплики чтения масштабируют чтение, но отстают от первичной базы, поэтому пользователь, обновивший профиль и тут же перезагрузивший страницу, может увидеть старое значение, что читается как ошибка или, для баланса или флага согласия, как провал соответствия. Решите по потоку, важно ли чтение собственных записей, и направьте такие чтения на первичную базу или используйте механизм согласованности сессии. Принесите список потоков, обслуживаемых репликами, и отметьте те, по которым пользователь действует сразу после записи. Для балансов, прав и согласия воспринимайте устаревшие чтения как отказы корректности, а не косметические. Суть в том, чтобы покупать согласованность, действительно нужную каждой нагрузке, и делать принимаемую вами устарелость явной, а не случайной.

  4. Можете ли вы сегодня изменить схему вашей крупнейшей, самой загруженной таблицы без простоя и кто на самом деле отрабатывал шаги «расширить-сузить»? Схема эволюционирует вечно, а отказ, который вредит больше всего, это ломающее изменение «большим взрывом», блокирующее огромную таблицу, замораживающее сервис и не откатываемое чисто. В большой команде риск умножается, потому что несколько сервисов читают одну форму, поэтому ломающее изменение требует, чтобы старый и новый код работали бок о бок через поэтапное развёртывание. Противоположное тяготение это скорость: одно изменение пишется быстро, тогда как «расширить-сузить» (добавить новую форму, заполнить, писать в обе, перевести читателей, убрать старую форму) больше шагов и больше терпения. Принесите вашу крупнейшую таблицу, честную оценку того, как долго наивное изменение блокировало бы её, и конкретную миграцию, которую кто-то прогнал от начала до конца на репетиции, а не в теории. В корпоративных и государственных системах, работающих непрерывно и несущих целевые показатели доступности, установленные законом, простой при миграции нарушение, поэтому дисциплина «расширить-сузить» плата за разрешение вообще менять схему.

  5. Какие кэшированные или реплицированные значения при выдаче в устаревшем виде вызвали бы отказ соответствия или безопасности, а не косметический, и протестирован ли путь инвалидации каждого из них? Кэширование это проблема корректности в костюме производительности: опасность не в медлительности, а в выдаче права, баланса, флага согласия или решения о доступе после того, как они изменились. Для большой организации опасность рассеяна, потому что кэши и краевые слои накапливаются по командам, и ни один человек не может перечислить, что где кэшируется и когда сбрасывается. Напряжение реально: агрессивное кэширование и длинные TTL покупают задержку и защищают базу данных, тогда как строгая свежесть стоит и того и другого. Принесите опись кэшированных и обслуживаемых CDN данных с пометкой, какие записи несут последствия для соответствия или безопасности, плюс свидетельство того, что путь инвалидации каждой из них испытан на практике, а не просто настроен. В регулируемой и государственной среде устаревшее значение согласия или права проверяемый отказ, поэтому таким элементам нужен явный протестированный путь инвалидации, иначе их не следует кэшировать вовсе.

  6. Какова ваша стратегия хранения, архивирования и размещения данных для каждого авторитетного хранилища и можете ли вы доказать её аудитору? Данные переживают код и часто переживают команду, которая его писала, поэтому неограниченный рост и расплывчатые правила размещения тихо становятся проблемой, которой никто не владеет, пока таблица не становится неуправляемой, а запись не оказывается не в той юрисдикции. Большая организация охватывает много хранилищ и регионов, а противоположные соображения это стоимость (горячее хранилище дорого, поэтому архивируйте и ярусуйте), производительность (раздутые таблицы замедляют всё) и юридическая обязанность (установленные законом нижние пределы хранения и верхние пределы размещения, способные конфликтовать). Принесите для каждого авторитетного набора данных срок хранения, где данные физически живут, механизм архивирования и удаления и имя ответственного. Для корпоративных и особенно государственных систем хранение и размещение обычно юридические мандаты с требованиями аудита и суверенитета, поэтому возможность доказать, где живёт каждая запись, как долго хранится и когда уничтожается, это лицензия на деятельность, а не любезность.

Взгляд по секторам

Стартап. Запускайте одну базу данных и сопротивляйтесь зоопарку. Единое управляемое реляционное хранилище даёт транзакции, одну вещь для резервного копирования и одно место для рассуждения о согласованности, а это именно то, что команда из трёх человек может удержать в голове. Добавляйте кэш, реплику чтения или поисковый индекс, только когда конкретный медленный запрос или реальный объём чтения вынуждает, чтобы сложность приходила с оплаченной причиной. Версионируйте миграции с первого дня, потому что дооснащение дисциплины миграций в живой продукт гораздо труднее, чем начать с неё.

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

Крупная организация. Основная трудность полиглотная персистентность между многими командами: реляционная система записи плюс поиск, кэш, хранилище и, возможно, графовые механизмы или механизмы временных рядов, каждое во владении сервиса, а не общее. Стандартизируйте эксплуатационные инструменты, резервное копирование и мониторинг по сохраняемым хранилищам, удерживайте принятие нового механизма на высокой планке и делайте миграции «расширить-сузить» и явную инвалидацию кэша умолчанием. Управляйте хозяйством как портфелем с ясным владением данными, чтобы ни один механизм не пережил нагрузку, которая его оправдала, и ни одна команда не была сцеплена через общую базу данных.

Государственный сектор. Размещение данных, установленное законом хранение и доказуемая целостность определяют каждый выбор. Разворачивайте каждое хранилище в суверенных регионах, настраивайте CDN кэшировать только неперсональные данные и держите неизменяемую историю аудита для записей, которые должны быть восстановимы для регуляторов. Миграции, предписанные новым законодательством, нужно применять обратно совместимо через конвейер, чтобы сервис оставался доступным в законодательные сроки, а систему записи должно быть возможно определить, чтобы вы могли доказать, какое значение юридический источник, и перестроить из него каждую производную копию.

Примеры

Стартап. Стартап начальной стадии запускает всё на одном управляемом экземпляре PostgreSQL и сопротивляется желанию добавить отдельный поисковый механизм, кэш и хранилище, пока в них нет нужды. Одна база данных означает одну вещь для резервного копирования, одно место для рассуждения о согласованности и транзакции, которые просто работают, что важно, когда вся команда три инженера. Они добавляют кэш Redis и реплику чтения только когда конкретный медленный запрос и реальный объём чтения это оправдывают, так что сложность приходит с оплаченной причиной, а не раньше неё.

Крупная организация. Розничный банк хранит авторитетную главную книгу в строго согласованной реляционной базе данных: каждая проводка это настоящая транзакция ACID, шардированная по диапазону счетов для масштаба записи. Вокруг неё полиглотное хозяйство: поисковый индекс для поиска клиентов, кэш Redis (сквозная запись, короткий TTL) для сводок по счетам в мобильном приложении, колоночное хранилище для регуляторной и аналитической отчётности и графовая база данных для обнаружения мошенничества в сети транзакций. Изменения схемы главной книги используют «расширить-сузить» с записью в обе, чтобы система 24/7 никогда не простаивала ради миграции.

Государственный сектор. Национальный реестр транспортных средств хранит авторитетные записи в реляционной системе записи с установленным законом хранением и полной историей аудита. Публичные поиски «проверить транспортное средство» обслуживаются с реплики чтения и краевого кэша с коротким TTL, потому что слегка устаревшие публичные данные приемлемы, а объём чтения затмевает запись. Закон о размещении данных требует, чтобы все записи оставались в стране, поэтому каждое хранилище развёрнуто в суверенных регионах, а CDN настроен кэшировать только неперсональные данные. Миграции для добавления новых полей, предписанных транспортной политикой, применяются обратно совместимо через конвейер, чтобы сервис оставался доступным в законодательные сроки.

Бизнес-обоснование: мотивы, ROI и TCO

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

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

Антипаттерны и ловушки

  • Общая база данных между сервисами. Несколько сервисов читают и пишут одну схему, сцепляя команды и превращая каждое изменение в кризис координации.
  • Одна база данных для всего. Навязывание аналитики, очередей, поиска и транзакций одному реляционному механизму, пока он не рухнет.
  • Миграции «большим взрывом». Единые ломающие изменения схемы, требующие простоя и не откатываемые безопасно.
  • Кэширование без стратегии инвалидации. Устаревшие данные выдаются бесконечно или ошибки корректности, потому что никто не владеет моментом сброса кэша.
  • Преждевременное шардирование. Распределение данных до того, как нагрузка этого требует, с постоянной потерей соединений и транзакций без пользы.
  • Игнорирование отставания репликации. Чтение собственной записи с отстающей реплики и получение устаревших данных, нарушающее ожидания пользователей.
  • Неограниченный рост данных. Нет стратегии архивирования или хранения, поэтому таблицы растут, пока производительность и стоимость не становятся непереносимыми.
  • Хранение производных данных как истины. Воспринимание кэша, индекса или проекции как системы записи с последующим обнаружением её дрейфа.

Модель зрелости

  • Уровень 1: Начальный. Одна база данных используется для всех целей. Изменения схемы ручные и стихийные, без дисциплины миграций. Кэширование случайно, а инвалидация запоздалая мысль. Проблемы производительности решаются реактивно покупкой более крупной машины, и никто не может надёжно назвать систему записи для данного набора данных.
  • Уровень 2: Развитие. Некоторые выборы хранилищ намеренны, появился кэш или хранилище, но практика различается по командам. Миграции версионируются, но иногда требуют простоя, а «расширить-сузить» используется тем, кто случайно знает об этом. Несколько сервисов по-прежнему делят базу данных, а стратегии кэширования различаются от команды к команде.
  • Уровень 3: Стандартизация. Полиглотная персистентность сопоставлена с нагрузками, каждое хранилище во владении сервиса и никогда не общее. Автоматизированные, обратно совместимые миграции «расширить-сузить» без простоя документированный, обеспечиваемый стандарт по организации. Стратегии кэширования, TTL и пути инвалидации явные проектные артефакты, а единая система записи для каждого набора данных задокументирована, и производные копии перестраиваемы из неё.
  • Уровень 4: Управление. Хозяйство данных измеряется и контролируется относительно базовых значений. Вы отслеживаете длительность миграций и долю откатов, отставание репликации относительно требований чтения собственных записей, долю попаданий в кэш и инциденты устаревания, эксплуатационную стоимость по хранилищам и задержку запросов на целевых процентилях и действуете по числам. Хранение и размещение проверяются на соответствие требованиям закона, корректность производных данных проверяется непрерывно, и каждый механизм должен оправдывать свою стоимость нагрузкой, которую обслуживает.
  • Уровень 5: Оркестрация. Архитектура данных непрерывно улучшается и интегрирована с планированием мощностей, стоимости и рисков по организации. Выбор шардирования, кэширования и согласованности перебалансируется по нагрузке по мере смещения шаблонов доступа и стоимости, а хранилища, не заслуживающие больше места, выводятся плановыми миграциями. Эволюция схем, архивирование и размещение полностью автоматизированы и адаптивны, так что хозяйство перестраивается под новые мандаты и нагрузку без аварийного переустройства платформы.

Идеи для обсуждения

  1. Какие из ваших нынешних хранилищ выполняют работу, для которой не проектировались, и какой механизм был бы правильным?
  2. Можете ли вы сегодня выполнить изменение схемы на вашей крупнейшей таблице без простоя? Если нет, почему?
  3. Где ваша система кэширует данные, чья устарелость может вызвать отказ соответствия или корректности?
  4. Какие сервисы делят базу данных и что потребовалось бы, чтобы дать каждому собственную?
  5. Где единая записываемая база данных ваш потолок масштабирования и репликация чтения или шардирование верный следующий шаг?
  6. Какова ваша стратегия хранения и архивирования и кто за неё отвечает?

Главные выводы

  • Данные переживают код; решения о хранении и моделировании ограничивают бизнес на всю жизнь системы.
  • Сопоставляйте каждую нагрузку с парадигмой хранения, подходящей её шаблону доступа; ожидайте полиглотную персистентность в масштабе.
  • Давайте каждому сервису владение его данными; никогда не сцепляйте команды через общую базу данных.
  • Воспринимайте эволюцию схемы как непрерывную и используйте обратно совместимые миграции «расширить-сузить» без простоя.
  • Кэширование это проблема корректности: проектируйте TTL, инвалидацию и защиту от лавин намеренно и никогда не кэшируйте критичные для соответствия данные без протестированного пути инвалидации.
  • Покупайте только те гарантии согласованности и транзакций, что нужны каждой нагрузке; шардирование и репликация меняют межраздельные транзакции на масштаб.

Источники и дополнительное чтение

  • Martin Kleppmann, Designing Data-Intensive Applications
  • Pramod Sadalage and Martin Fowler, NoSQL Distilled
  • Pramod Sadalage and Scott Ambler, Refactoring Databases: Evolutionary Database Design
  • C. J. Date, An Introduction to Database Systems
  • Joe Celko, SQL for Smarties
  • Vlad Mihalcea, High-Performance Java Persistence (transactions, isolation, concurrency)
  • Eric Evans, Domain-Driven Design (bounded contexts and data ownership)
  • Werner Vogels, “Eventually Consistent”