Тази статия първо разглежда какви проблеми обикновено трябва да решава междинният софтуер за съобщения, какви трудности ще срещнат при решаването на тези проблеми, дали Apache RocketMQ може да бъде решен като високопроизводителен и високопропускателен разпределен междинен софтуер с отворен код от Alibaba и как тези проблеми са дефинирани в спецификацията. Тази статия ще представи архитектурния дизайн на RocketMQ, за да даде на читателите бързо разбиране на RocketMQ. 1. Какви проблеми трябва да решава междинният софтуер за съобщения? Публикуването/Subscribe е най-основната функция на междинния софтуер за съобщения и също така е свързана с традиционната комуникация с RPC. Няма да навлизам в подробности тук. Приоритетът, описан в спецификацията за приоритет на съобщенията, се отнася до опашка на съобщения, всяко съобщение има различен приоритет, обикновено описан с цели числа, съобщението с висок приоритет се доставя първо, ако съобщението е изцяло в опашка памет, тогава може да бъде сортирано според приоритета преди доставката, така че високият приоритет да бъде доставен първи. Тъй като всички съобщения в RocketMQ са постоянни, ако са сортирани според приоритет, натоварването ще бъде много голямо, така че RocketMQ не поддържа конкретно приоритет на съобщенията, но може да реализира подобни функции в заобиколно решение, т.е. да конфигурира опашка с висок приоритет и опашка с нормален приоритет и да изпраща различни приоритети към различни опашки. За приоритетните въпроси те могат да се обобщят в 2 категории:
- Докато приоритетът е постигнат, той не е приоритет в строгия смисъл и обикновено се разделя на високо, средно, ниско или няколко допълнителни нива. Всеки приоритет може да бъде представен от различна тема, а при изпращане на съобщение да се посочат различни теми, които да представят приоритета, което може да реши повечето приоритетни проблеми, но да компрометира точността на бизнес приоритетите.
- Строг приоритет, приоритетът се изразява като цяло число, като 0 ~ 65535; този вид приоритетен проблем обикновено не е подходящ за решаване с различни теми. Ако искате MQ да реши този проблем, това ще има много голямо влияние върху представянето му. Ето една точка, за да сте сигурни, че бизнесът наистина се нуждае от това стриктно приоритизиране, и ако приоритетите се свият до малко, колко голямо въздействие ще има това върху бизнеса?
Редът на съобщенията се отнася до вид съобщение, което може да бъде консумирано в реда на изпращане. Например, поръчка генерира 3 съобщения, а именно създаване на поръчка, плащане на поръчка и завършване на поръчка. Когато консумирате, има смисъл да консумирате в този ред. Но в същото време поръчките могат да се консумират паралелно. RocketMQ може стриктно да гарантира, че съобщенията са подредени. Филтър за съобщения Филтриране на съобщения Брокер В Broker филтрирането според изискванията на потребителя има предимството да намали предаването на ненужни съобщения към потребителя. Недостатъкът е, че увеличава тежестта върху брокера и е сравнително сложен за изпълнение. 1. Taobao Notify поддържа различни методи за филтриране, включително директно филтриране по тип съобщение и гъвкаво филтриране на синтактични изрази, което може да отговори на почти най-взискателните нужди от филтриране. 2. Taobao RocketMQ поддържа филтриране чрез прост Message Tag, както и Message Header и тяло. 3. Гъвкаво филтриране на синтактични изрази също се поддържа в спецификацията CORBA 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 на сървъра след приключване на консумацията. Точно веднъж- Етапът на изпращане на съобщение не позволява изпращане на дублирани съобщения.
- В етапа Consume Message не се допуска консумация на дублирани съобщения.
Само когато горните две условия са изпълнени, съобщението може да се счита за "Точно веднъж", и за да се постигнат горните две точки, неизбежно ще се генерират огромни режийни разходи в разпределената системна среда. Затова, за да се постигне висока производителност, RocketMQ не гарантира тази функция и изисква дедупликация в бизнеса, което означава, че потребителските съобщения трябва да са идемпотентни. Въпреки че RocketMQ не може строго да гарантира недублиране, при нормални обстоятелства рядко има повтарящи се изпращания и консумации, само аномалии в мрежата, потребителски старт и спиране и други необичайни ситуации като дублиране на съобщения. Основната причина за този проблем е, че съществува несигурност в мрежовите обаждания, тоест третото състояние – нито успех, нито провал, затова възниква проблемът с повторението на съобщенията. Какво трябва да направя, ако Broker's Buffer е пълен? Буферът на брокера обикновено се отнася до размера на буфера в паметта на опашка в брокера, който обикновено е ограничен по размер; какво ако буферът е пълен? Ето как се обработва това в спецификацията CORBA Notification (Уведомление):
- RejectNewEvents отхвърля новото съобщение и връща кода за грешка RejectNewEvents на Producer.
- Изхвърлете съществуващи съобщения според конкретна политика
- AnyOrder - Всяко събитие може да бъде изхвърлено при препълване. Това е стандартната настройка за това свойство.
- FifoOrder - Първото получено събитие ще бъде първото отхвърлено.
- LifoOrder - Последното получено събитие ще бъде първото изхвърлено.
- PriorityOrder - Събитията трябва да се изхвърлят в приоритетен ред, така че събитията с по-нисък приоритет да бъдат изхвърлени преди събитията с по-висок приоритет.
- Крайна поръчка - Събитията трябва първо да се отхвърлят в реда на най-краткия срок на изтичане.
RocketMQ няма концепцията за буфер за памет, а опашките на RocketMQ са постоянни дискове, като данните се изчистват редовно. За решение на този проблем, RocketMQ има много съществена разлика от другите MQ-та – буферът на паметта на RocketMQ е абстрахиран в опашка с безкрайна дължина, независимо колко данни влизат, може да се инсталира, тази безкрайност е предпоставена, брокерът редовно изтрива изтекли данни, например брокерът запазва само 3 дни съобщения, след което дължината на този буфер е безкрайна, данните от преди 3 дни ще бъдат изтрити от края на опашката. Ретроспективното потребление се отнася до посланието, което потребителят е консумирал успешно и то трябва да бъде повторно консумирано поради търсенето на бизнеса. Например, поради повреда на потребителската система, данните от преди 1 час трябва да бъдат използвани отново след възстановяване, след което брокерът трябва да предостави механизъм за връщане на прогреса на потреблението според времевия размер. RocketMQ поддържа ретроспективна консумация, базирана на време, с времево измерение, точно до милисекунди, което може да се върне напред или назад. Основната функция на междинния софтуер за наслагване на съобщения е асинхронното разкъсване, а друга важна функция е да блокира пиковата честота на потока от данни на фронтенда и да осигури стабилността на бекенд системата, което изисква междинният софтуер за съобщения да има определена способност за стекване на съобщения, а купчината на съобщения интегрира следните две ситуации:
- Съобщенията се трупат в буферите на паметта и след като надхвърлят буфера на паметта, съобщенията могат да бъдат прекъснати според определена политика за изпускане, както е описано в спецификацията за известия на CORBA. Подходящо е за услуги, които могат да понасят изхвърляне на съобщения; в този случай капацитетът за натрупване на съобщенията се дължи основно на размера на буфера с памет, а влошаването на производителността няма да бъде твърде голямо след като съобщението бъде стекнато, тъй като количеството данни в паметта има ограничено влияние върху достъпа към външния свят.
- Съобщенията се натрупват в системи за постоянна памет като база данни, KV съхранение, файлови записи. Когато съобщенията не могат да бъдат достигнати в кеша на паметта, е неизбежно достъпът до диска, който генерира голямо количество четени входове, а пропускателната способност на четения вход директно определя възможността за достъп на съобщенията след като бъдат натрупани.
Има четири основни точки за оценка на способността за натрупване на съобщения:
- Колко съобщения могат да се натрупат, колко байта? Тоест, огромният капацитет на съобщението.
- След като съобщението е натрупано, влияе ли пропускателната способност на съобщението от натрупването?
- Ще бъде ли засегната нормалната консумация на потребителите след като съобщението се натрупа?
- След като съобщенията се натрупат, какъв е пропускателният капацитет при достъп до натрупани на диска съобщения?
Разпределени транзакции Няколко известни разпределени спецификации за транзакции, като XA, JTA и др. Сред тях XA спецификацията се поддържа широко от големи доставчици на бази данни като Oracle, MySQL и др. Сред тях е лидерът на XA за внедряване на TM, като Oracle Tuxedo, който се използва широко във финансите, телекомуникациите и други области. Разпределените транзакции включват двустепенни проблеми с потвърждаването, а що се отнася до съхранението на данни, трябва да се поддържа KV съхранение, тъй като вторият етап на връщане на комита трябва да промени състоянието на съобщението, което включва действие по намиране на съобщението според ключа. RocketMQ заобикаля проблема с намирането на съобщението според ключа във втория етап, използвайки първия етап за изпращане на подготвеното съобщение, получавайки отместването на съобщението, а втория етап за достъп до съобщението чрез офсета и модифициране на състоянието, като офсетът е адресът на данните. Методът за реализиране на транзакции в RocketMQ не се извършва чрез KV хранилище, а чрез офсет метода, който има значителен недостатък, а именно промяната на данни чрез офсет ще доведе до твърде много мръсни страници в системата, което изисква специално внимание. Планирани съобщения Планираните съобщения означават, че съобщенията не могат да бъдат консумирани от потребителите веднага след като бъдат изпратени към брокера и могат да се консумират само в определен момент или след изчакване на определено време. Ако искате да поддържате произволна точност на времето, на ниво брокер трябва да сортирате съобщения, а ако е необходимо упоритост, то сортирането на съобщения неизбежно ще доведе до огромни разходи за производителност. RocketMQ поддържа времеви съобщения, но не поддържа произволна точност на времето и поддържа специфични нива, като тайминг 5s, 10s, 1m и др. Опит за повторно съобщение След като потребителят не успее да го погълне, осигурете механизъм за повторен опит, който да го възприеме отново. Грешките в потребителските съобщения обикновено могат да се разглеждат в следните ситуации:
- Поради самото съобщение, като провал при десериализацията, самите данни не могат да бъдат обработени (например зареждане на телефонна сметка, мобилният номер на текущото съобщение е излязъл от акаунта и не може да бъде презареден) и др. Тази грешка обикновено изисква пропускане на това съобщение и консумиране на други съобщения, а това неуспешно съобщение е 99% неуспешно, дори ако консумацията се опита отново веднага, затова е най-добре да се предостави механизъм за повторен опит с ограничено време, тоест да се опита отново след 10 секунди.
- Тъй като зависимите приложни услуги са недостъпни, като например DB връзката е недостъпна, външната системна мрежа е недостъпна и т.н. При среща с тази грешка, дори ако текущото неуспешно съобщение бъде пропуснато, ще бъдат погълнати и други съобщения. В този случай се препоръчва да се приложи sleep 30s и да се погълне следващото съобщение, което може да намали натиска върху брокера да опита съобщението отново.
Обзор на RocketMQНека разберем дали RocketMQ решава проблемите, с които се сблъсква споменатият по-горе междинен софтуер за съобщения.
Какво е RocketMQ?
Горната фигура е типичен модел на междинен софтуер за съобщения, който изпраща и получава съобщения, RocketMQ също е проектиран по този начин, накратко, RocketMQ има следните характеристики:
- Това е междинен софтуер с модел на опашки с висока производителност, висока надеждност, високи характеристики в реално време и разпределени характеристики.
- Производител, Потребител и Опашка могат да бъдат разпределени.
- Producer изпраща съобщения към някои опашки на свой ред, колекцията от опашки се нарича Тема, Потребител Ако излъчва консумация, една потребителска инстанция поглъща всички опашки, съответстващи на тази тема, а ако е клъстерна консумация, множество потребителски инстанции поглъщат колекцията от опашки, съответстващи на тази тема, равномерно.
- Може да се гарантира строг ред на съобщенията
- Осигурява богати режими за изтегляне на съобщения
- Ефективни хоризонтални възможности за мащабиране на абонатите
- Механизъм за абонамент за съобщения в реално време
- Стотици милиони капацитет за натрупване на съобщения
- По-малка зависимост
Физическа структура на разгръщане на RocketMQ
Както е показано на горната фигура, структурата на разгръщане на RocketMQ има следните характеристики:
- Name Server е практически безсъстоянен възел, който може да бъде внедрен в клъстери без никаква синхронизация на информацията между възлите.
- Разгръщането на Брокер е сравнително сложно, Брокер е разделен на Майстор и Подчинен, Мастър може да съответства на няколко Роба, но Слейв може да съответства само на един Мастър, съответствието между Мастър и Слейв се дефинира чрез посочване на едно и също БрокерИме, различен БрокерId, БрокерId е 0 за Мастър, а не-0 означава Роб. Магистърските степени могат да бъдат разгръщани и в няколко степени. Всеки брокер установява дълга връзка с всички възли в клъстера на сървъра за имена и регистрира тематична информация към всички сервери за имена на редовни интервали.
- Производителят установява дълга връзка с един от възлите в клъстера на сървъра за имена (избран на случаен принцип), периодично извлича информация за маршрутизиране на темата от сървъра за име, установява дълга връзка с главния сървър, който предоставя услугата на темата, и изпраща сърдечни удари към главния сървър на редовни интервали. Producer е напълно без състояние и може да се внедрява в клъстери.
- Потребителят установява дълга връзка с един от възлите в клъстера на сървъра за имена (избран на случаен принцип), редовно извлича информация за маршрутизиране на темата от сървъра за имена и установява дълга връзка с главния и подчинения, които предоставят тематичната услуга, като изпраща сърдечни удари към главния и подчинения на редовни интервали. Потребителите могат да се абонират за съобщения както от Master, така и от Slave, а правилата за абонамент се определят от конфигурацията на Broker.
Логическа структура на разгръщане на RocketMQ
Както е показано на горната фигура, логическата структура на разгръщане на RocketMQ има две характеристики: Производител и Потребител.
Използвана за представяне на приложение за съобщения, Producer Group съдържа множество Producer инстанции, които могат да бъдат няколко машини, множество процеси на една машина или множество Producer обекти на един процес. Групата производители може да изпраща множество съобщения по тема, а групата на продуцентите функционира по следния начин:
- Идентифицирайте тип продуцент
- Можете да попитате, че има няколко Producer инстанции в това приложение за съобщения чрез инструмента O&M
- При изпращане на разпределено съобщение за транзакция, ако производителят се повреди неочаквано, брокерът активно ще се обади обратно на всяка машина от групата производители, за да потвърди статуса на транзакцията.
Използвана за представяне на потребителско приложение за съобщения, потребителската група съдържа множество потребителски инстанции, които могат да бъдат няколко машини, множество процеси или множество потребителски обекти на един процес. Множество потребители в потребителска група консумират съобщения равномерно разпределено, и ако са настроени да излъчват, всяка инстанция под тази потребителска група консумира цялото количество данни.
Структура за съхранение на данни в RocketMQ
Както е показано на горната фигура, RocketMQ използва метод за съхранение, който разделя данните от индексите. Ефективно намаляване на загубата на файлови ресурси, входни ресурси и памет. Дори с огромни данни като Alibaba, сценариите с висока паралелност могат ефективно да намалят латентността от край до край и да имат силни хоризонтални възможности за мащабиране.
|