Слишком много открытых файлов с менеджером. Список - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь использовать многопроцессорную обработку для ускорения моего синтаксического анализатора в AWS Lambda Python.

Он отлично работает локально, но когда я пробую его на лямбду, появляется ошибка, указанная ниже. Почему я получаю эту ошибку и как ее исправить?

 {   "errorMessage": "[Errno 24] Too many open files",   "errorType":
 "OSError",   "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 64, in lambda_handler\n    p.start()\n",
     "  File \"/var/lang/lib/python3.7/multiprocessing/process.py\", line 112, in start\n    self._popen = self._Popen(self)\n",
     "  File \"/var/lang/lib/python3.7/multiprocessing/context.py\", line 223, in _Popen\n    return
 _default_context.get_context().Process._Popen(process_obj)\n",
     "  File \"/var/lang/lib/python3.7/multiprocessing/context.py\", line 277, in _Popen\n    return Popen(process_obj)\n",
     "  File \"/var/lang/lib/python3.7/multiprocessing/popen_fork.py\", line 20, in __init__\n    self._launch(process_obj)\n",
     "  File \"/var/lang/lib/python3.7/multiprocessing/popen_fork.py\", line 69, in _launch\n    parent_r, child_w = os.pipe()\n"   ] }

Мой код выглядит так:

def parse(item, L):
    r = requests.get(item[0], headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3'},
                     cookies={'name': 'Parser',
                              'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'})
    if (r.status_code == 200):
        if item[1] not in L:
            L.append([r.text, r.status_code, item[1]])
    else:
        L.append([None, r.status_code, item[1]])

def lambda_handler(event, context):
    # Make DB Connection

    with Manager() as manager:
        L = manager.list()  # <-- can be shared between processes.
        processes = []

        for item in sqlSelectVars:
            p = multiprocessing.Process(target=parse, args=(item, L))
            processes.append(p)
            p.start()

        for process in processes:
            process.join()

        # Commit my parsed values to the DB with PyMySQL
        try:
            cursor.executemany(sqlUpdateRawHtml, L)
            cursor.connection.commit()

1 Ответ

0 голосов
/ 08 ноября 2019

Просто по вашему описанию. Я думаю, причина в том, что вы создаете слишком много процессов .

Из документации Lambda Лямбда-ограничения AWS мы можем получить:

Файловые дескрипторы: 1,024

Процессы выполнения / потоки: 1,024

Таким образом, эту часть необходимо изменить:

        for item in sqlSelectVars:
            p = multiprocessing.Process(target=parse, args=(item, L))

С другой стороны, вы хотите«использовать многопроцессорность, чтобы ускорить мой анализатор». На самом деле, если вы просто вычисляете в parse, слишком много процессов бесполезны. Вместо этого при создании процесса возникают дополнительные издержки.

...