Что может быть лучше технического поста? Технический пост, за которым стоит бэкграунд трёх дней мучений!
Появилась у меня необычная потребность — ускорить выполнение одного метода. Изучив его работу, я понял: можно добиться ускорения через внедрение кэша. Простая задачка! (Эх, наивный…)
Дано:
У нас от 1 до 20 тысяч записей. Каждая запись выполняет от 1 до 20 тысяч вычислений — которые, к счастью, часто повторяются. А значит, могут быть закэшированы.
Сложность: O(n²). Ну что ж, впихнём кэш.
Первая реализация была на MapDB, ведь он уже использовался в другом методе этого проекта.
Результат? Запрос 324 млн ключей через MapDB — идея плохая.
Время выполнения: 8 часов.
Окей, нужен вариант, готовый к хайлоаду.
Выбор пал на RocksDB. Переписал всё под него.
Результат: 2 часа выполнения (~21 000 операций/сек). Уже лучше, но всё ещё не то.
Думаю — может, твикнем параметры Rocks? Что может пойти не так?
Итог: нагрузка на диск — 1200 МБ/с, 0 операций в секунду. Красота…
Начинаю твикать осознанно, читая доку. Что я сделал:
- Отключил внутренний кэш RocksDB
- Уменьшил размер блоков до 8 МБ
- Отключил кэширование индексов
- Включил кэширование страниц на уровне ОС
- Увеличил размер страниц до 128 КБ
- Снял лимит на число дескрипторов
И ещё один важный шаг — переписал get-запросы на batched multiGet. Почему?
- Меньше JNI-переключений между Java и C++
- Оптимизация I/O при чтении смежных ключей
- Внутренний параллелизм RocksDB при multiGet
И… да! Ускорение до 1.5 часа.
Что дальше? Подключил GPT, начали вместе думать.
Появилась идея: батч в 18 000 ключей — перебор.
Сократил до 1000 — и получил прирост!
Результат: ~41 210 операций в секунду. Много? Да. Достаточно? Пока — нет.
Продолжение следует…
Появилась у меня необычная потребность — ускорить выполнение одного метода. Изучив его работу, я понял: можно добиться ускорения через внедрение кэша. Простая задачка! (Эх, наивный…)
Дано:
У нас от 1 до 20 тысяч записей. Каждая запись выполняет от 1 до 20 тысяч вычислений — которые, к счастью, часто повторяются. А значит, могут быть закэшированы.
Сложность: O(n²). Ну что ж, впихнём кэш.
Первая реализация была на MapDB, ведь он уже использовался в другом методе этого проекта.
Результат? Запрос 324 млн ключей через MapDB — идея плохая.
Время выполнения: 8 часов.
Окей, нужен вариант, готовый к хайлоаду.
Выбор пал на RocksDB. Переписал всё под него.
Результат: 2 часа выполнения (~21 000 операций/сек). Уже лучше, но всё ещё не то.
Думаю — может, твикнем параметры Rocks? Что может пойти не так?
Итог: нагрузка на диск — 1200 МБ/с, 0 операций в секунду. Красота…
Начинаю твикать осознанно, читая доку. Что я сделал:
- Отключил внутренний кэш RocksDB
- Уменьшил размер блоков до 8 МБ
- Отключил кэширование индексов
- Включил кэширование страниц на уровне ОС
- Увеличил размер страниц до 128 КБ
- Снял лимит на число дескрипторов
И ещё один важный шаг — переписал get-запросы на batched multiGet. Почему?
- Меньше JNI-переключений между Java и C++
- Оптимизация I/O при чтении смежных ключей
- Внутренний параллелизм RocksDB при multiGet
И… да! Ускорение до 1.5 часа.
Что дальше? Подключил GPT, начали вместе думать.
Появилась идея: батч в 18 000 ключей — перебор.
Сократил до 1000 — и получил прирост!
Результат: ~41 210 операций в секунду. Много? Да. Достаточно? Пока — нет.
Продолжение следует…
❤🔥34❤10🔥5🤯2🤝1😎1
Бессонный кодер
Что может быть лучше технического поста? Технический пост, за которым стоит бэкграунд трёх дней мучений! Появилась у меня необычная потребность — ускорить выполнение одного метода. Изучив его работу, я понял: можно добиться ускорения через внедрение кэша.…
Дальше начался метод научного тыка. Сократил объём операций до 56 250 000 и начал тестировать разные гипотезы. Вот что получилось:
Результаты:
База (2 ГБ, batch = 1000): 8m 11s
Расширенный Block Cache (10 ГБ): 7m 59s
Уменьшенный batch (500): 8m 09s
Увеличенный batch (2000): 8m 06s
Лексикографически отсортированный batch: 7m 57s
Лексикографически отсортированный весь get: 7m 57s
Сокращение потоков вдвое: 7m 18s
Увеличение потоков вдвое: 9m 32s
Увеличение параллелизма и фоновых задач RocksDB: 8m 05s
Что стало ясно:
1. Block Cache:
Увеличение с 2 до 10 ГБ дало прирост всего ~2%.
➝ Значит, либо данные не влезают в кэш, либо узкое место — не RAM.
2. Batch size:
Изменения в пределах 500–2000 почти не влияют.
➝ Значит, размер уже оптимален под текущий паттерн доступа.
3. Сортировка:
Минимальный выигрыш от сортировки ключей (~14 секунд).
➝ Либо ключи уже достаточно локализованы, либо RocksDB сам всё делает неплохо.
4. Потоки:
Вот где интересно: меньше потоков → быстрее (7:18), больше потоков → медленнее (9:32).
➝ Классический bottleneck по диску или lock'ам:
➝ меньше потоков → меньше переключений и блокировок,
➝ больше потоков → хаос и случайные I/O.
5. Параллелизм RocksDB:
Изменение этих параметров почти не повлияло.
➝ Узкое место в другом.
Когда идеи начали заканчиваться, пришла мысль — а что если всё загрузить в память и забыть про диск?
Ну... не хватило 30 ГБ ОЗУ 😃 Больно, больно.
И тут чёрт меня дёрнул проверить версию JNI-обёртки.
Оказалось — она отстаёт на 2 мажорных версии. Обновил с RocksDB JNI 8 → 10 и...
БАХ — 833 171 операций в секунду с диска.
Время выполнения метода: 390 секунд.
ПОБЕДА.
🧠 Итого:
Три дня, куча боли, и в итоге:
- Ускорение метода в десятки раз
- Глубокое погружение в RocksDB
- Новые знания о высоконагруженных системах
А теперь слово моему копилоту:
Именно вот этим и интересна разработка в целом, это целый логический квест, где ты не знаешь что будет дальше, но точно уверен, главная ошибка тут - ты.
Результаты:
База (2 ГБ, batch = 1000): 8m 11s
Расширенный Block Cache (10 ГБ): 7m 59s
Уменьшенный batch (500): 8m 09s
Увеличенный batch (2000): 8m 06s
Лексикографически отсортированный batch: 7m 57s
Лексикографически отсортированный весь get: 7m 57s
Сокращение потоков вдвое: 7m 18s
Увеличение потоков вдвое: 9m 32s
Увеличение параллелизма и фоновых задач RocksDB: 8m 05s
Что стало ясно:
1. Block Cache:
Увеличение с 2 до 10 ГБ дало прирост всего ~2%.
➝ Значит, либо данные не влезают в кэш, либо узкое место — не RAM.
2. Batch size:
Изменения в пределах 500–2000 почти не влияют.
➝ Значит, размер уже оптимален под текущий паттерн доступа.
3. Сортировка:
Минимальный выигрыш от сортировки ключей (~14 секунд).
➝ Либо ключи уже достаточно локализованы, либо RocksDB сам всё делает неплохо.
4. Потоки:
Вот где интересно: меньше потоков → быстрее (7:18), больше потоков → медленнее (9:32).
➝ Классический bottleneck по диску или lock'ам:
➝ меньше потоков → меньше переключений и блокировок,
➝ больше потоков → хаос и случайные I/O.
5. Параллелизм RocksDB:
Изменение этих параметров почти не повлияло.
➝ Узкое место в другом.
Когда идеи начали заканчиваться, пришла мысль — а что если всё загрузить в память и забыть про диск?
Ну... не хватило 30 ГБ ОЗУ 😃 Больно, больно.
И тут чёрт меня дёрнул проверить версию JNI-обёртки.
Оказалось — она отстаёт на 2 мажорных версии. Обновил с RocksDB JNI 8 → 10 и...
БАХ — 833 171 операций в секунду с диска.
Время выполнения метода: 390 секунд.
ПОБЕДА.
🧠 Итого:
Три дня, куча боли, и в итоге:
- Ускорение метода в десятки раз
- Глубокое погружение в RocksDB
- Новые знания о высоконагруженных системах
А теперь слово моему копилоту:
Итоги оптимизации:
Обновление rocksdbjni дало основной прирост
Точное количество потоков имеет критичное значение
Сортировка ключей даёт минимальный, но стабильный прирост
Batch и cache — важны, но эффект умеренный
Использование NVMe SSD — must-have
Что дальше?
Архитектурные изменения: шардирование, горизонтальное масштабирование
Или full in-memory при небольших объёмах
Именно вот этим и интересна разработка в целом, это целый логический квест, где ты не знаешь что будет дальше, но точно уверен, главная ошибка тут - ты.
❤24🔥4⚡3👾2❤🔥1🕊1🆒1
В прошлом посте про геймдев я упомянул шину событий игры, и вы задали вопрос, что это за шина вообще?
Я люблю ваши вопросы, так что давайте ответим на него! 🥰
В больших проектах с большим количеством разных модулей, а в нашем случае модов, нам нужен способ передавать информацию о различных событиях между всеми нашими частями. И тут в бой входит шина событий.
Шина - список методов которые принимают то или иное событие, порой с дополнительными плюшками в виде приоритетов или отмены события.
Давайте представим что Рома нажал ПКМ по двери чтобы открыть её и войти в комнату Брендона. Тут в дело вступает
Ивент в шине, тут он будет проходить по всем местам где есть на него подписка (пример):
Но как мы определяем какая подписка должна выполнится первее, для этого у нас есть приоритеты:
Возвращаясь к Брендону. Сначала наше событие приходит в HIGH подписку где мы проверяем, если Рома сильно ранен или у него нет рук, то событие отменяется, и идёт дальше, выглядит это примерно так:
Если Рома не прыгал со скалы, то ивент пройдёт дальше, и словится другим слушателем, который уже даст команду Брендону начать быковать на Рому, вот как-то так :3
Я люблю ваши вопросы, так что давайте ответим на него! 🥰
В больших проектах с большим количеством разных модулей, а в нашем случае модов, нам нужен способ передавать информацию о различных событиях между всеми нашими частями. И тут в бой входит шина событий.
Шина - список методов которые принимают то или иное событие, порой с дополнительными плюшками в виде приоритетов или отмены события.
Давайте представим что Рома нажал ПКМ по двери чтобы открыть её и войти в комнату Брендона. Тут в дело вступает
PlayerInteractEvent.RightClickBlock
. Когда сервер получает пакет от клиента игрока о том что тот делает клик, в шину событий улетает этот ивент:public static PlayerInteractEvent.RightClickBlock onRightClickBlock(Player player, InteractionHand hand, BlockPos pos, BlockHitResult hitVec) {
PlayerInteractEvent.RightClickBlock evt = new PlayerInteractEvent.RightClickBlock(player, hand, pos, hitVec);
NeoForge.EVENT_BUS.post(evt);
return evt;
}
Ивент в шине, тут он будет проходить по всем местам где есть на него подписка (пример):
@SubscribeEvent
public void onRightClick(PlayerInteractEvent.RightClickBlock event) {
event.getEntity().sendSystemMessage(Component.literal("КАК ТЫ СМЕЛ ТЫКНУТЬ ПО БЛОКУ?"));
}
Но как мы определяем какая подписка должна выполнится первее, для этого у нас есть приоритеты:
public enum EventPriority
{
HIGHEST, //First to execute
HIGH,
NORMAL,
LOW,
LOWEST; //Last to execute
}
Возвращаясь к Брендону. Сначала наше событие приходит в HIGH подписку где мы проверяем, если Рома сильно ранен или у него нет рук, то событие отменяется, и идёт дальше, выглядит это примерно так:
@SubscribeEvent
public void onRightClick(PlayerInteractEvent.RightClickBlock event) {
if(event.getEntity().isWithoutHands()) {
event.setCanceled(true);
}
}
Если Рома не прыгал со скалы, то ивент пройдёт дальше, и словится другим слушателем, который уже даст команду Брендону начать быковать на Рому, вот как-то так :3
❤42❤🔥6🤔1🎉1👌1🍓1
Пока я тут собираю информацию для постов по Игре Бога, согласую её публикацию (NDA дело такое), собираю это в посты - проходит много времени, а ведь у меня ещё и работа есть, так что да, вы видите посты не так часто как этого хочу я. И параллельно изучению сценариев, изучению истории коммитов и кода я пересматриваю серии.
Ютуб что логично, заметил что у меня появился интерес к Игре Бога, а ещё он знает что я люблю смотреть документалки и рассказы про кино, к примеру MacGuffin Channel, И ОН РЕШИЛ ВЫДАТЬ МНЕ ЛЕГЕНДАРНОЕ КОМБО.
https://www.youtube.com/watch?v=z0v3_T2ynto
Короче да, ребята, я нашёл новую звёздочку лофд, за такой труд мы можем автору закинуть лайков)
Ютуб что логично, заметил что у меня появился интерес к Игре Бога, а ещё он знает что я люблю смотреть документалки и рассказы про кино, к примеру MacGuffin Channel, И ОН РЕШИЛ ВЫДАТЬ МНЕ ЛЕГЕНДАРНОЕ КОМБО.
https://www.youtube.com/watch?v=z0v3_T2ynto
Короче да, ребята, я нашёл новую звёздочку лофд, за такой труд мы можем автору закинуть лайков)
YouTube
О чем был Сезон Лололошки ИГРА БОГА? Часть #1
Представляю вам первую часть своего фильма о сюжетном сезоне ютубера MrLololoshka — “Игра Бога”.
ТГ: http://t.me/Ya_Oskar2002
Донат: https://www.donationalerts.com/r/ya_oskar
Фрагманеты видео:
@MrLololoshka
https://www.youtube.com/@UC9wty4TUXn2yeEn3RhfeJ6w…
ТГ: http://t.me/Ya_Oskar2002
Донат: https://www.donationalerts.com/r/ya_oskar
Фрагманеты видео:
@MrLololoshka
https://www.youtube.com/@UC9wty4TUXn2yeEn3RhfeJ6w…
❤40🥰10💯6🍓2💅2💘1
Какая самая неотъемлемая часть сюжета?
Конечно же чат. Ведь в отсутствие возможности передавать мысли персонажей голосом, мы делаем это через текст — тот самый, который читаете вы и Рома. Именно поэтому мы уделяем ему отдельное внимание.
Например, если вы посмотрите первую и третью серии Игры Бога, то заметите, как мы начали работать над айдентикой чата.
Наши персонажи всегда пишут в квадратных скобках — [Картер] — это сразу позволяет понять: перед вами сюжетный герой, а не просто системное сообщение или реплика от энтити из какого-нибудь мода.
Кроме того, у каждого сезона есть свой уникальный цвет чата, и он тоже выбран не случайно. Он отражает настроение и тематику сезона — и я уверен, уже успел отложиться у вас в голове как визуальная ассоциация.
Фан-факт:
Для последних сезонов выбор цвета был настолько детализированным, что на это реально ушло несколько дней и масса обсуждений между сценаристами, геймдизайнерами и Ромой.
Вот такие вот мелочи, которые на самом деле — совсем не мелочи :3
Конечно же чат. Ведь в отсутствие возможности передавать мысли персонажей голосом, мы делаем это через текст — тот самый, который читаете вы и Рома. Именно поэтому мы уделяем ему отдельное внимание.
Например, если вы посмотрите первую и третью серии Игры Бога, то заметите, как мы начали работать над айдентикой чата.
Наши персонажи всегда пишут в квадратных скобках — [Картер] — это сразу позволяет понять: перед вами сюжетный герой, а не просто системное сообщение или реплика от энтити из какого-нибудь мода.
Кроме того, у каждого сезона есть свой уникальный цвет чата, и он тоже выбран не случайно. Он отражает настроение и тематику сезона — и я уверен, уже успел отложиться у вас в голове как визуальная ассоциация.
Фан-факт:
Для последних сезонов выбор цвета был настолько детализированным, что на это реально ушло несколько дней и масса обсуждений между сценаристами, геймдизайнерами и Ромой.
Вот такие вот мелочи, которые на самом деле — совсем не мелочи :3
❤🔥84❤10🕊7🦄3🔥2🤯1👀1
Есть интересная и очень крутая вещь в нашем флоу работы, в процессе написания серии кодером и её тестирования тестером, она может немного изменится в сторону лучшего визуала и геймплея. Что я имею в виду? Ну смотрите, первая серия Игры Бога.
Помните все страшилки которые насылал на Рому Люциус? На самом деле их изначально было на одну больше, когда бы он рубил первое дерево, его бы ударила молния, но в процессе разработки и тестирования было решено что этот момент излишен и он был успешно вырезан.
А помните алмазный блок в конце тоннеля? Тоже такой момент, его не было, хоба, и появился в процессе разработки, как мотивация чтобы Рома зашёл в тоннель, а не сбежал куда подальше.
И так мы работаем до сих пор, бывают крайне маленькие изменения, бывают чуть большие, вплоть до смены локации чтобы катсцена или файт выглядели эпичнее. Вот как-то так)
Помните все страшилки которые насылал на Рому Люциус? На самом деле их изначально было на одну больше, когда бы он рубил первое дерево, его бы ударила молния, но в процессе разработки и тестирования было решено что этот момент излишен и он был успешно вырезан.
А помните алмазный блок в конце тоннеля? Тоже такой момент, его не было, хоба, и появился в процессе разработки, как мотивация чтобы Рома зашёл в тоннель, а не сбежал куда подальше.
И так мы работаем до сих пор, бывают крайне маленькие изменения, бывают чуть большие, вплоть до смены локации чтобы катсцена или файт выглядели эпичнее. Вот как-то так)
🔥54❤5🥰3👌2🤩1
Время моей (и, надеюсь, вашей) любимой рубрики!
Что мы смотрим во время миграции (ну или просто долгого математического расчёта).
И сегодня на наш стол падает «Баракамон» — прекрасное аниме о том, как молодой каллиграф по стечению обстоятельств оказывается сослан в глухую деревушку на острове. Там он постепенно переосмысливает свою жизнь, ценности, работу — и учится заново быть собой.
Это очень тёплое аниме в жанре повседневности. Обязательно посмотрите его, если вы сейчас сталкиваетесь с выгоранием, потерей своего стиля или просто нуждаетесь в теплоте.
Но меня особенно зацепила одна тема, которая в отличие от прочих не проговаривается напрямую, но играет важную роль.
Нару — вторая главная героиня. Активная, весёлая девочка лет семи. Живёт с дедом — родителей у неё нет. Вроде бы она прекрасно справляется, не выглядит «покинутой» или грустной, но по ходу сюжета ты начинаешь чувствовать: ей не хватает взрослого, стабильного, тёплого присутствия. И именно ГГ постепенно становится для неё такой фигурой.
Не сразу, не по плану, но — становится.
И в их отношениях рождается нечто среднее между связью старшего и младшей, и… почти родительской заботой.
Это не проговаривается словами, но чувствуется.
И вот в этом, как мне кажется, и кроется одна из важных тем «Баракамона»:
люди могут стать семьёй не по крови, а по выбору и совместному пути.
(Если будете смотреть Баракамон, то обязательно вместе с ним смотрите Мидзикамон, это 2-ух минутные Чиби ролики которые подготовлены для просмотра после каждой серии)
Что мы смотрим во время миграции (ну или просто долгого математического расчёта).
И сегодня на наш стол падает «Баракамон» — прекрасное аниме о том, как молодой каллиграф по стечению обстоятельств оказывается сослан в глухую деревушку на острове. Там он постепенно переосмысливает свою жизнь, ценности, работу — и учится заново быть собой.
Это очень тёплое аниме в жанре повседневности. Обязательно посмотрите его, если вы сейчас сталкиваетесь с выгоранием, потерей своего стиля или просто нуждаетесь в теплоте.
Но меня особенно зацепила одна тема, которая в отличие от прочих не проговаривается напрямую, но играет важную роль.
Нару — вторая главная героиня. Активная, весёлая девочка лет семи. Живёт с дедом — родителей у неё нет. Вроде бы она прекрасно справляется, не выглядит «покинутой» или грустной, но по ходу сюжета ты начинаешь чувствовать: ей не хватает взрослого, стабильного, тёплого присутствия. И именно ГГ постепенно становится для неё такой фигурой.
Не сразу, не по плану, но — становится.
И в их отношениях рождается нечто среднее между связью старшего и младшей, и… почти родительской заботой.
Это не проговаривается словами, но чувствуется.
И вот в этом, как мне кажется, и кроется одна из важных тем «Баракамона»:
люди могут стать семьёй не по крови, а по выбору и совместному пути.
(Если будете смотреть Баракамон, то обязательно вместе с ним смотрите Мидзикамон, это 2-ух минутные Чиби ролики которые подготовлены для просмотра после каждой серии)
❤37🤩4❤🔥3🔥2🤝2🆒1
Кукловод. О чём вы подумали, прочитав это слово? Фильм? Страшилка? Кукла из «Пилы»?
А ведь именно так можно назвать Storytelling.
Почему? В ранние времена в сюжете часто использовались сущности из других модов и ванильной игры: зомби, Картер, да даже Селести.
С нашими сущностями всё понятно — мы ими управляем напрямую. Но что насчёт чужих?
Тут в дело вступает наша комплексная система, которая полностью перехватывает управление существом на себя — прямо как кукловод управляет своей марионеткой.
Наш «кукловод» может:
- поворачивать и направлять
- менять маршрут
- подменять текстуры
- глушить систему целей (goals)
и многое другое…
В итоге любая сущность подчиняется нашей воле.
Вот так вот :3
А ведь именно так можно назвать Storytelling.
Почему? В ранние времена в сюжете часто использовались сущности из других модов и ванильной игры: зомби, Картер, да даже Селести.
С нашими сущностями всё понятно — мы ими управляем напрямую. Но что насчёт чужих?
Тут в дело вступает наша комплексная система, которая полностью перехватывает управление существом на себя — прямо как кукловод управляет своей марионеткой.
Наш «кукловод» может:
- поворачивать и направлять
- менять маршрут
- подменять текстуры
- глушить систему целей (goals)
и многое другое…
В итоге любая сущность подчиняется нашей воле.
Вот так вот :3
❤74☃12🔥6🤯3🫡3👍2🤔2🤝2💘2🤗1
Пока посты пишутся, для вас вопрос, у меня тут возникла возможность провести стрим(ы) где мы будем шалить с разработкой вечерами, что думаете, и где?
Final Results
49%
Да, в Telegram (полная свобода и прекрасный плейлист)
14%
Да, в YouTube (мы ограничены content ID)
26%
Да, на Twitch (надо ещё создать)
1%
Да, на w.tv (надо прочитать пользовательское соглашение ещё)
10%
Я пасс
❤🔥45❤10🤗4👍2🔥2💘2😎2🍓1
Бессонный кодер
Пока посты пишутся, для вас вопрос, у меня тут возникла возможность провести стрим(ы) где мы будем шалить с разработкой вечерами, что думаете, и где?
Первый, тестовый, стрим в 19:00 по МСК 😘
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥50👏12💘5❤4🎃2🦄2😎2🔥1🥰1
Сказ о том, как мы финал пытались пережить
Ага, наконец-то пост-разбор инцидента 14 августа. Поехали!
Что изменилось по сравнению с прошлыми финалами?
Мы выросли. В ансабе уже 60 000 человек, бот стоит в тысячах чатов (включая чат архимага), и нагрузка выросла в разы. Было ясно: финал — это стресс-тест. Но мы ещё не знали, насколько, и что это тест наших нервов.
Подготовка началась заранее:
- за сутки до финала заморозили релизы (чтобы случайно не деплойнуть баг в самый ответственный момент);
- за 10 минут до премьеры сделали лучшее, что могли — открыли дашборды и начали молиться.
Хронология (UTC+3)
14:57 — первый алерт: повышенная нагрузка на приём обновлений. Началось.
15:24 — странность: поток обновлений резко падает. Нагрузка есть, а обновлений нет.
15:28 — понимаем, что не достучаться до Telegram: запросы уходят в таймаут. Начинаем действовать.
15:29 — пробуем стандартную меру (ресет подключений). Не помогает. В логах только это:
15:39 — экстренно перезапускаем всю ноду.
15:42 — ребут завершён. Всё ещё таймауты. Решаем перенести работу с Telegram на сервер в РФ.
15:47 — запускаемся с запасной локации.
Параллельно тестируем пинг:
15:58 — обрывается внутренний VPN (ТСПУ, привет). Мы снова в нокауте.
16:02 — запускаемся на резерве. Пинг огромный, но живём.
16:10 — датацентр сообщает: проблему устранили. Запускаем миграцию трафика обратно.
16:11–16:13 — аккуратно переводим очередь и приёмку сообщений.
16:17 — заканчиваем обработку накопившейся очереди. Мы снова в бою.
Что же случилось?
Один из промежуточных провайдеров на маршруте до Telegram ушёл на техработы/сломался. Сервер был доступен, но маршрут — нет. Вот комментарий от ДЦ:
Что мы пережили?
За 2.5 часа инцидента мы успели обработать:
- 20 000 сообщений,
- 3 000 входов в чаты,
- 30 000 обновлений от Telegram.
Что мы вынесли?
Нужно серьёзнее думать о кластеризации и геораспределении: несколько локаций, стабильные каналы, отсутствие зависимости от одного ISP и минимизация рисков со стороны ТСПУ.
Вот как-то так, в итоге вся наша команда не смогла посмотреть финал на премьере(
Ага, наконец-то пост-разбор инцидента 14 августа. Поехали!
Что изменилось по сравнению с прошлыми финалами?
Мы выросли. В ансабе уже 60 000 человек, бот стоит в тысячах чатов (включая чат архимага), и нагрузка выросла в разы. Было ясно: финал — это стресс-тест. Но мы ещё не знали, насколько, и что это тест наших нервов.
Подготовка началась заранее:
- за сутки до финала заморозили релизы (чтобы случайно не деплойнуть баг в самый ответственный момент);
- за 10 минут до премьеры сделали лучшее, что могли — открыли дашборды и начали молиться.
Ну что, @imguardbot, я запомню тебя таким. Земля пухом твоим серверам.
Хронология (UTC+3)
14:57 — первый алерт: повышенная нагрузка на приём обновлений. Началось.
15:24 — странность: поток обновлений резко падает. Нагрузка есть, а обновлений нет.
15:28 — понимаем, что не достучаться до Telegram: запросы уходят в таймаут. Начинаем действовать.
15:29 — пробуем стандартную меру (ресет подключений). Не помогает. В логах только это:
Failed to fetch updates. Waiting: 1s request to https://api.telegram.org/botXXXX/getUpdates...
failed, reason: connect ETIMEDOUT 149.154.167.220:443
15:39 — экстренно перезапускаем всю ноду.
15:42 — ребут завершён. Всё ещё таймауты. Решаем перенести работу с Telegram на сервер в РФ.
15:47 — запускаемся с запасной локации.
Параллельно тестируем пинг:
12 packets transmitted, 0 received, 100% packet loss
15:58 — обрывается внутренний VPN (ТСПУ, привет). Мы снова в нокауте.
16:02 — запускаемся на резерве. Пинг огромный, но живём.
16:10 — датацентр сообщает: проблему устранили. Запускаем миграцию трафика обратно.
16:11–16:13 — аккуратно переводим очередь и приёмку сообщений.
16:17 — заканчиваем обработку накопившейся очереди. Мы снова в бою.
Что же случилось?
Один из промежуточных провайдеров на маршруте до Telegram ушёл на техработы/сломался. Сервер был доступен, но маршрут — нет. Вот комментарий от ДЦ:
Мы наблюдаем ухудшение маршрута (потеря пакетов/высокий пинг) с несколькими ISP на промежуточных узлах. Из-за этого соединение может обрываться, даже если сервер доступен. Вероятно, техническое обслуживание или временная перенастройка маршрута.
Что мы пережили?
За 2.5 часа инцидента мы успели обработать:
- 20 000 сообщений,
- 3 000 входов в чаты,
- 30 000 обновлений от Telegram.
Что мы вынесли?
Нужно серьёзнее думать о кластеризации и геораспределении: несколько локаций, стабильные каналы, отсутствие зависимости от одного ISP и минимизация рисков со стороны ТСПУ.
Вот как-то так, в итоге вся наша команда не смогла посмотреть финал на премьере(
❤55❤🔥6🔥4🕊4😨2😭1