Как стать автором
Обновить

Комментарии 8

НЛО прилетело и опубликовало эту надпись здесь
В каждом из двух наших дата-центров запущено по четыре таких демона
Это в пределах одного ДЦ в новом соответсвенно еще 4 поднимут
fisher говорил о шардинге данных (юзеры/фотки/комментарии и тд) по серверам СУБД. Это там, в базах данных, бешеные терабайты, там критически важно уметь нормально переносить выход из строя каких-то нод. В данном случае Александр говорит про узкоспециализированный демон, занимающийся своей, конкретной, опять же довольно узкоспециализированной задачей.
Что будете делать, когда появится третий дата-центр?

А когда он появится? такие штуки происходят совсем нечасто, мы все-таки пока еще не гугл :)
Можете рассказать поподробнее:
  1. Для агрегации событий нами была разработана специальная СУБД
    Если я правильно понимаю, то для пользовательских данных вы используете реляционную базу данных, а для событий собственную. В этом случае, каким образом вы гарантируете консистентность данных между ними? Two-phase commit, idempotence или какой-нибудь другой механизм?
  2. Данные пользователей хранятся не только в памяти, но и сохраняются на диск, поэтому уведомления не теряются [при перезапуске демона]. Каким образом вы обеспечиваете durability и высокую производительность [25kreq/s]? append-only + fsync на несколько событий или иным способом? Возможна ли все-таки потеря данных при падении демона?
  3. Каким образом вы отмечаете отправленные события? Что будет, если электронное письмо или push-уведомление уже отправлено, событие еще не помечено, как отправленное, а демон упал? Будет ли одно и то же событие продублировано при перезапуске демона (т.е. получит ли пользователь два одинаковых сообщения)?

Спасибо.
1. Для пользовательских данных используется MySQL. События в демоне, агрегирующем уведомления, хранятся по user_id получателя.

  • Если пользователь удаляется — прошел коммит в MySQL, то в демон отправляется команда — удалить все по user_id. Если команда не прошла, то консистентность может быть нарушена.
  • Перед каждой отправкой мы проверяем, что получатель не удален.
  • Каждого пользователя, который отправил вам уведомления мы также проверяем, что он не удален. Таким образом невозможна ситуация, когда вам придет уведомление, в котором фигурируют удаленные пользователи (на момент отправки, конечно).


2. 25kreq/s — это на 4 демона, то есть на каждый по 6 в пике. (подробнее могут ответить наши системные программисты)

3. Событие не будет продублировано. Отданные скрипту уведомления демон внутри себя откладывает в специальную очередь и ждет, когда ему подтвердят отправку специальной командой — cancel(timeout, flags) или confirm. По умолчанию он по таймауту очистит эту уведомления командой confirm. Второй раз он может отдать то же уведомление, если мы его отложили командой cancel на некоторое время с какими-то флагами, которые означают причину. К примеру, причина — пользователь еще онлайн.
Данные пользователей хранятся не только в памяти, но и сохраняются на диск, поэтому уведомления не теряются [при перезапуске демона]. Каким образом вы обеспечиваете durability и высокую производительность [25kreq/s]? append-only + fsync на несколько событий или иным способом? Возможна ли все-таки потеря данных при падении демона?

Раз в n минут (для этого демона сделано вроде раз в 5-10 минут, если память не изменяет) демон форкается и потомок сохраняет новые данные в очередной файл изменений. Раз в k минут (1 или 2 часа, вроде) демон форкается и потомок сохраняет полный снепшот данных на диск. При загрузке, соответственно, сначала грузится последний снепшот, а затем накатываются изменения.

Таким образом, при падении демона, мы можем потерять новые события за максимум n минут + время на поднятие демона. Демон не настолько критичный, т.к. сами данные не теряются (они в реляционной СУБД), а событиями за небольшой промежуток времени можно пренебречь (пользователь все равно увидит новые события зайдя на сайт). Тем более что падения демона довольно редкое событие.

Временами n и k можно управлять, конечно. Основные затраты — время на системный вызов fork(). В случае если демон сжирает значительное кол-во памяти (скажем 60 GiB и больше), системный вызов fork() может выполняться 1-2 секунды, что недопустимо. Демон о котором здесь идет речь занимает в памяти примерно 4-5 GiB.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий