Перейти к содержанию

Руководство по производительности

Цель этого руководства — помочь пользователям и администраторам эффективно использовать InfraVision. Оно содержит различные рекомендации и лучшие практики, собранные за время использования, и предназначено для широкого спектра сценариев применения.

Конфигурация сервера

Конфигурация InfraVision

InfraVision поставляется с разумной конфигурацией по умолчанию для большинства окружений, но администраторам рекомендуется изучить все доступные параметры для тонкой настройки своей установки. Ниже выделены некоторые наиболее значимые параметры, влияющие на производительность.

Уменьшите максимальный размер страницы

InfraVision разбивает большие наборы результатов на страницы для уменьшения общего размера ответа. Параметр MAX_PAGE_SIZE указывает максимальное количество результатов на странице, которое может запросить клиент. По умолчанию установлено значение 1000. Рассмотрите уменьшение этого числа, если вы обнаружите, что API-клиенты часто запрашивают очень большие наборы результатов.

Ограничьте количество алиасов GraphQL

По умолчанию InfraVision ограничивает GraphQL-запрос 10 алиасами. Рассмотрите уменьшение этого числа, установив GRAPHQL_MAX_ALIASES на более низкое значение.

Обозначьте изолированные развёртывания

Если ваша установка InfraVision не имеет доступа в Интернет, установите ISOLATED_DEPLOYMENT в True. Это предотвратит попытки приложения выполнять рутинные внешние запросы.

Уменьшите частоту выборки Sentry

Если Sentry включён для отчётов об ошибках и аналитики, рассмотрите снижение частоты выборки. Это можно сделать, изменив значения sample_rate и traces_sample_rate в SENTRY_CONFIG.

Удалите ненужные обработчики событий

Проверьте, были ли добавлены пользовательские обработчики событий в EVENTS_PIPELINE. Удалите те, которые больше не нужны.

Фоновые воркеры задач

InfraVision откладывает выполнение определённых задач на фоновые воркеры через очереди Redis, обслуживаемые одним или несколькими фоновыми воркерами. Эти воркеры работают асинхронно от фронтенд WSGI-воркеров и обрабатывают задачи в порядке их поступления в очередь.

InfraVision создаёт три очереди по умолчанию для фоновых задач: high, default и low. Дополнительные очереди можно настроить через параметр конфигурации QUEUE_MAPPINGS.

По умолчанию фоновый воркер (запускаемый через manage.py rqworker) будет прослушивать все доступные очереди. Для улучшения отзывчивости на высокоприоритетные фоновые задачи рассмотрите выделение одного или нескольких воркеров для обслуживания только очереди high:

$ ./manage.py rqworker high
19:31:20 Worker 861be45b32214afc95c235beeb19c9fa: started with PID 2300029, version 2.6.0
19:31:20 Worker 861be45b32214afc95c235beeb19c9fa: subscribing to channel rq:pubsub:861be45b32214afc95c235beeb19c9fa
19:31:20 *** Listening on high...
19:31:20 Worker 861be45b32214afc95c235beeb19c9fa: cleaning registries for queue: high
19:31:20 Scheduler for high started with PID 2300096

API-клиенты

REST API

REST API InfraVision является основным средством интеграции с внешними системами, позволяя выполнять полные операции создания, чтения, обновления и удаления (CRUD). При работе с очень большими наборами данных следует учитывать несколько соображений по производительности.

Используйте «краткий» режим для простых списков

В случаях, когда вам нужно получить только минимальное представление объектов, добавьте ?brief=True к URL. Это инструктирует InfraVision опустить все поля, кроме следующих:

  • ID
  • URL
  • Отображаемый текст
  • Имя (или аналогичный идентификатор)
  • Slug (если присутствует)
  • Описание
  • Количество значимых связанных объектов (где применимо)

Например, площадка, запрошенная в кратком режиме, возвращает только следующее:

{
    "id": 2,
    "url": "https://{infravision}/api/dcim/sites/2/",
    "display": "DM-Akron",
    "name": "DM-Akron",
    "slug": "dm-akron",
    "description": ""
}

Опущение всех остальных полей (особенно тех, которые извлекают и возвращают связанные объекты) часто приводит к значительно более быстрым запросам.

Объявите выбранные поля

Если вам нужна большая гибкость в отношении полей, возвращаемых для типа объекта, вы можете указать список полей для включения, используя параметр запроса fields. Например, запрос /api/dcim/sites/?fields=id,name,status,region вернёт следующее:

{
    "id": 2,
    "name": "DM-Akron",
    "status": {
        "value": "active",
        "label": "Active"
    },
    "region": {
        "id": 51,
        "url": "https://{infravision}/api/dcim/regions/51/",
        "display": "Ohio",
        "name": "Ohio",
        "slug": "us-oh",
        "description": "",
        "site_count": 0,
        "_depth": 2
    }
}

Как и краткий режим, этот подход может значительно сократить время ответа API-запроса, опуская ненужные данные.

Применяйте пагинацию

Как и пользовательский интерфейс, REST API использует пагинацию для ограничения количества объектов, возвращаемых в одном ответе. Если размер страницы не указан в запросе (т.е. путём передачи ?limit=10), InfraVision будет использовать размер по умолчанию, определённый в PAGINATE_COUNT. Размер страницы по умолчанию — 50.

Для некоторых запросов, особенно использующих краткий режим или минимальный набор полей, может быть желательно указать больший размер страницы, чтобы потребовалось меньше запросов для получения всех объектов. Добавление ?limit=0 к запросу фактически пытается отключить пагинацию. (Однако обратите внимание, что запрошенный размер страницы не может превышать значение MAX_PAGE_SIZE, которое по умолчанию равно 1000.)

Сложные API-запросы, которые извлекают много связанных объектов, создают относительно высокую нагрузку на приложение и, как правило, выигрывают от уменьшенного размера страницы. Если вы обнаружите, что ваши API-запросы занимают чрезмерно много времени, попробуйте уменьшить размер страницы от значения по умолчанию, чтобы меньше объектов нужно было возвращать для каждого запроса.

GraphQL API

GraphQL API InfraVision, доступный только для чтения, предлагает альтернативу REST API и обеспечивает очень гибкий способ получения данных. GraphQL позволяет клиенту запрашивать любой объект из единой конечной точки, указывая только нужные атрибуты и связи. Многие пользователи предпочитают это более жёсткой структуре REST API, но важно понимать компромиссы при составлении сложных запросов.

Запрашивайте только необходимые поля

Для оптимальной производительности составляйте GraphQL-запросы так, чтобы возвращались только поля, необходимые клиенту. Это сократит общее время запроса, особенно при опущении связанных объектов.

Избегайте чрезмерно сложных запросов

Основное преимущество GraphQL API в том, что он позволяет клиенту переложить на сервер работу по объединению различных связанных объектов, что потребовало бы от клиента выполнения нескольких запросов к разным конечным точкам при использовании REST API. Однако это преимущество не даётся бесплатно: чем больше информации запрашивается в одном запросе, тем больше работы серверу нужно выполнить для извлечения сырых данных из базы данных и отрисовки их в GraphQL-ответ. Очень сложные запросы могут порождать десятки или сотни SQL-запросов на бэкенде, что увеличивает время отрисовки ответа.

Хотя может быть заманчиво упаковать как можно больше данных в один GraphQL-запрос, осознайте, что необходимо соблюдать баланс между минимизацией количества запросов и избеганием сложности в интересах производительности. Например, хотя можно получить через один GraphQL API-запрос все IP-адреса и все подключённые кабели для каждого устройства на площадке, вероятно, более эффективно (часто намного более эффективно) сделать два или три отдельных запроса и скоррелировать данные локально.

Используйте фильтры

Вы можете указать фильтры при выполнении GraphQL-запроса для ограничения набора возвращаемых объектов. Это работает немного иначе, чем REST API, поскольку фильтры объявляются внутри оператора запроса, а не добавляются к URL, но концепция та же. Например, чтобы вернуть только активные площадки:

query {
  site_list(
    filters: {
      status: STATUS_ACTIVE
    }
  ) {
    name
  }
}

Это возвращает только площадки со статусом «active» и позволяет избежать необходимости разбора всех остальных. Для получения дополнительной информации о фильтрах см. документацию GraphQL API.

Применяйте пагинацию

Как и REST API, GraphQL API поддерживает пагинацию. Запросы, возвращающие большое количество объектов, должны использовать пагинацию для ограничения размера каждого ответа.

{
  device_list(
    pagination: {limit: 100}
  ) {
    id
    name
    serial
    status
  }
}