Nano Hash - криптовалюты, майнинг, программирование

Асинхронный пул соединений в Tornado с несколькими процессами

Я использую библиотеки Tornado 4.2.1 и tornadoes 2.4.1 для запросов к своей базе данных Elasticsearch и ищу способ инициализировать пул соединения для совместного использования несколькими экземплярами RequestHandler в службе с несколькими процессами.

Возможно ли это сделать? Существуют ли специальные библиотеки для Tornado?

заранее спасибо


Ответы:


1

Поскольку tornado-es — это всего лишь HTTP-клиент, он использует AsyncHTTPClient. в ESConnection. Новое TCP-соединение устанавливается при каждом запросе, если не указан заголовок Connection: keep-alive.

conn = ESConnection()
conn.httprequest_kwargs['headers'] = {'Connection': 'keep-alive'}

Я не проверял, но должно работать. Я использовал аналогичную настройку в ruby ​​(с http-клиентом patron), и он работает хорошо.

Следующее

AsyncHTTPClient имеет ограничение на максимальное количество одновременных запросов (fetch) на ioloop. Каждый запрос, достигший предела, просто ставится в очередь внутри.

Вы можете увеличить глобальный лимит:

AsyncHTTPClient.configure(None, max_clients=50)

или отделить клиента своим лимитом (force_instance):

from tornadoes import ESConnection
from tornado.httpclient import AsyncHTTPClient

class CustomESConnection(ESConnection):

    def __init__(self, , host='localhost', port='9200', io_loop=None, protocol='http', max_clients=20):
        super(CustomESConnection, self).__init__(host, port, io_loop, protocol)
        self.client = AsyncHTTPClient(force_instance=True, max_clients=max_clients)

И наконец

Чтобы повторно использовать один и тот же ESConnection, вы можете создать его в приложении, поскольку приложение доступно для каждого запроса (RequestHandler).

from tornado.web import Application, RequestHandler
from tornadoes import ESConnection

class MainHandler(RequestHandler):
    def get(self):
        yield self.application.es.search('something')


class MyApp(Application):

    def __init__(self, *args, **kwargs):
        super(MyApp, self).__init__(*args, **kwargs)

        self.es = ESconnection()

if __name__ == "__main__":
    application = MyApp([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    tornado.ioloop.IOLoop.current().start()

Многопроцессорность

На самом деле нет простого пути. Распространенным подходом является пулер, который используется в основном, когда требуется постоянное соединение, например базы данных (pgbouncer для postgres) или как оптимизация на высоконагруженном сервисе.

И вам придется написать пулер, приложение-шлюз к es

subprocess1 
           \  (http, zmq, ...)
            \            
              > pooler (some queue and tornadoes api) - http -> elastisearch
            /
           /
subprocess2

Подпроцессы могут связываться с пулером через HTTP, ØMQ (есть много примеров, даже пулер) или некоторая реализация IPC (сокеты, .. .).

07.03.2016
  • Привет @kwarunek и большое спасибо за ваш ответ. Я полностью понимаю, что вы сказали, и это работает идеально. Единственное, чего я не понимаю, это возможно ли использовать его с несколькими подпроцессами. Внутри моего основного я реализовал механизм, в котором я получаю из командной строки, сколько подпроцессов нужно запустить, таким образом: http_server = tornado.httpserver.HTTPServer(MyApp) http_server.bind(8888) http_server.start(tornado.options.options.processes) tornado.ioloop.IOLoop.current().start() Возможно ли использовать ваш пример в нескольких подпроцессах? 07.03.2016
  • Я попытался запустить свой Tornado с двумя подпроцессами и получил эту ошибку: RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes(). 07.03.2016
  • Я добавил примечание о многопроцессорности. 07.03.2016
  • И ошибка времени выполнения вызвана, вероятно, тем, что создание AsyncHTTPClient перед разветвлением, как в stackoverflow. ком/вопросы/22641015/ 07.03.2016
  • Большое спасибо @kwarunek, это прекрасно! 08.03.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..