Скільки поїздів дальнього сполучення УЗ ганяє на добу, я так і не знайшов, тому рахую з іншого кінця: за 2025 УЗ перевезла 28 мільйонів пасажирів дальнього сполучення, це десь 77 тисяч місць на добу.
Продаж відкривається за 20 діб до відправлення, о восьмій ранку. Тобто щоранку заходить одна доба інвентаря: округлимо до ста тисяч, бо на свята чіпляють додаткові вагони.
Тепер розмір одного місця: поїзд, вагон, номер, статус, id замовлення, версія для оптимістичного локу — сто байт, і це з запасом. Сто тисяч місць це 10 мегабайт, а все вікно продажу, всі двадцять діб, це 200 мегабайт.
Весь квитковий інвентар країни вміщається в пам'ять робота пилососа 🙂
Записи (writes) мають зручну особливість: успішних бронювань за добу не буде більше, ніж місць у поїздах. Навіть якщо уявити, що всю добу розібрали за одну хвилину, це 1700 записів на секунду.
Спроб буде більше, на гарячому напрямку десятки на одне місце. Проте невдала спроба це перевірка в пам'яті, яка падає одразу і коштує майже нічого. Дорого стає тоді, коли всі ці спроби шикуються в чергу до одного рядка.
Читання страшніші на вигляд. Хай о восьмій одночасно сидить, не знаю, тисяч 50 із семи мільйонів користувачів застосунку, кожен смикає екран разів чотири за перші пів хвилини. Сім тисяч запитів на секунду.
Дані між оновленнями не змінюються, тому один сервер тримає весь стан у пам'яті і віддає ці сім тисяч не напружуючись. Додаємо другий, але не заради навантаження, а щоб було куди падати. Redis на гігабайт, Postgres під замовлення. Кластера і шардингу немає, бо шардити нема чого.
Значить, підвисання о восьмій це не питання потужності.
Воно зникає, якщо о восьмій нічого не оновлювати: дані відомі заздалегідь, кеш прогрітий з вечора, а восьма це просто поле
activeFrom. Роздавати цей список наперед не можна, бо хитрі зберуть його завчасно і о восьмій вистрелять уже готовим замовленням.В апці після невдалої спроби пасажирів треба додавати заново, і це не інфраструктура, це продукт. Дайте раз зберегти склад сім'ї і преференси: троє в одне купе, бажано нижні, якщо ні то верхні, а як геть край то сусідні купе і тд. Тоді після невдачі система сама підбирає наступний варіант, а не викидає вас на початок квесту.
А те п'ятихвилинне очікування, за яке встигаєш передумати, це або та сама черга до гарячого рядка, або штучна затримка, щоб система не лягла. Якщо друге, то тротлити нема від чого, ми щойно порахували. Якщо перше, то це, мабуть, і є та черга, і залізом вона не лікується.
Саме тут і треба міняти правила: замість гонки на мілісекунди збирати заявки у вікно, хвилин на п'ять, і розігрувати місця жеребкуванням серед усіх, хто встиг. Програв — дізнався одразу, а не за п'ять хвилин фальшивого банера. Тут залишається ризик ботів, проте цього разу гра не на швидкість, а на кількість. Для перемоги треба зайняти більше місць, а значить зробити більше ботів, і з цим легше боротись. Але це вже тема для іншого посту.
(усі цифри уявні, на істину не претендую, з дивану завжди краще видно, пишіть в коменти де я неправий, ставте лайки чи какашки)