Ця стаття спершу веде до того, які проблеми зазвичай має вирішувати проміжне програмне забезпечення повідомлень, які труднощі виникнуть при їх розв'язанні, чи можна вирішити Apache RocketMQ як високопродуктивний, високопродуктивний розподілений проміжний програмний забезпечення з відкритим кодом від Alibaba, а також як ці проблеми визначені у специфікації. У цій статті буде представлено архітектурний дизайн RocketMQ, щоб дати читачам швидке розуміння RocketMQ. 1. Які проблеми має вирішувати проміжне програмне забезпечення для повідомлень? Publish/Subscribe — це найпростіша функція проміжного програмного забезпечення повідомлень, а також відносно традиційної комунікації RPC. Я не буду вдаватися в подробиці. Пріоритет, описаний у специфікації пріоритету повідомлень, стосується черги повідомлень, кожне повідомлення має різний пріоритет, зазвичай описується цілими числами, повідомлення з високим пріоритетом доставляється першим, якщо повідомлення повністю знаходиться в черзі пам'яті, його можна відсортувати за пріоритетом перед доставкою, щоб високопріоритет був доставлений першим. Оскільки всі повідомлення в RocketMQ є постійними, якщо їх відсортувати за пріоритетом, накладні витрати будуть дуже великими, тому RocketMQ не підтримує пріоритет повідомлень, але може реалізувати подібні функції у обхідному напрямку, тобто налаштувати чергу з високим пріоритетом і чергу з нормальним пріоритетом, а також надсилати різні пріоритети в різні черги. Щодо пріоритетних питань, їх можна узагальнити у дві категорії:
- Поки пріоритет досягнуто, він не є пріоритетом у суворому сенсі, і зазвичай пріоритет поділяється на високий, середній, низький або ще кілька рівнів. Кожен пріоритет може бути представлений окремою темою, і при надсилання повідомлення вказуйте різні теми для представлення пріоритету, що може вирішити більшість проблем пріоритетів, але знизити точність бізнес-пріоритетів.
- Суворий пріоритет, пріоритет виражається як ціле число, наприклад 0 ~ 65535, такий тип задачі пріоритетів зазвичай не підходить для розв'язання з різними темами. Якщо ви хочете, щоб MQ вирішила цю проблему, це матиме дуже великий вплив на продуктивність MQ. Ось момент, щоб переконатися, що бізнесу дійсно потрібна ця сувора пріоритетність, і якщо пріоритети стиснуться до мінімуму, який вплив це матиме на бізнес?
Порядок повідомлень — це тип повідомлення, яке можна споживати у порядку відправлення. Наприклад, замовлення генерує 3 повідомлення: створення замовлення, оплата замовлення та завершення замовлення. Під час споживання має сенс споживати в такому порядку. Але водночас замовлення можна споживати паралельно. RocketMQ може суворо гарантувати, що повідомлення є впорядкованими. Фільтр повідомлень Брокер Фільтрація повідомлень У Broker фільтрація відповідно до вимог споживача має перевагу у зменшенні передачі непотрібних повідомлень споживачу. Недоліком є те, що це збільшує навантаження на брокера і є відносно складним у реалізації. 1. Taobao Notify підтримує різноманітні методи фільтрації, включно з прямою фільтрацією за типом повідомлення та гнучкою фільтрацією синтаксичних виразів, що може задовольнити майже найвимогливіші потреби фільтрації. 2. Taobao RocketMQ підтримує фільтрацію за простим тегом повідомлення, а також заголовком повідомлення та тілом. 3. Гнучка фільтрація синтаксичних виразів також підтримується у специфікації CORBA Notification Notification (Повідомлення). Фільтрація повідомлень з боку споживача Цю фільтрацію можна повністю налаштувати застосунком, але недоліком є те, що споживачу надсилається багато непотрібних повідомлень. Існує кілька поширених методів збереження повідомлень:
- Зберігайте у базі даних, наприклад Mysql.
- Зберігайте на KV-накопичуванні, такі як levelDB, Berkeley DB та інші системи зберігання KV.
- Збереження у вигляді файлових записів, таких як Kafka, RocketMQ
- Створіть збережений образ даних пам'яті, наприклад, beansstemd, VisiNotify
- (1), (2) і (3) усі три методи збереження мають можливість розширювати буфер черги пам'яті, і (4) є лише образом пам'яті, який може відновити дані з попередньої пам'яті навіть після того, як брокер завершить слухавку та перезапуск.
Специфікації JMS і CORBA Notification не вказують прямо, як зберігатися, але продуктивність частини збереження безпосередньо визначає продуктивність усього повідомленого проміжного програмного забезпечення. RocketMQ повністю використовує кеш пам'яті файлової системи Linux для підвищення продуктивності. Існує кілька ситуацій, коли надійність повідомлення впливає на надійність повідомлення:
- Брокер закривається нормально
- Крах брокера
- Збій ОС
- Машина втрачає живлення, але джерело живлення можна негайно відновити.
- Машина не вмикається (може бути пошкоджена ключові пристрої, такі як процесор, материнська плата, пам'ять тощо).
- Пошкодження дискового пристрою.
(1), (2), (3) і (4) — це ситуації, коли апаратні ресурси можна швидко відновити, і RocketMQ може гарантувати, що повідомлення не будуть втрачені або невелика кількість даних (залежно від того, чи є метод прошивки синхронним чи асинхронним). (5) (6) Це єдина точка відмови, яка не може бути відновлена; після її виникнення всі повідомлення на цій одній точці втрачаються. В обох випадках RocketMQ гарантує, що 99% повідомлень не губляться через асинхронну реплікацію, але все одно залишається дуже мало повідомлень, які можуть бути втрачені. Технологія синхронного подвійного запису може повністю уникнути окремих точок, що неминуче вплине на продуктивність, роблячи її придатною для ситуацій із надзвичайно високими вимогами до надійності повідомлень, таких як застосунки, пов'язані з Money. RocketMQ підтримує синхронний подвійний запис, починаючи з версії 3.0. Повідомлення з низькою затримкою можуть дійти до споживача одразу після того, як повідомлення доходить до брокера, без накопичення повідомлень. RocketMQ використовує метод довгого опитування, щоб переконатися, що повідомлення є дуже в реальному часі, а повідомлення в реальному часі не нижче за push. Принаймні один раз означає, що кожне повідомлення має бути доставлене один раз. RocketMQ Consumer спочатку витягує повідомлення в локальну зону, а потім повертає ack на сервер після завершення споживання. Рівно лише один раз- Етап надсилання повідомлення не дозволяє надсилати дублікати повідомлень.
- На етапі «Споживати повідомлення» дублікати повідомлень не дозволяються споживати.
Лише коли виконані дві вищезазначені умови, повідомлення можна вважати «Рівно один раз», і для досягнення цих двох пунктів неминуче виникнуть величезні накладні витрати в розподіленому системному середовищі. Тому для досягнення високої продуктивності RocketMQ не гарантує цю функцію і вимагає дедуплікації в бізнесі, що означає, що споживчі повідомлення мають бути ідемпотентними. Хоча RocketMQ не може строго гарантувати відсутність дублювання, за звичайних обставин рідко трапляються повторювані передачі та споживання, лише аномалії мережі, запуск і зупинка споживачів, а також інші аномальні ситуації, такі як дублювання повідомлень. Основна причина цієї проблеми полягає в невизначеності мережевих дзвінків, тобто третього стану — ні успіху, ні невдачі, тому виникає проблема повторення повідомлень. Що робити, якщо брокерський буфер заповнений? Буфер брокера зазвичай означає розмір буфера пам'яті в черзі в брокері, який зазвичай обмежений за розміром, а що робити, якщо буфер заповнений? Ось як це обробляється у специфікації сповіщень CORBA:
- RejectNewEvents відхиляє нове повідомлення і повертає код помилки RejectNewEvents Виробнику.
- Відкидайте існуючі повідомлення відповідно до певної політики
- AnyOrder — будь-яка подія може бути скинута при переповненні. Це налаштування за замовчуванням для цієї властивості.
- FifoOrder — Перша отримана подія буде першою відкинутою.
- LifoOrder — остання подія, отримана, буде першою відкинутою.
- PriorityOrder — Події слід відкидати у порядку пріоритету, щоб події нижчого пріоритету були відкинуті раніше за події вищого пріоритету.
- ДедлайнПорядок — Події слід спочатку відкидати у порядку найкоротшого дедлайну.
RocketMQ не має поняття буфера пам'яті, а черги RocketMQ є постійними дисками, і дані регулярно очищаються. Для розв'язання цієї проблеми RocketMQ має дуже суттєву відмінність від інших MQ: Буфер пам'яті RocketMQ абстрагований у чергу нескінченної довжини, незалежно від кількості даних, його можна встановити, ця нескінченність базується, брокер регулярно видаляє прострочені дані, наприклад, брокер зберігає лише 3 дні повідомлень, і хоча довжина цього буфера нескінченна, дані з 3 днів тому будуть видалені з кінця черги. Ретроспективне споживання означає повідомлення, яке споживач успішно спожив, і це повідомлення потрібно повторно споживати через попит бізнесу. Наприклад, через збій споживчої системи дані з годинної давності потрібно повторно використати після відновлення, тоді брокер має надати механізм для повернення прогресу споживання відповідно до часового виміру. RocketMQ підтримує ретроспективне споживання на основі часу, з часовим виміром, точним до мілісекунд, який можна відстежувати вперед або назад. Основна функція проміжного програмного забезпечення для стекування повідомлень — асинхронне розщеплення, а ще одна важлива функція — блокування пікового потоку даних на фронтенді та забезпечення стабільності бекенд-системи, що вимагає від проміжного програмного забезпечення певної здатності стекування повідомлень, а купча повідомлень інтегрує такі дві ситуації:
- Повідомлення накопичуються в буферах пам'яті, і коли вони перевищують буфер пам'яті, повідомлення можуть бути скинуті відповідно до певної політики скидання, як описано в специфікації CORBA Notification Notification специфікації. Він підходить для сервісів, які можуть терпіти відкидання повідомлень; у цьому випадку накопичувальні повідомленні головним чином залежать від розміру буфера пам'яті, і погіршення продуктивності не буде надто великим після накопичення повідомлення, оскільки обсяг даних у пам'яті має обмежений вплив на доступ до зовнішнього світу.
- Повідомлення накопичуються у постійних системах зберігання, таких як база даних, KV сховище, форма запису файлу. Коли повідомлення не можуть потрапити в кеш пам'яті, неминуче потрібно отримати доступ до диска, який генерує велику кількість зчитуваного виводу, а пропускна здатність читання безпосередньо визначає здатність доступу до повідомлень після їх накопичення.
Існує чотири основні моменти для оцінки здатності накопичувати повідомлення:
- Скільки повідомлень можна накопичити, скільки байтів? Тобто величезна ємність повідомлення.
- Після накопичення повідомлення чи впливає його пропускна здатність через накопичення?
- Чи постраждає нормальне споживання споживачів після того, як повідомлення накопичиться?
- Після накопичення повідомлень, яка пропускна здатність при доступі до повідомлень, накопичених на диску?
Розподілені транзакції Кілька відомих специфікацій розподілених транзакцій, таких як XA, JTA тощо. Серед них специфікація XA широко підтримується провідними постачальниками баз даних, такими як Oracle, MySQL тощо. Серед них лідер впровадження TM від XA, такий як Oracle Tuxedo, широко використовується у фінансах, телекомунікаціях та інших сферах. Розподілені транзакції включають двоетапні задачі фіксації, і з точки зору зберігання даних має підтримуватися KV-сховище, оскільки другий етап відкату коміту має змінювати стан повідомлення, що передбачає пошук повідомлення за ключем. RocketMQ обходить проблему пошуку повідомлення за ключем другого ступеня, використовуючи перший ступінь для надсилання підготовленого повідомлення, отримання зсуву повідомлення, а другий ступінь — для доступу до повідомлення через зсув і зміну стану; зсув — це адреса даних. Метод реалізації транзакцій у RocketMQ здійснюється не через KV-сховище, а через метод зміщення, який має суттєвий недолік: зміна даних через зміщення призводить до надмірної кількості забруднених сторінок у системі, що вимагає особливої уваги. Заплановані повідомлення Заплановані повідомлення означають, що споживачі не можуть споживати повідомлення одразу після відправки брокеру і можуть бути використані лише у певний момент часу або після очікування певного часу. Якщо ви хочете підтримувати довільну точність часу, на рівні брокера потрібно сортувати повідомлення, а якщо потрібна наполегливість, то сортування повідомлень неминуче спричинить величезні витрати на продуктивність. RocketMQ підтримує таймінг-повідомлення, але не підтримує довільну точність часу і підтримує конкретні рівні, такі як таймінг 5с, 10с, 1м тощо. Повторна спроба повідомлення Після того, як споживач не зможе сприйняти повідомлення, задайте механізм повторного спробування, щоб воно знову скористалося. Збої споживчих повідомлень зазвичай розглядаються у наступних ситуаціях:
- Через причину самого повідомлення, наприклад, через невдачу десеріалізації, самі дані повідомлення не можуть бути оброблені (наприклад, поповнення телефонного рахунку, номер мобільного телефону поточного повідомлення вийшов із системи, не можна поповнити) тощо. Ця помилка зазвичай вимагає пропуску цього повідомлення та споживання інших, і це невдале повідомлення на 99% є невдалим навіть при повторному використанні одразу, тому найкраще запропонувати механізм повторної спроби з обмеженим часом, тобто повторити через 10 секунд.
- Оскільки залежні нижні додаткові сервіси недоступні, наприклад, підключення до бази даних недоступне, зовнішня мережа системи недоступна тощо. У разі виникнення цієї помилки, навіть якщо поточне невдале повідомлення пропущено, інші повідомлення також будуть споживатися. У такому випадку рекомендується застосувати режим сну 30 секунд і споживати наступне повідомлення, що може зменшити тиск на брокера щодо повторної спроби повідомлення.
Огляд RocketMQ. Давайте дізнаємося, чи вирішує RocketMQ проблеми, з якими стикається згаданий вище проміжний програмний забезпечення для повідомлень.
Що таке RocketMQ?
Наведена вище ілюстрація є типовою моделлю проміжного програмного забезпечення для надсилання та отримання повідомлень, RocketMQ також розроблений таким чином, коротко кажучи, RocketMQ має такі характеристики:
- Це посереднє програмне забезпечення з моделлю повідомлень у черзі з високою продуктивністю, високою надійністю, високими характеристиками реального часу та розподіленими характеристиками.
- Виробник, споживач і черга можуть розподілятися.
- Producer по черзі надсилає повідомлення деяким чергам, колекція черги називається Topic, Consumer If broadcast consumption, один споживчий екземпляр споживає всі черги, що відповідають цій темі, а якщо кластерне споживання, кілька споживчих екземплярів рівномірно споживають колекцію черги, що відповідають цій темі.
- Гарантований суворий порядок повідомлень
- Забезпечує режими багатого витягу повідомлень
- Ефективне горизонтальне масштабування абонентів
- Механізм підписки на повідомлення в реальному часі
- Сотні мільйонів повідомлень для накопичення
- Менша залежність
Фізична структура розгортання RocketMQ
Як показано на рисунку вище, структура розгортання RocketMQ має такі характеристики:
- Сервер імен — це практично безстанний вузол, який можна розгортати в кластерах без жодної синхронізації інформації між вузлами.
- Розгортання Брокера досить складне: Брокер поділяється на Майстер і Слейв, Майстер може відповідати кільком Слейв, але Слейв може відповідати лише одному Мастеру, відповідність між Майстром і Слейвом визначається вказуванням однакового Імені Брокера, різного БрокерІдента, БрокерId дорівнює 0 для Майстра, а не 0 означає Слейв. Магістратуру також можна розгортати у кількох групах. Кожен брокер встановлює довге з'єднання з усіма вузлами кластеру сервера імен і регулярно реєструє інформацію про тему для всіх серверів імен.
- Виробник встановлює довге з'єднання з одним із вузлів кластера сервера імен (випадково обраним), періодично отримує інформацію про маршрутизацію теми від сервера імен, встановлює довге з'єднання з головним сервером, який надає сервіс теми, і регулярно надсилає серцебиття майстеру. Producer повністю безстанний і може розгортатися в кластерах.
- Споживач встановлює тривале з'єднання з одним із вузлів кластера сервера імен (випадково обраним), регулярно отримує інформацію про маршрутизацію теми від сервера імен, встановлює тривале з'єднання з Майстром і Слейвом, які надають тематичний сервіс, а також регулярно надсилає серцебиття Майстру та Слейву. Споживачі можуть підписатися на повідомлення як від Майстра, так і від Слейва, а правила підписки визначаються конфігурацією Брокера.
Логічна структура розгортання RocketMQ
Як показано на рисунку вище, логічна структура розгортання RocketMQ має дві характеристики: Виробник і Споживач.
Група Producer, що використовується для представлення додатку для обміну повідомленнями, містить кілька екземплярів Producer, які можуть бути кількома машинами, кількома процесами однієї машини або кількома об'єктами Producer процесу. Група продюсерів може надсилати кілька повідомлень про тему, а група продюсерів функціонує наступним чином:
- Визначте тип продюсера
- Ви можете запитати, що в цьому додатку для обміну повідомленнями є кілька екземплярів Producer через інструмент O&M
- Під час надсилання розподіленого повідомлення про транзакцію, якщо виробник несподівано виходить з ладу, брокер активно викликає будь-яку машину з групи виробників для підтвердження статусу транзакції.
Використовується для представлення споживчого додатку для обміну повідомленнями, споживча група містить кілька споживчих екземплярів, які можуть бути кількома машинами, кількома процесами або кількома споживчими об'єктами процесу. Кілька споживачів у групі споживачів споживають повідомлення рівномірно розподілено, і якщо встановити трансляцію, кожен екземпляр цієї групи споживає повний обсяг даних.
Структура зберігання даних RocketMQ
Як показано на рисунку вище, RocketMQ використовує метод зберігання, який розділяє дані від індексів. Ефективно зменшити втрати файлових ресурсів, IO ресурсів та пам'яті. Навіть із масивними даними, такими як Alibaba, сценарії з високим рівнем паралелізму можуть ефективно зменшити затримку від початку до кінця та забезпечують потужні горизонтальні можливості масштабування.
|