Стратегии получения полного содержимого всех сущностей списка #113
leshchenko1979
started this conversation in
Show and tell
Replies: 2 comments 1 reply
-
Для простоты восприятия: def chunks(iterable: list, chunk_size: int):
for i in range(0, len(iterable), chunk_size):
yield iterable[i:i + chunk_size]
crm = Bitrix(cc_hook, verbose=True)
start = datetime.now()
ids: List[dict] = crm.get_all(
'crm.lead.list',
params={
'select': ['ID']
}
)
leads = []
for ids_part in chunks(ids, 3000):
leads += crm.call('crm.lead.get', ids_part)
print(datetime.now() - start)
# 100%|██████████| 35368/35368 [00:02<00:00, 13752.49it/s]
# 100%|██████████| 3000/3000 [00:02<00:00, 1081.50it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 953.55it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 998.85it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 916.89it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 968.68it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 981.23it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 959.37it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 949.15it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 900.92it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 957.12it/s]
# 100%|██████████| 3000/3000 [00:03<00:00, 933.36it/s]
# 100%|██████████| 2368/2368 [00:02<00:00, 878.51it/s]
# 0:00:40.560666 |
Beta Was this translation helpful? Give feedback.
1 reply
-
См. также неудачную попытку перейти на новую стратегию выборки: #191 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Нередко при работе с Bitrix24 REST API возникает необходимость быстро получить содержимое определенных полей всех элементов какого-то списка (например, лидов). Традиционный способ для этого - обращение к серверу через метод
*.list
(например,crm.lead.list
для лидов) с параметромselect
, перечисляющим список требуемых полей. Однако в силу того, что информация сервером выдается постранично, существует несколько стратегий для того, чтобы получить весь список.Стратегии
Ниже мы описываем три стратегии, которые мы условно назвали "ID filter", "Start increment' и "List + get".
Первые две стратегии ("ID filter" и "Start increment") предложены в официальной документации Битрикс24: https://dev.1c-bitrix.ru/rest_help/rest_sum/start.php.
ID filter
Запросы отправляются к серверу последовательно с параметром
"order": {"ID": "ASC"}
(сортировка по возрастанию ID), и в каждом последующем запросе используются результаты предыдущего (фильтрация по ID, где ID > максимального ID в результатах предыдущего запроса).При этом для ускорения используется параметр
start = -1
для отключения затратной по времени операции расчета общего количества записей (полеtotal
), которое по умолчанию возвращается в каждом ответе сервера при вызове методов вида*.list
.В потенциале для ускорения можно попытаться параллельно передвигаться по списку сущностей в два потока: с начала списка и с конца, продолжая получать страницы, пока ID в двух потоках не пересекутся. Такой способ, возможно, будет давать двукратное ускорение до тех пор, пока не будет исчерпан пул запросов к серверу и не потребуется включить throttling.
Start increment
Стратегия, при которой перебираются страницы путем увеличения параметра
start
, который является средством позиционирования курсора для получения следующей страницы.Если перед нами стоит цель получить полный набор сущностей, то, в отличие от предыдущей стратегии, эта хорошо поддается ускорению (несмотря на то, что она требует использования параметра
start
, что замедляет работу сервера).После того, как мы получили первую страницу и увидели в ней общее количество элементов (поле
total
), то дальнейшее ускорение запросов можно получить двумя нижеописанными способами.Объединение запросов в батчи
Зная общее количество элементов, можно сразу создать запросы на все страницы и объединить их в батчи. (Битрикс поддерживает батчи в 50 запросов.) Использование батчей позволяет обойти ограничения на максимальную скорость запросов, так как один батч считается за один запрос при учете сервером количества получаемых запросов.
Параллельная отправка батчей к серверу
Примеры кода в официальной документации Битрикс24 REST API везде предлагают последовательную отправку запросов и описывают лишь ограничения на скорость отправки запросов. Но параллельная отправка запросов возможна и позволяет сильно ускорить обмен информацией с сервером.
Впрочем, таким образом достаточно просто перегрузить сервер, который даже при соблюдении скорости запросов начинает обрывать соединение и уходить в таймауты. Поэтому такой подход требует нахождения пределов нагрузки на сервер экспериментальным способом.
Именно такая стратегия сейчас заложена в метод
get_all()
в библиотекеfast_bitrix24
.List + get
Составная стратегия, при которой при помощи стратегии "Start increment" от сервера получается сначала список всех ID по методу
*.list
, а потом через метод*.get
получается содержимое сущностей для каждого ID. При этом в обоих шагах используются описанные выше способы ускорения "Объединение запросов в батчи" и "Параллельная отправка батчей".Тест
Чтобы проверить эффективность этих стратегий, мы провели тест (код теста: https://gist.github.com/leshchenko1979/970ebad4006221633b7201bce2b1ee2c).
Тест запрашивает страницы лидов (метод
crm.lead.list
) через 3 вышеописанные стратегии (при этом стратегия "ID filter" реализована в один поток - с начала списка ID). Для каждой стратегии запрашиваются 1, 50, 100 и 200 страниц и замеряется время выполнения запроса.Тест использует библиотеку fast_bitrix24 для автоматического контроля скорости запросов к серверу Битрикс24.
Тест проводим на 7-й версии REST API на списке в ~35000 лидов .
Результаты теста
Вывод
Стратегия "list + get" оказалась самой продуктивной. К сожалению, самостоятельная реализация такой стратегии требует от пользователя владения навыками написания асинхронного кода, а также построения инфраструктуры контроля скорости запросов к серверу Битрикс24.
Я не уверен в существовании подобных высокоуровневых библиотек для PHP, но для Python существует
fast_bitrix24
, который позволяет выгружать списки сущностей Битрикс24 со скоростью до тысяч элементов в секунду.Beta Was this translation helpful? Give feedback.
All reactions