View
1.999
Download
1
Category
Preview:
DESCRIPTION
Citation preview
Использование ØMQ для построения распределенных систем
Андрей ОхлопковАлексей Ермаков
План доклада• Разработка распределенных систем• ØMQ: краткий обзор• Case study: GH ATP
Распределенные системы
Распределенные системы• Более гибкие в разработке• Проще масштабировать• Надежнее
Масштабируемость
Отказоустойчивость
Гетерогенность
Взаимодействие• HTTP• TCP/IP• Message-Oriented Middleware (MOM)
MOM• Асинхронное взаимодействие через прием
и отправку сообщений• Очереди и маршрутизация
Распространенные MOM• Amazon SQS• MSMQ• JMS• AMQP (RabbitMQ, Apache Qpid)
ØMQ• Разработан компанией iMatix (AMQP)• LGPL• Поддерживает C/C++, C#, Java, Python, PHP,
Ruby, Erlang и другие языки • “Sockets on steroids”
Отличия от других MOM• Отсутствие брокера• API, похожий на BSD sockets API• Произвольный формат сообщений• Различные модели взаимодействия
Отличия от обычных сокетов• N:M взаимодействие• bind()/connect() могут быть вызваны в
любом порядке на любой стороне• Поток сообщений а не байтов• Автоматическое переподключение
Модели взаимодействия• Request/reply• Publish/subscribe• Pipeline
Request/reply
Request/reply: серверimport zmqcontext = zmq.Context(1)s = context.socket(zmq.REP)s.bind("tcp://*:5000") while True: request = s.recv() s.send(request.upper())
Request/reply: клиент import zmq, syscontext = zmq.Context(1)s = context.socket(zmq.REQ)s.connect("tcp://localhost:5000")s.send(sys.argv[1])print socket.recv(),
Request/reply$ python server.py &[1] 79259$ python client.py foo FOO$ python client.py barBAR
Request/reply: серверimport zmqcontext = zmq.Context(1)s = context.socket(zmq.REP)s.bind("tcp://*:5000") while True: request = s.recv() s.send(request.upper())
Request/reply: клиент import zmq, syscontext = zmq.Context(1)s = context.socket(zmq.REQ)s.connect("tcp://localhost:5000")s.send(sys.argv[1])print socket.recv(),
Проблема с масштабируемостью
Решение: queue device
Queue = XREQ + XREP + device
Queue = XREQ + XREP + deviceimport zmq, random, timecontext = zmq.Context(1)xrep = context.socket(zmq.XREP)xrep.bind("tcp://*:5000")xreq = context.socket(zmq.XREQ)xreq.bind("tcp://*:5001")zmq.device(zmq.QUEUE, xrep, xreq)
Несколько devices в одной сети
Модели взаимодействия• Request/reply• Publish/subscribe• Pipeline
Publish/subscribe
Publish/subscribe: сервер import zmq, random, timecontext = zmq.Context(1)s = context.socket(zmq.PUB)s.bind("tcp://*:5000")
Publish/subscribe: сервер while True: for city in ["Moscow", "Murmansk", "St. Petersburg"]: s.send(city, zmq.SNDMORE) s.send(str(random.randint(10, 20))) time.sleep(2)
Publish/subscribe: клиент import zmq, syscontext = zmq.Context(1)s = context.socket(zmq.SUB)s.connect("tcp://localhost:5000")
Publish/subscribe: клиентs.setsockopt(zmq.SUBSCRIBE, sys.argv[1])while True: city = socket.recv() temp = socket.recv() print city + ": " + temp
Publish/subscribe$ python server.py &[1] 79569$ python client.py MMoscow: 11Murmansk: 11Moscow: 13Murmansk: 17
Модели взаимодействия• Request/reply• Publish/subscribe• Pipeline
Pipeline
Другие возможности• PAIR-сокеты• Долговременные сокеты• Транспорты: in-process, IPC, TCP, PGM• Межпоточное взаимодействие
Другие возможности• Polling• Альтернативные модели взаимодействия• Devices (queue, forwarder, streamer и
собственные)
Что отсутствует• Транзакции• Гарантированная доставка сообщений• Информация о подключениях и контроль
над ними
Внимание! • В inproc-сокетах connect() должен быть
вызван после bind()• Сокеты привязаны к потокам• Фильтрация на стороне клиента в PUB/SUB• assert() в случае ошибок
Заключение• Легко использовать• Высокая производительность• Большой выбор моделей взаимодействия• Легко модифицировать существующую
архитектуру
Case study: GH ATP
Case study: GH ATP• Автоматизированная торговля ценными
бумагами• Большой объем данных (сотни тысяч
котировок в секунду)• Жесткие требования к производительности
Задача: получение котировок• Разные поставщики данных с разными
протоколами• Данные используются в нескольких
продуктах• Нужен унифицированный API
Требования• Низкое время отклика (<1 мс)• Большие объемы данных• Поддержка нескольких языков (на данный
момент — Scala и C++)• Load balancing, fault tolerance
Решение• Клиент-серверное взаимодействие на
основе ØMQ• Google Protocol Buffers для сериализации
сообщений
Клиент-сервер
Архитектура
Архитектура• Stateless взаимодействие• Легко балансировать нагрузку и
обеспечивать устойчивость• Высокая производительность
Цифры• Тестовые сервер и клиент (Scala), TCP/IP• Около 250 000 котировок в секунду• Средняя задержка: <1 мс• CPU bound (protobuf), ØMQ может дать
большую производительность
ØMQ — это• Легкая разработка высонагруженных
распределенных систем• Простая модификация и добавление нового
функционала• Масштабирование и скорость
• http://www.zeromq.com• http://mongrel2.org• Андрей Охлопков <oh@ghcg.com>• Алексей Ермаков <ae@ghcg.com>
Recommended