Контекст

Мы много читаем о масштабировании приложений и баз данных при проектировании систем. Наша команда прошла аналогичный путь масштабирования базы данных с высоким трафиком в PayPal.

Основная цель этой статьи - поделиться опытом построения масштабируемой системы с минимальным временем простоя и управляемыми расходами на инфраструктуру.

Чтобы справиться с ростом трафика, мы сначала сделали вертикальное масштабирование, добавив больше вычислительных ресурсов и ресурсов памяти. Объем запросов постоянно рос с годами, что затрудняло вертикальное масштабирование инфраструктуры без значительных простоев. Стоимость инфраструктуры для вертикального масштабирования, чтобы не отставать от роста трафика, также была очень высокой.

Позже мы представили реплики только для чтения (RO) как еще одну попытку масштабирования. Это решило некоторые из насущных проблем, но внесло другие сложности. Многие из наших вариантов использования требуют чтения данных сразу после их записи в источник записи (SOR), также известный как «чтение ваших собственных записей». Поскольку операции чтения обслуживаются объектами RO, а репликация данных из SOR в RO имела задержку, мы ввели кэширование для решения варианта использования «чтение собственных записей». Кэширование сделало код чрезвычайно сложным и трудным в обслуживании.

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

Ключевые ограничения

Любой проект решения масштабирования данных должен удовлетворять некоторым основным ограничениям:

  • Все существующие варианты использования должны поддерживаться.
  • На прикладном уровне должны быть минимальные изменения. Дизайн должен обеспечивать целостность прикладного уровня от логики масштабирования.
  • Требуется минимальная перебалансировка данных, возможность быстрого переключения при отказе и создание основы для географического распределения.
  • Дизайн не должен влиять на текущие SLA, включая задержку и другие показатели производительности.
  • Изменения следует ограничить серверной частью, поскольку существует множество клиентов с различными технологическими стеками и языками программирования.

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

Дизайн

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

Обзор

Подход, который мы использовали, заключается в горизонтальном масштабировании путем сегментирования данных по нескольким физическим базам данных. Логика сегментирования реализована в виде многоуровневой архитектуры. Ключ осколка хешируется и отображается в K сегментов. Корзина сопоставляется с одним из M логических сегментов с помощью таблицы базы данных. Логический осколок сопоставляется с одним из N физических осколков. Многоуровневая архитектура с косвенной адресацией позволяет в будущем дополнять физическую инфраструктуру с минимальным нарушением текущих транзакций.

Ключ разделения

Это один из первых шагов в дизайне. Выбор ключа осколка требует понимания текущего шаблона использования и будущего использования системы.

Глобальный вторичный индекс (GSI)

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

Логический и физический сегментирование

Данные разделены на K сегментов. Это дает нам возможность иметь K логических сегментов. Идентификатор шарда рассчитывается как хэш. Идентификатор шарда = (Хеш по ключу шарда)% K

Глобальный идентификатор (GID)

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

Обучение дизайну

  • Мы должны сделать логику приложения простой и прозрачной для логики сегментирования. Мы всегда должны помнить о конечном состоянии.
  • Нам нужно учитывать смешанный режим. Смешанный режим означает, что некоторые машины имеют текущую версию кода (N), а некоторые машины имеют более новую версию кода (N + 1). Это происходит по мере развертывания нового кода на сайте.
  • Мы не должны раскрывать клиентам внутренние идентификаторы. В нашем случае идентификаторы хранились в нескольких системах как в восходящем, так и в нисходящем направлении. При переходе на 64-битный глобальный идентификатор было очень сложно идентифицировать все места, где эти идентификаторы сохранялись.
  • Мы не должны тесно связывать модель данных предметной области с последующими корпоративными системами данных.
  • Нам следует изучить долгосрочный подход, а не краткосрочное решение.
  • У нас должна быть подробная и оптимизированная стратегия подключения.
  • У нас должен быть способ протестировать изменения инфраструктуры в производственной среде, прежде чем подключать функции. Важно понимать текущую топологию и найти способ протестировать доступ к новому пулу, чтобы заранее выяснить любые проблемы с опечатками в DNS или проблемы с сетевым подключением.
  • Мы должны убедиться, что мы тестируем нагрузку и производительность как для проводного, так и для автономного тракта.

Исполнение

Основой для выполнения является понимание экосистемы, включая клиентов, сложности, зависимости, варианты использования и потенциальное влияние из-за сбоев. Многие команды работали вместе, чтобы реализовать эти усилия.

  • Мы должны подготовить раздел данных. Работа над приложением включает в себя денормализацию таблиц, разрыв транзакций и объединений, подготовку sql к сегментированию, создание глобальных вторичных индексов и сценариев миграции для данных.
  • Работа над логическим сегментированием включает в себя автоматическое обнаружение ключа сегмента, перезапись SQL, включая внедрение ключа сегмента, маршрутизацию на основе ключа сегмента и обеспечение видимости нарушений. Приложение видит только одну цель, а сегменты прозрачны для приложения.
  • Работа над базой данных включает добавление ключа сегментирования во все таблицы, миграцию данных, целостность данных и обеспечение наличия всех баз данных и инфраструктуры. Значительная часть работы заключается в автоматизации перемещения данных между шардами.
  • Работа также включает обеспечение потоков данных между вышестоящими и нижележащими системами. Это включает в себя координацию с нижестоящими партнерами, чтобы гарантировать, что все изменения схемы завершены без влияния на последующую обработку.
  • В течение двух лет выпускались инкрементные выпуски, и было много партнерских отношений с различными командами, включая разработку релизов и операции с сайтом.

Обучение исполнению

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

Спонсорство

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

Основная команда

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

Партнеры и сотрудничество

Тесное сотрудничество со всеми зависимыми командами имеет решающее значение для успеха проекта такого масштаба.

Общение

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

Основывайтесь на победах

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

Сбои

Принимайте неудачи и учитесь на них.

Празднуйте прогресс

Иметь мотивированную команду, которая верит в инициативу и увлечена ею. Важно отмечать каждую победу - большую или маленькую.

Прилежание

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

Клиент прежде всего

Нам нужно убедиться, что это не повлияет на клиента. Тестирование одного сервера и медленное наращивание мощности гарантировали, что это не повлияет на клиента.

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