Милиони събития без срив на основната база
В тихи часове архитектура изглежда евтина: пристигна събитие — записахме го. После идва рекламна вълна, играчите натискат едно и също, партньорите искат сурови логове, и същата база, която пази баланси и сесии, започва да поема още един поток от записи. Най-директният път често е и най-скъпият за върни назад. По-долу са схеми, които реално се срещат в продукшън, без маркетингови обещания.
Свързани материали: Опашки и брокери: Redis, RabbitMQ, Kafka · API gateway и съобщения · Sail: опашки и RabbitMQ
Съдържание
- Защо телеметрията не трябва да живее в „парите“
- Приемане на събития без бавен отговор на клиента
- Redis: списъци срещу потоци
- RabbitMQ и Kafka — различен начин на мислене
- Аналитиката в отделна лента
- Точки за решение преди да закотвите дизайна
Защо телеметрията не трябва да живее в „парите“
OLTP е оптимизиран за кратки, консистентни операции: списване, смяна на статус, уникални ключове. Индексите и поддръжката на таблиците са изградени около този модел.
Потокът от събития е с друг ритъм:
- обемът е голям и на пикове, не равномерен;
- често става дума за факти („в момент T се случи X“), а не за едно непрекъснато обновяване на същия ред;
- отчетите изискват сканиране във времето, воронки, съединения — натоварване, което не прилича на типичните заявки към ядрото на продукта.
Когато всичко е в един инстанс, типично се вдигат опашките на закъснението при критични транзакции, индексите нарастват, репликацията изостава. Външно изглежда като „бавни графики“, а всъщност страда плащането и надеждността на състоянието.
Приемане на събития без бавен отговор на клиента
Целта е клиентът да получи бърз отговор, без да чака цялата верига до хранилището за BI. Междинният слой поглъща пика, после работници довършват записа.
Обичайни стъпки:
- Валидация и контекст на ръба — устройство, кампания, потребител; при нужда идемпотентен ключ срещу дублирани заявки от мрежата.
- Буфер с ясна семантика на загуба — Redis с устойчивост, брокер или друг append-ориентиран слой, не само RAM в PHP процеса.
- Пакетни вмъквания в целта — по-малко операции, по-малко натиск върху диска.
- Обратно налягане — ако консуматорът закъснее, ограничена опашка и сигнал нагоре (забавяне, отказ с 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 към ядрото.
Точки за решение преди да закотвите дизайна
- Допустима ли е загуба? Ако не — буферът трябва да е персистентен и репликиран, с мониторинг на закъснението.
- Колко строг е редът — по потребител, по сесия, или достатъчно е приблизително хронологично?
- Колко независими консуматора ще четат един и същ поток? Колкото повече, толкова по-често печели журнал със запазване.
- Къде са таблата? Ако са върху същия инстанс като плащанията — планирайте изолация: read replica,
statement_timeout, отделен сървър. - Има ли идемпотентност на входа? Без нея повторните заявки размиват метриките и салдата.
Следващите статии в архитектурата ще покрият устойчиви интеграции, състезания при списване и конкретни Laravel шаблони. Едно изречение за запомняне: да налееш поток от събития в същата кошница като парите без амортисьор е осъзнат компромис, не закон на природата.