Как увеличить скорость скрипта tornado python?

В наличии вот такой код на python
работает одинаково, что 500 асинхронных запросов, что 15000
определяется переменной "process_max"
нужно увеличить скорость до максимума.
судя по скорости которую выдает статистика скорость там около 10-20 запросов конкурентных.

import tornado
from tornado import httpclient
from tornado import gen
from functools import partial
import Queue
from tornado.httpclient import AsyncHTTPClient
import os
from time import gmtime, strftime
import json
from urlparse import urlparse

gloop = tornado.ioloop.IOLoop.instance()
qinput = Queue.Queue()
process_count = 0

process_max = 15000    # maximum count of query for one moment

#create tmp dir if not exists
dirname = "tmp"
if not os.path.exists(dirname):
    os.makedirs(dirname)

#fill queue
f = open('100000_hostsList.lst')
line = f.readline()
items = 0
hosts = []
while line:
    qinput.put("http://"+line)
    line = f.readline()

f.close()


def data_process(data, url, headers):
    data = {'url': url, 'data': data, 'headers': headers}

    dirname = "tmp/" + strftime("%Y-%m-%d_%H", gmtime())
    if not os.path.exists(dirname):
        os.makedirs(dirname)

    f = file(dirname + "/" + urlparse(url).hostname, "w+")
    f.write(json.dumps(data))
    f.flush()
    f.close()

@gen.engine
def process(url):
    global process_count, worker
    try:
        http_client = httpclient.AsyncHTTPClient()

        request = tornado.httpclient.HTTPRequest(url=str(url), connect_timeout=5.0, request_timeout=5.0, follow_redirects=True)
        response = yield tornado.gen.Task(http_client.fetch, request)

        if response.error: raise Exception(response.error)
        data_process(response.body, url, dict(response.headers))
    except Exception as e:
        print e
    process_count -= 1
    gloop.add_callback(worker)

def worker():
    global gloop, process_count, process_max
    print '# %d / %d (%d)' % (process_count, process_max, qinput.qsize())
    while process_count < process_max:
        if qinput.empty(): break
        url = qinput.get_nowait()
        process_count += 1
        gloop.add_callback(partial(process, url))
    if qinput.empty():
        if not process_count: gloop.stop()

print 'start'
gloop.add_callback(worker)
tornado.httpclient.AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
gloop.start()
print 'finish'
  • Вопрос задан
  • 761 просмотр
Пригласить эксперта
Ответы на вопрос 5
@jkotkot
режим сарказма
Если у вас не 500 ядерный комп, то решение скорее всего заключается в том, чтобы ВНИМАНИЕ!! УМЕНЬШИТЬ число потоков. Если потоков сильно больше, чем ядер и они постоянно работают, то переключение между ними занимает время и ресурсы. Накладные расходы на переключение потоков никто не отменял.
Ответ написан
Neuroware
@Neuroware
Программист в свободное от работы время
Нужно смотреть по загрузке ресурсов хоста, вероятно производительность упирается в дисковые операции data_process.
Как вариант для проверки можно поднять RAM диск и писать на него, если получится выигрыш нужно как то избавляться от записи на диск.
Ответ написан
@766dt
Надо сделать асинхронной работу с диском, а не только http запросы.
Запись на диск может и так быть асинхронной для скрипта, и если это так, то возможно достаточно было бы убрать
f.flush()
f.close()

и управление в скрипт вернется сразу. Насколько вообще критично дожидаться записи на диск?
Также можно поискать библиотеки для асинхронного файлового I/O, или как вариант - использовать любую базу с асинхронным драйвером для питона.
Ответ написан
@lega
По сути там 4 вещи которые могут "тормозить": cpu, диск, сеть, сервера (откуда скачивается).

1) Посмотрите не загружено ли одно ядро на 100% (речь не про весь процессор), если есть 100% то нужно "форкать".
2) Отключите сохранение:
def data_process(data, url, headers):
    pass
Если при этом cpu < 100% а сеть не загружена по максимуму - значит (промежуточные) сервера отдают медленно.
Ответ написан
@rodion-dev Автор вопроса
все ядра 0%
ресурсы не используются вообще
речь не о потоках, а об асинхронных загрузках.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы