Милиони събития без срив на основната база

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

Свързани материали: Опашки и брокери: Redis, RabbitMQ, Kafka · API gateway и съобщения · Sail: опашки и RabbitMQ

Съдържание


Защо телеметрията не трябва да живее в „парите“

OLTP е оптимизиран за кратки, консистентни операции: списване, смяна на статус, уникални ключове. Индексите и поддръжката на таблиците са изградени около този модел.

Потокът от събития е с друг ритъм:

  • обемът е голям и на пикове, не равномерен;
  • често става дума за факти („в момент T се случи X“), а не за едно непрекъснато обновяване на същия ред;
  • отчетите изискват сканиране във времето, воронки, съединения — натоварване, което не прилича на типичните заявки към ядрото на продукта.

Когато всичко е в един инстанс, типично се вдигат опашките на закъснението при критични транзакции, индексите нарастват, репликацията изостава. Външно изглежда като „бавни графики“, а всъщност страда плащането и надеждността на състоянието.


Приемане на събития без бавен отговор на клиента

Целта е клиентът да получи бърз отговор, без да чака цялата верига до хранилището за BI. Междинният слой поглъща пика, после работници довършват записа.

Обичайни стъпки:

  1. Валидация и контекст на ръба — устройство, кампания, потребител; при нужда идемпотентен ключ срещу дублирани заявки от мрежата.
  2. Буфер с ясна семантика на загуба — Redis с устойчивост, брокер или друг append-ориентиран слой, не само RAM в PHP процеса.
  3. Пакетни вмъквания в целта — по-малко операции, по-малко натиск върху диска.
  4. Обратно налягане — ако консуматорът закъснее, ограничена опашка и сигнал нагоре (забавяне, отказ с retry, dead letter), вместо безкраен растеж в паметта.

В Laravel естествено се ползва опашка след лека обработка. При много висок RPS често се отделя услуга за прием. Запис в Redis list без репликация и ясна политика не е гаранция срещу изчезване при рестарт.


Redis: списъци срещу потоци

Списък (LPUSH / BRPOP) е минимален канал — просто опашка. Работи, ако Redis вече е в стека. Няколко работника без дублиране или пропускане обаче изисква собствена шардинг логика или приемате тесен гърлов участък.

Streams добавят групи консуматори, ID на съобщения и pending за заседнали съобщения. По-близо сте до кратък журнал: ред в рамките на ключа, няколко независими читателя, без задължително внедряване на Kafka още утре.

Ограниченията остават: RAM, eviction. Ако паметта свърши и политиката изхвърля ключове със събития, губите данни. За критични следи — лимити, аларми за дължина, или брокер с дисково персистиране.


RabbitMQ и Kafka — различен начин на мислене

RabbitMQ мисли в опашки, routing, TTL, dead-letter — познат свят за Horizon и задачи от типа „изпрати имейл“, „извикай доставчик“. Подходящ за средни до големи, но не винаги за най-екстремния throughput без внимателно разделяне на опашки.

Kafka мисли в топици, партиции, offset, retention. Много услуги могат да четат същата история; удобно за голям обем, повторно възпроизвеждане и одит. Цената е операции на клъстъра и смяна на парадигмата от „задачата приключи“ към „offset-ът напредна“.

Изборът зависи от обем, брой читатели, колко дълго държите лентата и екипа ви. Често срещан хибрид: Rabbit за командни задачи, Kafka или управляван поток за сурови събития.


Аналитиката в отделна лента

OLAP тук означава всяко хранилище и модел за тежки четения върху големи периоди — колонов двигател, облачен склад, или втора PostgreSQL с различни индекси, без отчетите да джойнват директно „горещите“ таблици на портфейла.

Типичен поток: OLTP остава източник на истина за пари → събитията отиват в поток/опашкаELT или работници пълнят витрини → таблата четат само аналитичния контур. Актуалност — чрез материализирани изгледи, график или поточна агрегация.

Една обща events таблица в продовата база е евтина на старта и скъпа за поддръжка по-късно. Компромисът е отделна база/схема с лимити и без тежки заявки от BI към ядрото.


Точки за решение преди да закотвите дизайна

  1. Допустима ли е загуба? Ако не — буферът трябва да е персистентен и репликиран, с мониторинг на закъснението.
  2. Колко строг е редът — по потребител, по сесия, или достатъчно е приблизително хронологично?
  3. Колко независими консуматора ще четат един и същ поток? Колкото повече, толкова по-често печели журнал със запазване.
  4. Къде са таблата? Ако са върху същия инстанс като плащанията — планирайте изолация: read replica, statement_timeout, отделен сървър.
  5. Има ли идемпотентност на входа? Без нея повторните заявки размиват метриките и салдата.

Следващите статии в архитектурата ще покрият устойчиви интеграции, състезания при списване и конкретни Laravel шаблони. Едно изречение за запомняне: да налееш поток от събития в същата кошница като парите без амортисьор е осъзнат компромис, не закон на природата.