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

Пользователь

Отправить сообщение

Про потыкать - есть планы, надеюсь мы расскажем про них отдельно немного позже

Спасибо!
Да, как то не получилось коротко) тема объемная.
Надеюсь новичок утонет до статьи, и будет выплывать по тихоньку, куда деваться)

Учитывалась ли отправка в ios/android в замерах?
nekufa 10 тыс. пуш-уведомлений в секунду — это нагрузка с нашего продакшен на момент написания статьи.
Это вовсе не означает, что в нет запаса на рост нагрузки.

А еще не могли бы тогда уточнить как вы измеряли? Сообщения какого размера использовали?
Время ожидания feedback'а сюда не входит.
На графике показано суммарное время на обработку сообщения, т.е. не только отправка в сокет.
Для отправки сообщения нужно сходить в тарантул, сделать проверки, сформировать json, упаковать и отправить бинарные данные в ios.
Время обработки ухудшилось из-за проблем с proxy, желтый график без прокси — на нем время хорошее.
Сейчас суммарное время составляет 3-4мс.
Рестарт tarantool длился «минуты», 10-15 минут, не больше, предварительно нужно было сделать снапшот, это еще 10-15 минут, точнее время не назову. Во время снапшота — мастер работает и доступен на запись.
На сервере с tarantool память вся отдана ему. Других процессов нет.

Да ~12k — 15k уведомлений в секунду рассылают 8 серверов:
Intel® Xeon® CPU E5-2620 0 @ 2.00GHz
24 ядра
памяти — 32Гб
жесткие диски — обычные sata

Про лимитирующий фактор не совсем понял, поясните чуть подробнее что имелось ввиду?
В основном у нас кейсы не сортировкой, а с поиском по разным полям.
Там где нужен быстрый поиск — создаем индекс. Если операция редкая — используем full scan по primary key.
Если результирующая выборка небольшая, то сортировать можно в «питоне».
У tarantool 1.6, 1.7, 1.8 — одинаковый протокол с msgpack внутри.
Думаю сложностей быть не должно.
Кроме sql еще много всего интересного, например движок винил.
Было бы интересно попробовать его для хранения данных.
Ещё и fork делать?

А как вы собираетесь весь процесор на python занять без fork?
redis вас тут тоже не спасет.

> Нет, проблема явно не в этом:
отключите запись на диск в tarantool, и запустите свой бенчмарк для сравнения.

Внутри gtarantool запросы группируются в пачки, несколько запросов в отдельном гринлете отправляются через один вызов soket.send. В отдельном гринлете из сокета вычитываются несколько ответов за один soket.recv.
Ну уже видно, что gtarantool в 10 гринлетов быстрее чем обычный синхронный коннектор!
Подберите оптимальное кол-во гринлетов, а если питон утилизировал 1 ядро cpu на 100%, то делайте fork и грузите тарантул больше.

Еще вы сравниваете insert в tarantool и insert в redis, под капотом это немного различные вещи.
Запись на диск или в память. Ваш тест не ждет когда redis синканет все данные на диск.

Сравните разницу на select-ах в gtarantool и redis.
Сделайте несколько гринлетов, и выполняйте insert через общий tarantool-connection.
Можно посмотреть кейсы для gevent: https://habrahabr.ru/company/mailru/blog/254727/
так это ж отказоустойчивость
Рассылку новости инициирует редактор через админку, от админки сайта приходит http-запрос, и если HTTP 200 ОК, то начинается рассылка пуш-уведомлений. Также http-запрос может быть автоматически отправлен на другой доступный сервер.
Что если сообщение было успешно отправлено на следующий сервер, но не было там обработано из-за того, что сервер упал?

Да, будет нужно ждать пока сервер поднимут.
Тогда можно сделать отдельную очередь для таких «эстафетных» сообщений, и в случае падения сервера с такой очередью активировать ее где-то автоматически. Подумаю о такой фиче.
Схема с диапазонами вполне рабочая. Да, в Tarantool Queue можно выставить delay и подготовить сообщения заранее.
Min и Max для ключа также можно быстро извлечь из Tarantool.
Кейс с delay мы используем при рассылки пушей по временным зонам для приложения «Гороскопы».
Сообщения генерируются заранее во все очереди, обрабатываются по delay.

Если данные по primary key распределены неравномерно, то возможно деление по диапазонам приведет к неэффективной выборке пачек.
Также нужно подумать как разбивать на диапазоны, если primary key не числовой.
Что будет, если упадет сервер, на котором генерируются самые первые диапазоны в момент их генерации?

По поводу падения сервера. Маленькое сообщение отправляется перед обработкой пачки.
Если «соседний» сервер упал, то сообщение будет отправлено на следующий доступный сервер.
Для сообщений нужно гарантированно выполнить ack.
Также в Tarantool есть WAL и восстановление после аварии из снапшота.

В нашем случае мы не выбираем данные с очередей на соседних серверах намеренно.
Иначе все обработчики должны слушать все очереди в кластере, это увеличит нагрузку на инстансы Tarantool Queue,
а также создаст дополнительный ненужный траффик по сети.

Также нет опроса очередей 1000 с одного сервера, 1000 с другого, и т.д.
Все логические очереди обрабатываются асинхронно на одном сервере локально в один коннект к Tarantool Queue.
Именно это дает большую скорость их обработки.

По поводу «падает очередь», Tarantool Queue не падает, работает надежно!
«Умирает» сервер (такое у нас случалось не раз) — все работает как и работало.
Да, сообщения из очередей на этом сервере, если они там были, будут обработаны только после того, как сервер реанимируют.
Также такая конфигурация очень проста в эксплуатации, все сервера — одинаковые.
Согласен! Можно использовать «async def» и «await», разрабатывал и отлаживал aiotarantool еще под python-3.4.3
Планирую скоро перейти на этот сахар.
Расскажите что еще кроме go используется?
Что используется в качестве очередей?
Где хранятся пуш-токены?
Попробовал сравнить с Tornado, именно в стиле «Coroutines and concurrency».
Код коннектора для Tornado (прототип) можно посмотреть здесь.

К сожалению в стабильной ветке Tornado, Event Loop не богат concurrency-фичами, такими как Event или Condition.
Поэтому, коннектор и бенчмарк будет работать только на Tornado «4.2.dev1».

pip install git+https://github.com/tornadoweb/tornado.git

Код бенчмарка похож на asyncio.
Результаты бенчмарка:

insert — 30.270719
select — 28.614258
update — 29.975998
delete — 30.612288

Это заметно медленнее asyncio, возможно на callbacks будет быстрее, но совсем не хочется использовать этот стиль.
Yappi-профайлер показывает, что много времени тратится на вызовы tornado.gen, пруф. здесь.
При этом, за бенчмарк было сделано 5K вызовов read/write в tornado.iostream, что неплохо, по-сравнению с синхронным подходом.
Из плюсов можно отметить, что сам инстанс Tarantool расходует на порядок меньше CPU.
По сложности сравнивал именно с gevent, в нем event loop, как таковой — спрятан. Вызовы, в которых происходит переключение между гринлетами, остаются в неизменном виде. С Tornado не сравнивал, но было бы интересно узнать разницу по бенчмаркам.
1

Информация

В рейтинге
Не участвует
Работает в
Зарегистрирован
Активность