В качестве промежуточного программного обеспечения, основанного на дисковом хранилище, RocketMQ имеет неограниченные возможности невыполненных работ и обеспечивает высокую пропускную способность и возможности обслуживания с низкой задержкой Его основной частью должен быть элегантный дизайн хранилища.
Напоминание: эта статья взята из второй версии недавно включенного в список "RocketMQ Technology Insider". Одно из самых больших изменений заключается в том, что перед анализом исходного кода основной рабочий механизм RocketMQ сначала извлекается с помощью изображений и текстов, что снижает сложность чтения исходного кода.
1. Обзор хранилища
Файлы, хранящиеся в RocketMQ, в основном включают файлы Commitlog, файлы ConsumeQueue и файлы индексов.
RocketMQ хранит сообщения всех тем в одном файле, чтобы гарантировать, что файлы записываются в том же порядке, когда сообщения отправляются, и делает все возможное, чтобы обеспечить высокую доступность и высокую пропускную способность при отправке сообщений.
Однако промежуточное программное обеспечение сообщений, как правило, представляет собой модель подписки и публикации на основе темы. Сообщения должны выбираться в соответствии с темами при использовании сообщений. Очевидно, что фильтрация сообщений в соответствии с темами в файле Commitlog станет крайне неэффективной. Чтобы улучшить поиск сообщений по темам. Для повышения эффективности RocketMQ представил файл ConsumeQueue, который широко известен как файл очереди потребления.
Реляционные базы данных могут извлекать записи на основе атрибутов полей. Как промежуточное программное обеспечение сообщений, предназначенное главным образом для развития бизнеса, RocketMQ также предоставляет возможности извлечения на основе атрибутов сообщений.Основная основная концепция дизайна заключается в создании файла Commitlog.Хэш-индекс и сохранение в индексном файле.
После последовательной записи в файл Commitlog в RocketMQ файлы ConsumeQueue и Index строятся асинхронно.Схема потока данных выглядит следующим образом:
2. Организация файлов хранилища
RocketMQ обеспечивает максимальную последовательную запись на диск в процессе записи сообщений. Все сообщения для всех тем записываются в один файл, файл Commitlog. Все сообщения добавляются в файл в порядке поступления. После того, как сообщение записано, его нельзя изменить. Конкретный макет файла Commitlog показан на следующем рисунке:Существует большая разница между программированием на основе файлов и программированием на основе памяти.В модели программирования на основе памяти у нас есть готовые структуры данных, такие как List и HashMap.Читать и записывать данные очень удобно.Тогда один сообщение хранится в файле Commitlog., как его найти?
Точно так же, как реляционные данные введутПоле идентификатора, в файловой модели программирования также вводится токен идентификации для сообщения:физическое смещение сообщения, то есть сообщение сохраняется в начале файла.
Именно с концепцией физического смещения именование имени файла Commitlog также очень сложно, используя для имени смещение первого сообщения, хранящегося в файле во всей файловой группе Commitlog, например, первый файл журнала фиксации 000000000000000000000 , второй файл — 00000000001073741824 и так далее.
Преимущество этого в том, что дается физическое смещение любого сообщения, например, смещение сообщения 73741824, которое можно искать по дихотомии, быстро найти файл в первом файле, а затем использовать физическое смещение сообщения. Разница, полученная путем вычитания имени файла, представляет собой абсолютный адрес в файле.
Концепция файла Commitlog заключается в том, чтобы добиваться максимального написания сообщений, но мы знаем, что модель потребления сообщений представляет собой механизм подписки на основе темы, то есть группа потребителей потребляет сообщения определенной темы. Если мы будем извлекать сообщения из файла журнала коммитов в соответствии с темой, мы обнаружим, что это никогда не бывает хорошей идеей.Мы можем извлекать сообщения только одно за другим из первого сообщения файла, и его производительность можно представить.Поэтому в Чтобы решить проблему поиска сообщений на основе темы, RocketMQ Представлен файл потребления очереди, и структура потребления очереди показана на следующем рисунке.Файл ConsumeQueue — это файл очереди потребления сообщений и файл Commitlog.Индексный файл на основе темы, который в основном используется потребителями для обработки сообщений по темам. Метод организации — /topic/queue, и в одной очереди находится несколько файлов.
Конструкция Consumequeue очень сложна, и каждая запись имеет фиксированную длину (8 байтов физического смещения журнала фиксации, 4 байта длины сообщения, 8 байтов хэш-кода тега).
Вместо сохранения исходной строки тега мы решили сохранить хэш-код,Цель состоит в том, чтобы гарантировать, что длина каждой записи фиксирована, и запись может быть быстро обнаружена путем доступа к аналогичным индексам массива, что значительно повышает производительность чтения файлов ConsumeQueue.
Представьте, что потребитель сообщения получает доступ к сообщению в соответствии с темой и ходом потребления сообщения (логическое смещение consumeuqe), то есть количеством записей Consumeque. 20, чтобы найти запись. Начальное смещение (смещение в файле потребления очереди), а затем прочитать смещение 20 байт, чтобы получить запись, не просматривая файл потребления очереди.
По сравнению с Kafka у RocketMQ есть мощное преимущество, то есть он поддерживает получение сообщений по атрибутам сообщения.Введение файлов ConsumerQueue решает проблему поиска по теме, но если вы хотите искать сообщения по определенному атрибуту сообщение, файл потребления очереди бессилен.
RocketMQ представляет индексный файл Index для реализациихэш-индекс на основе файлов. Структура хранения файлов IndexFile показана на следующем рисунке:Файлы IndexFile реализуют хеш-индексацию на основе файлов физического диска. Файл состоит из 40-байтового заголовка файла, 5 миллионов хеш-слотов, по 4 байта на каждый хэш-ячейку и, наконец, 20 миллионов записей индекса, каждая из которых состоит из 20 байтов, каждая из 4 байтов. , 8-байтовое физическое смещение сообщения, 4-байтовая метка времени и 4-байтовая предыдущая запись индекса (структура связанного списка хэш-коллизий).
То есть устанавливается отношение отображения между хэш-кодом ключа индекса и физическим смещением., по ключу сначала быстро определите в файл журнала коммитов,Чтобы узнать о конкретном рабочем механизме хэш-индекса, вы можете обратиться к подробному введению в разделе 4.5.3 второго издания RocketMQ Technology Insider..
3. Пишите последовательно
Другой принцип разработки для повышения производительности чтения и записи на диске заключается в следующем.последовательная запись на диск.
Последовательная запись на диск широко используется в моделях хранения на основе файлов. Вы можете подумать о цели введения журналов повторов MySQL. Мы знаем, что в механизме хранения MySQL InnoDB будет пул памяти, используемый для кэширования файловых блоков на При обновлении После того, как оператор изменит данные, он сначала изменит их в памяти, затем запишет изменения в файл повторения (чистит на диск), а затем периодически сбрасывает данные из пула памяти InnoDB на диск.Почему бы не обновить его непосредственно в указанный файл данных, как только произойдет изменение данных? В базе данных MySQL InnoDB тысячи листов, и данные каждого листа будут храниться в отдельном файле, если данные каждой таблицы будут изменены, они будут сброшены на диск, и останется большое количество случайной записи, и производительность не может быть улучшена. , поэтому вводится файл повтора, и файл повтора записывается последовательно, что на первый взгляд добавляет еще одну операцию дисковой щетки, но поскольку это последовательная запись, по сравнению со случайной записью, улучшение производительности принес очень значительный.
4. Механизм отображения памяти
Хотя последовательная запись на диск может значительно повысить эффективность записи ввода-вывода, если в файловом хранилище используется обычный API операций с файлами JAVA, такой как FileOutputStream, улучшение производительности будет очень ограниченным RocketMQ вводит сопоставление памяти для сопоставления дисковых файлов. В памяти диск работает так же, как и память, и производительность улучшена на другой уровень.
В JAVA файлы с отображением памяти могут быть созданы с помощью метода карты FileChannel.
Файл, созданный этим методом в Linux-сервере, использует pagecache операционной системы, то есть кеш страниц.
Стратегия использования памяти в операционной системе Linux будет максимально использовать физическую память машины и находиться в памяти, которая является так называемым кэшем страниц. Когда памяти операционной системы недостаточно, используется алгоритм замены кеша, такой как LRU, для высвобождения редко используемого страничного кеша, то есть операционная система будет автоматически управлять этой частью памяти.
Если процесс RocketMQ Broker завершится аварийно, данные, хранящиеся в кэше страниц, не будут потеряны, и операционная система будет периодически сохранять данные из кэша страниц на диск для обеспечения безопасности и надежности данных. Однако при отключении питания машины и других ненормальных условиях данные, хранящиеся в кэше страниц, могут быть потеряны.
5. Гибкая и изменяемая стратегия кисти
имеютПоследовательная запись и отображение памятиС благословением RocketMQ производительность записи RocketMQ была в значительной степени гарантирована, но у всего есть свои плюсы и минусы.Введены механизмы отображения памяти и кэша страниц.Сообщение будет сначала записано в кеш страницы, а сообщение не будет действительно сохранились на диск в это время. Затем, после того как брокер получает сообщение, отправленное от клиента, сохраняет ли он его в кэше страниц и сразу возвращает успех, или ему нужно сохраниться на диске, прежде чем возвращать успех?
Это «сложный» выбор для торговли производительностью и надежностью сообщений. С этой целью RocketMQ предоставляет различные стратегии: синхронная кисть, асинхронная кисть.
5.1 Синхронная чистка
В реализации RocketMQ синхронная очистка становитсягрупповое представление, не каждое сообщение нужно сбрасывать. Его конструктивная концепция показана на рисунке:Используя синхронную очистку, каждый поток отслеживает данные в памяти, отправляет запрос на очистку потоку очистки, а затем блокируется; поток очистки получает задачу из очереди задач,Затем запустите Flush, но не только промойте сообщения, связанные с запросом, но непосредственно промойте все сообщения в памяти, которые будут промыты на партии.Тогда ты можешьРазбудить группу потоков запросов для обновления группы.
5.2 Асинхронная очистка
Преимущество синхронной очистки состоит в том, что она может гарантировать, что сообщение не будет потеряно, то есть успешный возврат клиенту означает, что сообщение было сохранено на диске, то есть сообщение очень надежно, но это в за счет производительности задержки ответа на запись, поскольку сообщения RocketMQ сначала записываются в кэш страниц, поэтому вероятность потери сообщения невелика.Если вы можете допустить определенную вероятность потери сообщения, вы можете рассмотреть возможность использования асинхронной очистки.
Асинхронная очистка означает, что брокер возвращает сообщение об успешном завершении сразу после сохранения сообщения в кэше страниц, а затем запускает асинхронный поток для периодического выполнения метода fore FileChannel и периодически сбрасывает данные из памяти на диск.Интервал по умолчанию – 500 мс.
6. Разделение чтения и записи на уровне памяти
RocketMQ представила механизм transientStorePoolEnable для снижения нагрузки на кэш страниц, то есть механизм разделения чтения и записи на уровне памяти.
По умолчанию RocketMQ записывает сообщения в кеш страниц и читает сообщения из кеша страниц при потреблении сообщений.Таким образом, при высоком уровне параллелизма нагрузка на кеш страниц будет относительно большой, что склонно к переходным процессам.broker busy, поэтому RocketMQ также представляет функцию transientStorePoolEnable, которая сначала записывает сообщение в память вне кучи и немедленно возвращает его, затем асинхронно отправляет данные из памяти вне кучи в кэш страниц, а затем асинхронно сбрасывает их на диск. Его рабочий механизм показан на следующем рисунке:Сообщения не пытаются читать из памяти вне кучи при потреблении чтений, а из кэша страниц, таким образом формируяРазделение чтения и записи на уровне памяти, то есть когда сообщение пишется, оно в основном обращено к памяти вне кучи, а при чтении сообщения — в основном к кэшу страниц.
Преимущество этой схемы в том, что сообщения записываются непосредственно в память вне кучи, а затем асинхронно записываются в кэш страниц. По сравнению с добавлением каждого сообщения и записью его непосредственно в pagechae его самым большим преимуществом является то, что операция записи сообщений в pagecache является пакетной.
Недостаток этой схемы в том, что если процесс Broker аварийно завершится из-за какой-то неожиданной операции, данные, хранящиеся в памяти вне кучи, будут потеряны, но если они будут помещены в кэш страниц, то брокер аварийно завершится и не потеряет сообщения. .
Статья впервые опубликована:Woohoo.coding W.net/posts/3364 ах…
Ну, эта статья представлена здесь,Подписывайтесь, лайкайте и комментируйте, это самая большая поддержка для меня.
Освойте одно или два основных промежуточного программного обеспечения Java, стучитесь в BAT и других производителей необходимые навыки, чтобы дать вам курс обучения промежуточного программного обеспечения Java, помочь нам добиться трансформации на рабочем месте.
Наконец, поделитесь хардкорной электронной книгой RocketMQ автора, и вы получите опыт эксплуатации и обслуживания потока сообщений со 100 миллиардами уровней.
способ получения:Электронная книга RocketMQ.