Архитектура и практика хранения KV Meituan триллионного уровня

Redis задняя часть
Архитектура и практика хранения KV Meituan триллионного уровня

Являясь важной службой онлайн-хранилища Meituan, хранилище KV обрабатывает триллионы запросов в день для онлайн-сервисов. На Глобальной конференции по разработке программного обеспечения QCon 2019 (Шанхайская станция) Ци Зебинь, старший технический эксперт Meituan, поделился «Комментариями Meituan об архитектуре и практике хранения KV триллионного уровня». в основном разделен на четыре части: первая часть описывает процесс разработки хранилища Meituan KV; вторая часть описывает архитектуру и практику памяти KV Squirrel; третья часть знакомит с архитектурой и практикой постоянного KV Cellar; и, наконец, делится планами на будущее и новыми тенденции в отрасли.

История развития хранилища Meituan-Dianping KV

Распределенное хранилище KV первого поколения Meituan показано в архитектуре в левой части рисунка ниже, я думаю, что многие компании прошли этот этап. Выполнение согласованного хеширования в клиенте и развертывание множества экземпляров Memcached в бэкэнде реализует самый простой распределенный дизайн хранилища KV. Однако с таким дизайном есть явные проблемы: например, при выводе ноды из простоя данные будут потеряны, места в кеше не хватит и его нужно расширить, а консистентный хэш тоже потеряет часть данных, д., что принесет много хлопот развитию бизнеса.

С развитием проекта Redis Meituan также представила Redis для решения упомянутых выше проблем, а затем разработала архитектуру, как показано в правой части рисунка выше. Как видите, клиент все тот же, использующий алгоритм согласованного хеширования, а сервер стал структурой master-slave, состоящей из Redis. Когда какой-либо узел выходит из строя, мы можем выполнить отработку отказа с помощью Redis Sentinel, чтобы добиться высокой доступности. Но есть проблема, которая не решена: если емкость увеличить или уменьшить, то консистентный хэш все равно потеряет данные, так как же решить эту проблему?

В это время мы обнаружили, что существует относительно зрелый проект хранилища KV с открытым исходным кодом: Ali Tair. В 2014 году мы представили Tair для удовлетворения потребностей бизнес-хранилищ KV. Архитектура версии Tair с открытым исходным кодом в основном разделена на три части: нижняя часть приведенного выше рисунка — это узел хранения, узел хранения будет сообщать о пульсе своему центральному узлу, а внутри центрального узла есть два узла управления конфигурацией. узел, который будет контролировать все узлы хранения. Когда какой-либо узел хранения выходит из строя или расширяется, он перестраивает топологию кластера. Когда клиент запускается, он получает таблицу маршрутизации непосредственно с центрального узла. Эта таблица маршрутизации представляет собой просто схему распределения данных кластера, и клиент напрямую считывает и записывает в узел хранения в соответствии с таблицей маршрутизации. В ответ на предыдущую проблему расширения KV и потери данных он также имеет механизм переноса данных для обеспечения целостности данных.

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

Буквально в 2015 году Redis официально выпустила кластерную версию Redis Cluster. Поэтому мы не отставали от темпов сообщества и проделали большую работу по разработке в сочетании с внутренними потребностями, а также разработали Squirrel для хранения KV с полной памятью, высокой пропускной способностью и малой задержкой. Кроме того, на основе Таира мы также добавили множество собственных функций и разработали Cellar, хранилище KV, которое является постоянным, большой емкостью и высоконадежным для данных. Поскольку версия Tair с открытым исходным кодом не обновлялась в течение четырех или пяти лет, итерация Cellar полностью разработана Meituan самостоятельно, и сообщество Redis было очень активным. В общем, итерация Squirrel — это и самоисследование, и сообщество, и дизайн функций самоисследования будет стараться быть совместимым с официальной архитектурой. Как вы можете увидеть позже, из-за этих различий Cellar и Squirrel также выбрали разные конструкции для решения одной и той же проблемы.

Эти два хранилища фактически являются разными решениями в области хранения КВ. В практических приложениях, если объем данных предприятия невелик и чувствителен к задержкам, мы рекомендуем вам использовать Squirrel; если объем данных велик и не особенно чувствителен к задержкам, мы рекомендуем использовать Cellar с меньшими затратами. В настоящее время ежедневные вызовы этих двух систем хранения KV в Meituan превысили один триллион, а их пиковые запросы также превысили сто миллионов в секунду.

Memory KV Squirrel Архитектура и практика

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

KV 数据分布介绍

Далее, давайте поговорим о познании архитектуры высокой доступности Лично я считаю, что высокую доступность можно рассматривать как с макро-, так и с микроперспективы. С макроэкономической точки зрения высокая доступность относится к тому, как выполнять аварийное восстановление. Например, если нода зависла, что делать? Компьютерный зал или группа компьютерных залов в определенном регионе не работают, что делать? С микроперспективы высокая доступность — это то, как обеспечить высокую сквозную вероятность успеха. Можем ли мы добиться высокой доступности бизнес-запросов, выполняя некоторые обновления эксплуатации и обслуживания или перенос данных расширения и сокращения? В этой статье также будет рассказано о некоторых работах по обеспечению высокой доступности, проделанных Meituan как с макро-, так и с микроперспективы.

Squirrel 架构

На картинке выше показана наша архитектура Squirrel. Средняя часть соответствует официальному кластеру Redis. Он имеет структуру master-slave, а экземпляры Redis взаимодействуют через протокол Gossip. Справа мы добавили платформу планирования кластера, включая службы планирования, службы масштабирования и службы высокой доступности. Она будет управлять всем кластером и обновлять результаты управления в ZooKeeper в виде метаданных. Наш клиент будет подписываться на изменения метаданных в ZooKeeper, получать состояние топологии кластера в режиме реального времени и выполнять операции чтения и записи непосредственно в кластере Redis.

Аварийное восстановление Squirrel Node

Тогда посмотрите, как выполнить аварийное восстановление Squirrel. Для кластера Redis существует полный механизм для борьбы с простоем узла. Согласно официальному решению, обычно требуется 30 секунд, чтобы любой узел вышел из строя и был удален как FAIL. Удаление основной библиотеки может повлиять на целостность данных, поэтому нужно быть осторожным. Но как насчет рабских библиотек? Мы считаем этот процесс совершенно ненужным. Еще один момент, все мы знаем, что объем данных для хранения KV в памяти, как правило, относительно невелик. Для компаний с большим объемом бизнеса, как правило, имеется много кластеров. Если произойдет сбой коммутатора, это повлияет на многие кластеры, и будет очень проблематично сделать копии после простоя. Чтобы решить эти две проблемы, мы создали службу высокой доступности HA.

Его архитектура показана на рисунке ниже, и он отслеживает все узлы кластера в режиме реального времени. Будь то дрожание сети или время простоя (например, Redis 2), он может обновлять ZooKeeper в режиме реального времени и сообщать ZooKeeper об удалении Redis 2. После того, как клиент получит сообщение, трафик чтения будет направлен непосредственно в Redis 3. Если у Redis 2 есть только десятки секунд сетевого джиттера, через десятки секунд, если узел HA отслеживает, что он восстановился, он будет добавлен обратно.

Squirrel—节点容灾

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

Приведенным выше решением мы сократили время удаления из репозитория с 30 до 5 секунд. Кроме того, мы используем HA для автоматического применения экземпляров контейнера для присоединения к кластеру, превращая копирование во время простоя в автоматическую операцию на уровне минуты без какого-либо ручного вмешательства.

Межрегиональное аварийное восстановление Squirrel

Мы решили проблему простоя одного узла, так как же решить межрегиональную проблему? Давайте сначала посмотрим на различия между регионами. Во-первых, по сравнению с сетью в компьютерном зале того же региона межрегиональная частная линия очень нестабильна; во-вторых, пропускная способность межрегиональной частной линии очень ограничена и дорога. Репликация внутри кластера не учитывает экстремальные сетевые среды. Если мы развернем основную базу данных в Пекине, а две подчиненные базы данных — в Шанхае, один и тот же фрагмент данных придется передавать дважды по выделенной линии, идущей на север, что приведет к огромной трате пропускной способности выделенной линии. Кроме того, с развитием и эволюцией бизнеса мы также занимаемся унифицированным развертыванием и удаленной многоактивной архитектурой. Использование официальной синхронизации master-slave не может удовлетворить наши потребности. Исходя из этого, мы сделали схему репликации между кластерами.

Как показано на рисунке выше, здесь нарисованы главный кластер в Пекине и подчиненный кластер в Шанхае.Что нам нужно сделать, так это синхронизировать данные главного кластера в Пекине с подчиненным кластером в Шанхае через службу синхронизации кластеров. Согласно процессу, задача "установления канала синхронизации между двумя кластерами" должна быть сначала выдана нашему модулю планирования синхронизации. Модуль планирования синхронизации выдаст задачу синхронизации между ведущим и подчиненным кластерами для синхронизации кластера. После получения задача синхронизации, кластер синхронизации будет действовать как ведомое устройство Redis и извлекать данные из ведомой библиотеки на основном кластере через протокол репликации Redis, включая RDB и последующие добавочные изменения. После того, как машина синхронизации получит данные, они будут преобразованы в команду записи от клиента и записаны на главный узел шанхайского подчиненного кластера. Таким образом мы синхронизируем данные главного кластера в Пекине с подчиненным кластером в Шанхае. Точно так же нам также очень просто выполнять несколько действий в разных местах.С помощью обратной связи синхронизации можно добиться двусторонней синхронизации между кластерами.

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

  • Миграция данных вызывает дрожание времени ожидания.
  • Постоянство вызывает дрожание времени ожидания.
  • Запросы Hotspot Key вызывают перегрузку одного узла.

Squirrel Smart Migration

При переносе данных мы в основном столкнулись с тремя проблемами:

  • Хотя Redis Cluster предоставляет возможности переноса данных, ему все равно, какие слоты должны быть перенесены и откуда переносятся слоты.
  • При переносе данных все думают, что чем быстрее, тем лучше, но скорость переноса может повлиять на обычные бизнес-запросы.
  • Команда Redis Migrate заблокирует рабочий поток, особенно при переносе больших значений, он будет заблокирован на долгое время.

Для того, чтобы решить эти проблемы, мы сделали совершенно новый миграционный сервис.

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

  • Во-первых, между узлами миграции в кластере будет параллелизм, например одновременная выдача команд миграции в Redis 1 и Redis 3.
  • Во-вторых, каждая команда Migrate будет переносить пакет ключей.
  • В-третьих, мы будем использовать службу мониторинга для сбора данных об успешности, времени, нагрузке на сервер, QPS и т. д. клиента в режиме реального времени, а затем передавать этот статус обратно на машину миграции. Процесс переноса данных аналогичен процессу медленного старта TCP, он будет все время увеличивать скорость, если процент успешных запросов падает, его скорость будет уменьшаться, а конечная скорость миграции стабилизируется в динамическом балансе, так что достижение самая быстрая миграция при минимизации обычных бизнес-запросов.

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

Squirrel Persistence Рефакторинг

RDB генерируется, когда Redis master-slave синхронизируется. Процесс создания RDB вызовет Fork для создания подпроцесса для записи данных на жесткий диск.Хотя Fork имеет механизм COW операционной системы, когда использование памяти достигает 10G или 20G, весь процесс все равно будет заблокирован в секундах. Это практически неприемлемо для онлайн-бизнеса. Мы также включим AOF для служб с высокими требованиями к надежности данных, а открытие AOF может привести к блокировке процесса из-за джиттера ввода-вывода, что также повлияет на процент успешных запросов. Для этих двух проблем официального механизма сохраняемости наше решение состоит в том, чтобы реконструировать механизм сохраняемости.

На картинке выше показана наша последняя версия механизма персистентности Redis.Запрос на запись будет сначала записан в БД, а затем записан в невыполненную работу памяти, которая совпадает с официальной. В то же время он отправит запрос в асинхронный поток, а асинхронный поток отвечает за сброс изменений в Backlog жесткого диска. Когда на жестком диске слишком много невыполненных работ, мы возьмем на себя инициативу по созданию RDB в период низкой нагрузки, а затем удалим невыполненную работу, созданную до RDB.

Если мы хотим выполнить синхронизацию master-slave в это время, что нам делать? Первый шаг все тот же, что и официальный, ищем нужную точку синхронизации в бэклоге памяти, если нет, то идем в бэклог жесткого диска, чтобы найти точку синхронизации. Из-за большого объема жесткого диска в Backlog жесткого диска может храниться особенно большой объем данных, поэтому редко возникает ситуация, когда точку синхронизации невозможно найти. Если нет невыполненной работы на жестком диске, мы инициируем операцию, аналогичную полной повторной передаче, но полная повторная передача здесь не требует создания RDB на месте, она может напрямую использовать RDB, хранящуюся на жестком диске, и последующую невыполненную работу на жестком диске. для завершения полной ретрансляции Retransmission. Благодаря этому дизайну мы сокращаем количество полных повторных передач. Кроме того, мы уменьшаем джиттер, вызванный большим количеством RDB, контролируя генерацию RDB в области низких пиков. В то же время мы также избегаем дрожания, вызванного записью AOF. Однако, поскольку написание AOF происходит полностью асинхронно, это решение будет менее надежным, чем официальные данные, но мы думаем, что эти затраты размениваются на улучшение юзабилити, что очень полезно.

Ключ точки доступа белки

Давайте взглянем на решение Squirrel Hot Key. Как показано на рисунке ниже, общий ведущий и подчиненный узлы являются узлами в обычном кластере, а ведущий и подчиненный точки доступа являются узлами вне обычного кластера. Давайте посмотрим, как они связаны.

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

Архитектура и практика погреба Persistence KV

Давайте взглянем на архитектуру и практику персистентного KV Cellar. На изображении ниже показана наша последняя схема архитектуры Cellar.

По сравнению с Tair с открытым исходным кодом от Alibaba, есть два основных отличия в архитектуре. Первый — OB, а второй — ZooKeeper. Наш OB похож на Observer ZooKeeper, предоставляя службы запросов для метаданных центрального узла Cellar. Он может синхронизировать последнюю таблицу маршрутизации с мастером центрального узла в режиме реального времени, а таблица маршрутизации клиента получается из OB. Это дает два основных преимущества: во-первых, это естественным образом изолирует большое количество бизнес-клиентов от мастера, главного мозга кластера, чтобы предотвратить влияние запросов таблицы маршрутизации на управление кластером. Во-вторых, поскольку OB используется только для запроса таблицы маршрутизации и не участвует в управлении кластером, его можно расширять горизонтально, что значительно улучшает возможности запроса нашей таблицы маршрутизации. Кроме того, мы внедрили ZooKeeper для распределенного арбитража, чтобы решить упомянутую только что проблему «разделения мозга» Master и Slave в случае сегментации сети, а за счет хранения метаданных кластера в ZooKeeper мы обеспечили высокий уровень метаданные надежные.

Аварийное восстановление погребного узла

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

Как показано на рисунке выше, если узел A выходит из строя, срабатывает механизм Handoff.В это время центральный узел уведомляет клиента о том, что узел A вышел из строя, и позволяет клиенту отправить запрос сегмента 1 в B как хорошо. После того, как узел B нормально обработает клиентский запрос на чтение и запись, он также запишет данные осколков 1 и 2, которые должны были быть записаны на узел A, в локальный журнал.

Если узел A не работает в течение 3–5 минут или джиттер сети восстанавливается через 30–50 секунд, узел A сообщит о пульсе центральному узлу, а центральный узел уведомит узел B: «Узел A восстанавливается, вы переходите к нему. Ему передаются данные, которых нет в периоде.» В это время узел B запишет обратно локально сохраненный журнал на узел A. После того, как узел A получит полный объем данных во время сбоя, центральный узел сообщит клиенту, что узел A был полностью восстановлен, и клиент может отправить запрос на сегмент 1 обратно узлу A.

С помощью этой операции мы можем добиться быстрого удаления узла за считанные секунды, а после восстановления узла нам нужно будет заполнить лишь небольшой объем инкрементных данных. Кроме того, если узел A нуждается в обновлении, центральный узел сначала переключает трафик узла A на узел B через активную передачу обслуживания, а затем записывает инкрементный журнал обратно после обновления узла A, а затем переключает трафик обратно для присоединения к кластеру. . Таким образом, активно запуская механизм Handoff, мы реализуем функцию тихого обновления.

Подвал Межрегиональное аварийное восстановление

Далее я расскажу, как Cellar выполняет межрегиональное аварийное восстановление. Проблема межрегионального аварийного восстановления, с которой сталкиваются Cellar и Squirrel, одинакова, и решение также заключается в межкластерной репликации. На следующем рисунке показан пример межрегионального сценария главного кластера в Пекине и подчиненного кластера в Шанхае. Например, если клиент записывает операцию записи на узел А главного кластера в Пекине, узел А скопирует ее. к узлам B и D, как обычная внутрикластерная репликация. В то же время узел A также скопирует данные на узел H подчиненного кластера. После того, как узел H обработает запись межкластерной репликации, он также выполнит репликацию в подчиненном кластере и скопирует операцию записи на узлы I и K подчиненного кластера. Устанавливая такой канал репликации между узлами master-slave кластера, мы завершаем репликацию данных между кластерами, и эта репликация обеспечивает наименьшее использование пропускной способности между регионами. Точно так же два узла между кластерами могут достичь эффекта двусторонней синхронизации и удаленной многоактивности путем настройки двух двусторонних каналов репликации.

Погреб Сильная Консистенция

После того, как мы завершили аварийное восстановление узла и кросс-региональное аварийное восстановление, бизнес выдвинул для нас более высокие требования: надежное согласованное хранилище. Наша предыдущая репликация данных была асинхронной, поэтому при удалении сбоя данные могут быть потеряны, потому что данные неисправного узла не были реплицированы. Но для таких сценариев, как финансовые платежи, они не терпят потери данных. Столкнувшись с этой проблемой, как мы должны ее решить? Текущее основное решение в отрасли — это строго согласованная репликация на основе протоколов Paxos или Raft. В итоге мы выбрали протокол Raft. Главным образом потому, что бумага Raft очень детализирована и является высокотехнологичной бумагой. В отрасли также существует множество зрелых реализаций Raft с открытым исходным кодом, которые можно использовать в качестве основы для наших исследований и разработок, тем самым сокращая цикл исследований и разработок.

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

Вы можете видеть, что слот 1 находится на узлах хранения 1, 2 и 4, а слот 2 — на узлах хранения 2, 3 и 4. Каждый слот образует группу Raft, и клиент будет читать и писать на Raft Leader. Поскольку мы предварительно выделили 16384 слота, при небольшом размере кластера на наших узлах хранения могут быть сотни или даже тысячи слотов. В настоящее время, если каждая группа репликации Raft имеет собственный поток репликации, запрос репликации, журнал и т. д., потребление ресурсов будет очень большим, а производительность записи будет низкой. Таким образом, мы реализовали Multi Raft. Cellar будет вести журнал для всех групп репликации Raft на одном узле и использовать одну и ту же группу потоков для выполнения репликации. Пакеты репликации между различными группами Raft также будут интегрированы в соответствии с целевым узлом для убедитесь, что производительность записи не ухудшается из-за слишком большого количества групп Raft. На самом деле у Raft есть собственный механизм выбора главного узла.Он может управлять своим собственным главным узлом.Если какой-либо узел выходит из строя, он может выбрать новый главный узел через механизм выборов. Итак, разве центральный узел не должен управлять группой Raft? нет. Вот типичный сценарий: если какие-то узлы кластера проходят несколько раундов восстановления после простоя, Raft Leader станет крайне неравномерным среди узлов хранения. Чтобы обеспечить строгую согласованность данных, клиентский трафик чтения и записи должен быть отправлен на лидера плота.В это время трафик узла кластера будет очень несбалансированным. Таким образом, наш центральный узел также будет выполнять планирование лидера группы Raft. Например, слот 1 хранится в узлах 1, 2 и 4, а узел 1 является ведущим. Если узел 1 умирает, Raft выбирает узел 2 в качестве лидера. Затем узел 1 восстанавливается и снова присоединяется к кластеру, а центральный узел просит узел 2 вернуть лидера узлу 1. Таким образом, даже после серии сбоев и восстановлений количество Лидеров среди наших узлов хранения все еще может быть гарантированно сбалансировано.

Далее мы рассмотрим, как Cellar гарантирует высокий уровень сквозного успеха. Вот также три вопроса, которые влияют на показатель успеха. Миграция данных и проблемы с горячими клавишами, с которыми сталкивается Cellar, такие же, как и у Squirrel, но решения разные. Это связано с тем, что Cellar идет по пути собственной разработки, не учитывая совместимость с официальной версией и внося дополнительные изменения в архитектуру. Другая проблема заключается в том, что медленные запросы блокируют очередь обслуживания и вызывают масштабные тайм-ауты, что является другой проблемой, с которой можно столкнуться при проектировании сети Cellar и многопоточной модели работы.

Интеллектуальная миграция подвала

На приведенном выше рисунке показана диаграмма архитектуры интеллектуальной миграции Cellar. Мы разделяем миграцию корзины на три состояния. Первое состояние является нормальным состоянием без каких-либо переходов. Если слот 2 должен быть перенесен с узла A на узел B в это время, A сделает моментальный снимок слота 2, а затем отправит полный снимок на узел B. При переносе данных пакет возврата узла B вернет состояние узла B. Что включает в себя статус B? Давление двигателя, трафик сетевой карты, длина очереди и т. д. Узел A будет регулировать скорость миграции в соответствии со статусом узла B. Как и в случае с Squirrel, после периода корректировки скорость миграции достигнет динамического баланса, обеспечивая максимально быструю миграцию и в то же время как можно меньше влияя на обычные запросы бизнеса.

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

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

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

Когда мы проанализировали случаи тайм-аута, которые произошли в сети, мы обнаружили, что только один или два запроса в пакете запросов тайм-аута часто были вызваны медленной обработкой движка.Большинство запросов истекло только из-за того, что общее время ответа было слишком большим. из-за слишком долгого ожидания в очереди. Согласно онлайн-анализу, на реальные медленные запросы приходится только 1/20 запросов с тайм-аутом.

Каково наше решение? Очень просто, снести пул потоков и снести очередь. После того, как наш сетевой поток получит пакет, он будет разделен на четыре очереди в соответствии с характеристиками его запроса, будь то чтение или запись, быстрый или медленный. Запросы на чтение и запись легко отличить, но как разделить быстрые и медленные? Мы будем различать быстрые и медленные запросы в зависимости от количества запрашиваемых ключей, размера значения и количества элементов структуры данных. Затем соответствующие четыре пула рабочих потоков используются для обработки запросов соответствующих очередей, что реализует изоляцию быстрых и медленных запросов на чтение и запись. Таким образом, если у меня будет медленный запрос на чтение, это не повлияет на нормальную обработку остальных трех запросов. Однако это также приведет к проблеме.Наш пул потоков изменился с одного на четыре.Число потоков увеличилось в четыре раза? На самом деле это не так, когда один из наших пулов потоков простаивает, мы помогаем другим пулам потоков обрабатывать запросы. Поэтому наш пул потоков стал четыре, но общее количество потоков не изменилось. Такой дизайн в нашей онлайн-проверке может уменьшить задержку обслуживания TP999 на 86%, что может значительно сократить время ожидания.

Ключ от погреба

На рисунке выше представлена ​​схема архитектуры решения Cellar Hotspot Key. Мы видим, что центральный узел добавил ответственности и имеет больше управления областью горячих точек.Теперь он не только отвечает за нормальное распределение копий данных, но также управляет распределением данных горячих точек.Этот кластер разместил области горячих точек на узлах C и Д. Давайте посмотрим, как эта схема работает в процессе чтения и записи. Если у клиента есть операция записи на узел A, узел A будет судить, является ли записанный ключ точкой доступа, в соответствии со статистикой точки доступа в реальном времени после завершения обработки. Если ключ является точкой доступа, то он будет реплицировать данные в кластере при репликации данных на узлы в области точки доступа, то есть на узлы C и D на рисунке. В то же время, когда узел хранения возвращает результат клиенту, он сообщает клиенту, что ключ является точкой доступа, и клиент кэширует ключ точки доступа. Когда у клиента есть запрос на чтение этого ключа, он напрямую переходит в зону доступа для чтения данных. Таким образом, мы можем только расширить данные точки доступа.В отличие от Squirrel, нам нужно переместить весь слот для расширения. При необходимости центральный узел также может размещать область хотспота на всех узлах кластера, а все запросы на чтение хотспота могут распределяться по всем узлам сбалансированным образом. Кроме того, с помощью этой репликации данных точки доступа в реальном времени мы можем решить проблему согласованности, вызванную схемой KV точки доступа кэша на стороне клиента.

Планы развития и тенденции отрасли

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

  • Во-первых, оптимизация протокола Redis Gossip. Всем известно, что когда масштабы протокола Gossip станут больше, объем сообщений резко увеличится, а его время Failover также будет становиться все больше и больше. Поэтому, когда масштаб кластера достигнет уровня TB, это сильно повлияет на доступность кластера, поэтому позже мы сосредоточимся на некоторых оптимизациях в этой области.
  • Во-вторых, мы сделали репликацию Raft между копиями данных узлов хранения Cellar, чтобы обеспечить надежную согласованность данных.Позже мы также сделаем репликацию Raft в центральной точке Cellar, чтобы нам не нужно было полагаться на ZooKeeper для распределенного арбитража. , метаданные сохраняются, и наша архитектура становится проще и надежнее.
  • В-третьих, хотя и Squirrel, и Cellar являются хранилищами KV, поскольку они разработаны на основе разных проектов с открытым исходным кодом, API и протоколы доступа отличаются.В будущем мы рассмотрим возможность интеграции Squirrel и Cellar на уровне SDK, хотя бэкэнд будет иметь Различные кластеры хранения, но бизнес-сторона может использовать набор SDK для доступа.

На системном уровне мы изучаем и внедряем некоторые технологии обхода ядра, такие как DPDK, SPDK и технологии ввода-вывода пользовательского режима для сетей и жестких дисков. Он может обойти ядро ​​и получить доступ к этим устройствам через механизм опроса, что может значительно улучшить возможности ввода-вывода в системе. Поскольку хранилище является службой с интенсивным вводом-выводом, производительность будет значительно улучшена.

На аппаратном уровне интеллектуальные сетевые адаптеры, поддерживающие RDMA, могут значительно сократить задержку сети и повысить пропускную способность; существуют также технологии флэш-памяти, такие как 3D XPoint, такие как недавно выпущенное хранилище Intel AEP, задержка доступа которого уже близка к задержке памяти. будущее, флэш-память и память Границы между ними также будут становиться все более и более размытыми; наконец, взгляните на вычислительное оборудование, например, на добавление карты FPGA во флэш-память и на то, чтобы выполнять работу, которую должен выполнять ЦП, например, данные сжатие, распаковка и т. д. для выполнения карты, такое оборудование может уменьшить задержку ответа службы при освобождении ЦП.

об авторе

Зебин, старший технический эксперт Meituan Dianping, присоединился к Meituan в 2014 году.

Предложения о работе

Центр технологий хранения данных Департамента базовых технологий Meituan уже давно набирает старших/старших инженеров и технических экспертов по C/C++, Go, Java.Добро пожаловать в семью Департамента базовых технологий Meituan. Заинтересованные студенты могут присылать свои резюме по адресу: tech@meituan.com (указать в теме письма: Отдел базовых технологий - Центр технологий хранения данных)

Чтобы прочитать больше технических статей, отсканируйте код, чтобы подписаться на общедоступную учетную запись WeChat — техническая команда Meituan!