Ограничение скорости Google Cloud Tasks
Я пытаюсь ограничить число облачных задач Google не более чем одной обработанной задачей в секунду.
Я создал свою очередь с помощью:
gcloud tasks queues create my-queue \
--max-dispatches-per-second=1 \
--max-concurrent-dispatches=1 \
--max-attempts=2 \
--min-backoff=60s
Описание этого дает мне:
name: projects/my-project/locations/us-central1/queues/my-queue
rateLimits:
maxBurstSize: 10
maxConcurrentDispatches: 1
maxDispatchesPerSecond: 1.0
retryConfig:
maxAttempts: 2
maxBackoff: 3600s
maxDoublings: 16
minBackoff: 60s
state: RUNNING
После создания группы задач в журналах я вижу, что многие из них нежелательно обрабатываются в течение 1 секунды:
2019-07-27 02:37:48 default[20190727t043306] Received task with payload: {'id': 51}
2019-07-27 02:37:48 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 52}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 53}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 54}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 55}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 56}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 57}
2019-07-27 02:37:49 default[20190727t043306] "POST /my_handler HTTP/1.1" 200
2019-07-27 02:37:49 default[20190727t043306] Received task with payload: {'id': 58}
Как правильно заставить его запускать не более 1 задачи в течение этого 1-секундного интервала времени?
Обновление 30/06:
Я попробовал это снова с базовой настройкой, та же проблема.
Подробнее о настройке и процессе:
- Исходный код https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/flexible/tasks, без изменений
- Разверните app.yaml, а не app.f flex.yaml
- Запускать задачу несколько раз: python create_app_engine_queue_task.py --project = $ PROJECT_ID --queue = $ QUEUE_ID --location = $ LOCATION_ID --payload = привет
- Проверьте журналы: прочитайте журналы приложений gcloud
На этот раз им потребовалось некоторое время, чтобы начать обработку, но после этого кажется, что все они были обработаны более или менее одновременно:
Полные журналы:
2019-07-30 00:22:37 default[20190730t021951] [2019-07-30 00:22:37 +0000] [9] [INFO] Starting gunicorn 19.9.0
2019-07-30 00:22:37 default[20190730t021951] [2019-07-30 00:22:37 +0000] [9] [INFO] Listening at: http://0.0.0.0:8081 (9)
2019-07-30 00:22:37 default[20190730t021951] [2019-07-30 00:22:37 +0000] [9] [INFO] Using worker: threads
2019-07-30 00:22:37 default[20190730t021951] [2019-07-30 00:22:37 +0000] [23] [INFO] Booting worker with pid: 23
2019-07-30 00:22:37 default[20190730t021951] [2019-07-30 00:22:37 +0000] [26] [INFO] Booting worker with pid: 26
2019-07-30 00:27:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:27:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:27:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:27:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:41 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:41 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:42 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:42 default[20190730t021951] Received task with payload: hello
2019-07-30 00:37:43 default[20190730t021951] "POST /example_task_handler HTTP/1.1" 200
2019-07-30 00:37:43 default[20190730t021951] Received task with payload: hello
Ответы
Ответ 1
tl;dr Это, вероятно, работает как задумано. Вы можете ожидать начальный пакет задач maxBurstSize
, который затем замедлится до maxDispatchesPerSecond
.
Причиной этого является алгоритм "Token Bucket": есть корзина, которая может содержать не более maxBurstSize
токенов и изначально содержит столько токенов. Задача отправляется, если наступило запланированное время, и в ведре есть жетон И в полете находится меньше, чем maxConcurrentDispatches
, в противном случае мы ожидаем выполнения этих условий. Когда задача отправляется, токен удаляется из корзины. Когда корзина не заполнена, токены добавляются со скоростью maxDispatchesPerSecond
.
Таким образом, скорость не является точным ограничением для отправки задач. Задачи можно отправлять с произвольной скоростью, если в корзине есть токены и задачи готовы к запуску. Только когда задачи должны ждать токенов, мы должны замедляться до заданной скорости. Так как ведро начинает заполняться, вы можете получить начальный выброс.
В API и консоли Cloud Tasks размер сегмента доступен только для чтения (и API вызывает его max_burst_size
). Но используя более старую конфигурацию queue.yaml
, вы можете контролировать размер сегмента вместе с другими параметрами, например,
queue:
- name: my-appengine-queue
rate: 2/s
bucket_size: 20
max_concurrent_requests: 5
Тогда gcloud app deploy queue.yaml
. Однако, если вы сделаете это, помните об этих подводных камнях: https://cloud.google.com/tasks/docs/queue-yaml#pitfalls
К вашему сведению, есть проблема, чтобы увидеть, можно ли улучшить документацию.