secon'2014 - Сергеев Антон - Асинхронные задачи в ifunny

44

Upload: -secon2014

Post on 16-Jun-2015

142 views

Category:

Presentations & Public Speaking


0 download

DESCRIPTION

Я расскажу про то, как выполнять тяжелые задачи, требующие значительного количества серверных ресурсов и времени так, чтобы это оставалось незаметным для пользователя. Какую архитектуру выбрали мы, каким инструментом пользуемся для решения асинхронных задач в iFunny. Поделюсь опытом: какие трудности были встречены на пути перехода к асинхронным задачам, какие решения выбрали и как мы видим наше светлое будущее. Доклад будет интересен всем, кто интересуется сложными распределенными системами.

TRANSCRIPT

Page 1: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Асинхронные задачи в iFunny :)

Сергеев Антон@hackPNZ

Page 2: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Про что все это?

Когда и для чего могут понадобиться асинхронные задачи; Существующие готовые решения;

Что выбрали мы, наша архитектура, наш опыт.

Page 3: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

iFunny :)Юмористический сервис;

Суточная аудитория:4 000 000 пользователей;

Около 250 000 работпубликуется ежедневно;

Около 1 000 000 000 просмпросмотров контента каждый день.

Page 4: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

РазработкаiFunny :)

Page 5: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

iFunny 2.4Возможность добавлять GIF

Тяжелый контент (до 10Mb);

Конвертация в видео при добавлении (формат webm);

Нарезка тумбов, форматы jpegи webp.

Q2 2013

Page 6: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

iFunny 3.0Подписки, возможностьрепубликации работ

Подписки, добавление работв ленты пользователей;

РепуРепубликации, добавление републикаций в ленты пользователей.

Q4 2013

Page 7: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Asynchronoustask queue

Page 8: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Поддержка множества языков для реализации воркеров(в том числе, PHP); Очень большой лимит размера сообщения (4GB);

Большое количество мануалов в сети.

www.gearman.org

Page 9: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Python в качестве основного поддерживаемого языка; Проект быстро развивается, активное сообщество;

Легко развертывается, минимум конфигов и лишнего кода;

Интеграция с Django.

www.celeryproject.orgCelery

Page 10: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Мы выбрали Celery

Python :)

Гибкий, поддержка множества различных брокеров;

Отказоустойчивый, легко масштабируется;

Высокопроизводительный;

Вдохновляющий опыт Instagram.

Page 11: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Celerybrokers

Page 12: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

RabbitMQ

Стабильный; Рекомендуют по-умолчанию.

Cложность тонкой настройки;

Плюс еще один компонент инфраструктуры.

Page 13: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Redis

Давно и успешно используем в продакшне; Быстрые запись/чтение (задачи хранятся в памяти);

Легко поднять с нуля.

Дорого для больших данных;

Failover: можно, но сложно.

Page 14: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Experimental brokers

MongoDB; | ограничение размера документа 16Mb

Beanstalk;

Amazon SQS;

CouchDB;

SQLAlchemy;

...другие.

Page 15: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Сельдерей + редис!

Page 16: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Архитектура

Page 17: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

API Instances

Celery gates

Celeryworkers

Redis storage

Page 18: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

2x uWSGI gate instances

2x AWS EC2 c3.xlarge(4 vCPU, 7.5Gb RAM, 2x 40Gb SSD)

8x Worker instances

8x AWS EC2 c3.2xlarge(8 vCPU, 15Gb RAM, 2x 80Gb SSD)

Page 19: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

rpm

Page 20: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Задачи в iFunny :)

Публикация контента;

Fanout;

Revoke fanout;

Рассылка email-уведомлений.

Page 21: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Конфигурация Celerycelery = Celery('celerytasks')

celery.config_from_object(‘celeryconfig')

@celery.task()

def test_task(foo):

result = tasks.test.execute(foo)

return result

Page 22: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Broker configBROKER_URL = "redis://:12345@localhost:6379/0"

CELERY_RESULT_BACKEND = "redis://:12345@localhost:6379/0"

Page 23: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

API entry pointfrom flask import g...

@app.route(“/test/task", methods=[‘GET'])

def test_task():

foo = g.params.get('foo')

async_result = celerytasks.test_task.delay(foo)

return async_result

Page 24: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Разделение очередейCELERY_ROUTES = {

'celerytasks.test_task': {'queue': 'test_foo'}, 'celerytasks.foo_task': {'queue': 'test_foo'}, 'celerytasks.bar_task': {'queue': 'test_bar'},

}

Page 25: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Task callingfeatures

Page 26: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Linking

test_task.apply_async((foo), link=test_task.s(bar))

Custom error handler

test_task.apply_async((foo), link_error=error_handler.s())

Countdown

result = test_task.apply_async((foo), countdown=3)rresult.get() # вернет результат как минимум через 3 секунды

Page 27: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Expiration

test_task.apply_async((foo), expires=60) # задача истечет через 60 секунд от текущего времени (получает статус REVOKED)

Retry

test_task.apply_async((foo), retry=True, retry_policy={

'max_retries': 3, 'interval_start': 0, 'interval_step': 0.2, 'interval_max': 0.2,

})

Page 28: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Serializers

test_task.apply_async((foo), serializer=‘json') # pickle, JSON, YAML, msgpack etc

Compression

test_task.apply_async((foo), compression=‘zlib') # gzip, bzip2

Routing to queue

test_task.apply_async(queue=‘test_queue')test_task.apply_async(queue=‘test_queue')

Page 29: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Логирование

Page 30: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Graylog2

Open source система аналитики данных; Собственный формат сообщений GELF;

Дополнительно берем сообщения из syslog.

Иногда падает при использовании GELF.

Page 31: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 32: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Мониторинг

Celery events;

Flower;

Datadog;

New Relic;

...другие.

Page 33: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

FlowerReal-time tasks monitoring; Workers pool restart;

Web-interface;

Основан на celery events.

Постоянно падал в пике нагрузки;

Мало сМало статистики.

Page 34: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 35: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 36: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 37: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Datadogfrom statsd import statsd

...

@app.route("/foo", methods=['POST'])

def foo():

statsd.increment('ifunny.tasks.received', 1, tags=[“task:foo”])

Page 38: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 39: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny
Page 40: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

New RelicСреднее время выполнения задачи; Детальная статистика по типам задач;

Реалтайм мониторинг ошибок;

Количество запросов в минуту;

Футболка в подарок :)

ССтоит недешево.

Page 41: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Среднее время выполнения задач

Page 42: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Мониторинг ошибок

Page 43: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Что дальше?

Celery 3.1 — течет память;

Failover гейтов пришлось сделали руками в коде API;

Гейты сами по себе — тяжелые и избыточные;

Добавлять задачи напрямую из Redis;

Думаем насчет RabbitMQ.

Page 44: SECON'2014 - Сергеев Антон - Асинхронные задачи в iFunny

Спасибо за внимание!

Вопросы?

Сергеев Антон@hackPNZgithub.com/hackpnz