Большие сайты и магазины на базе WordPress/WooCommerce

Цель статьи — показать, как спроектировать и запустить сайт или магазин с сотнями тысяч и миллионами записей.

1. Когда нужен «большой» стек

Признаки:

  • Каталог от 100k до 5M товаров или записей
  • Фасетные фильтры и быстрый поиск
  • Пики трафика (распродажи, инфоповоды)
  • Много интеграций (ERP, CRM, BI, маркетплейсы)

Цели по метрикам (ориентиры):

  • p95 поискового запроса ≤ 200 мс
  • p95 PLP (страница списка) ≤ 300 мс
  • Лаг индексации после изменения цены/стока < 5 минут

2. Базовые принципы архитектуры

  • Разделение чтения и записи
    • Запись: админка, импорт, вебхуки
    • Чтение: витрина, поиск, каталог, публичные API
  • Headless‑подход
    • Витрина: Next.js/Nuxt с SSG/ISR
    • WordPress: CMS и REST API
  • Внешний поиск и фасетки
    • Elasticsearch или Manticore (self‑hosted), Algolia (SaaS)
  • Асинхронная обработка
    • Очереди для импорта, переиндексации, писем, интеграций
  • Кэширование на всех слоях
    • Redis object cache, CDN/edge‑cache, microcache на веб‑сервере

Схема запросов: Браузер → CDN/Edge → Фронт → API → БД/Кэш → Поисковый индекс → Очереди.


3. Хранилище и база данных

  • MySQL/MariaDB (InnoDB), отдельные диски под данные и журналы, NVMe
  • Минимально необходимые индексы. Не индексируйте всё подряд
  • Реплика БД для чтения. Основной узел — для записи
  • WooCommerce: включить HPOS (High‑Performance Order Storage)
  • Массовые изменения — пакетами и в окно обслуживания

Настройки по умолчанию (ориентиры):

  • innodb_buffer_pool_size ≈ 50–70% RAM
  • Медленные запросы включены, алерты по p95
  • Мониторинг лага репликации

4. Импорт и поток данных

Инструменты: WP‑CLI, Action Scheduler, WP All Import, собственные воркеры.

Очереди: Redis Streams, RabbitMQ или SQS. Обязательно ретраи и DLQ.

Процесс:

  1. Получение источника (CSV/JSON/вебхук)
  2. Разбиение на чанки по 1–5k записей
  3. Постановка задач в очередь
  4. Воркеры записывают в БД (идемпотентно: внешний_id → post_id)
  5. Событие на переиндексацию
  6. Контрольные метрики и отчёт по ошибкам

Пример команд:

# Поставить импорт в очередь
wp bigdata:enqueue-import --file=products.csv --chunk=2000

# Запустить воркеры
wp bigdata:worker run --concurrency=4

Псевдокод воркера:

function handle_chunk(array $rows) {
  foreach ($rows as $row) {
    $pid = upsert_product($row); // идемпотентно
    dispatch_to_indexer($pid);   // обновить индекс
  }
}

5. Поиск и фасеты

Зачем выносить поиск:

  • LIKE и сложные JOIN по postmeta плохо масштабируются
  • Внешний индекс даёт быстрые агрегаты, сортировки и курсорную пагинацию

Подходы:

  • Elasticsearch: агрегаты, сортировки, горизонтальное масштабирование
  • Manticore: лёгкий self‑hosted, хорошая морфология для RU, RT‑индексы
  • Algolia: SaaS, простой старт, оплата за запросы

Минимальная схема документа:

{
  "id": 123,
  "slug": "nike-air-max-270",
  "title": "Nike Air Max 270",
  "brand": "Nike",
  "price": 129.90,
  "currency": "USD",
  "availability": "in_stock",
  "rating": 4.6,
  "attributes": {"color": ["black", "white"], "size": ["40", "41"]},
  "popularity": 0.87,
  "updated_at": "2025-10-05T12:01:00Z"
}

Рекомендации:

  • Храните предрассчитанные поля для сортировок и фасеток
  • Для глубокой пагинации используйте cursor/search_after
  • Обновляйте индекс триггерами на сохранение и ночными батчами

6. Витрина (PLP/PDP)

  • PLP получает результаты и агрегаты из поискового индекса
  • Пагинация без OFFSET. Используйте курсоры
  • Edge‑кэш популярных фильтров. Инвалидация по тегам
  • PDP может быть гибридной (часть данных из БД, часть — из индекса)

7. API‑слой

  • WordPress REST API и WooCommerce REST
  • Отдавайте только нужные поля, используйте ETag/If‑None‑Match
  • Кастомные эндпоинты для пакетных операций
  • Альтернатива: WPGraphQL, кэширование резолверов
  • Защита: rate‑limiting, подписи запросов, WAF

Пример кастомного эндпоинта:

add_action('rest_api_init', function () {
  register_rest_route('bigdata/v1', '/products/bulk', [
    'methods' => 'GET',
    'callback' => 'get_bulk_products',
    'args' => ['page' => ['default' => 1]],
  ]);
});
function get_bulk_products($request) {
  $args = ['post_type' => 'product', 'posts_per_page' => 1000, 'paged' => $request['page']];
  return rest_ensure_response(get_posts($args));
}

8. Производительность и наблюдаемость

Кэш:

  • Redis object cache
  • CDN/edge cache
  • Microcache на Nginx/LiteSpeed

Нагрузочное тестирование:

  • k6, Locust или JMeter
  • Профили: поиск с фасетками, распродажа, массовые импорты

Наблюдаемость:

  • Метрики: p50/p95/p99 по ключевым маршрутам, error rate, лаги очередей и репликации
  • Трейсинг: OpenTelemetry + бэкенд (Jaeger/Tempo)
  • Логи: медленные запросы MySQL, ошибки PHP, воркеры

9. Безопасность и бэкапы

  • Инкрементные бэкапы БД и файлов
  • Проверка восстановления по расписанию
  • Хранение секретов в Vault/Parameter Store
  • Ограничение и аудит доступа к админке и API

10. Типовые проблемы и решения

  • Медленный поиск на MySQL Решение: внешний индекс, пред‑агрегации
  • Частые инвалидации кэша Решение: теговая инвалидация, иерархическое ключевание, разные TTL
  • Рост wp_postmeta Решение: вывод фасеток в индекс, очистка неиспользуемых мета, HPOS
  • Долгие массовые UPDATE Решение: батчи, очереди, окна обслуживания, миграции с откатами

11. Контрольные списки

База данных:

  • [ ] innodb_buffer_pool_size настроен
  • [ ] Реплика для чтения
  • [ ] Медленные запросы и алерты включены

Поиск:

  • [ ] Индекс содержит поля для сортировок и фасеток
  • [ ] Инкрементальные обновления и ночные батчи
  • [ ] Пагинация курсором/search_after

Витрина:

  • [ ] Edge‑кэш и теговая инвалидация
  • [ ] PLP без OFFSET
  • [ ] Критические ресурсы прелоадятся

Импорт:

  • [ ] Очереди, ретраи, DLQ
  • [ ] Идемпотентность (внешний_id → post_id)
  • [ ] Мониторинг ошибок и отчёты

Наблюдаемость:

  • [ ] Дашборды p95 PLP/поиск
  • [ ] Лаг репликации и лаг индексации
  • [ ] Алерты на рост 5xx и рост очередей

12. Пошаговая миграция к «большой» архитектуре

  1. Подключить Redis object cache и CDN
  2. Включить HPOS (WooCommerce)
  3. Внедрить внешний поиск на часть маршрутов (canary)
  4. Перевести импорт на очереди и батчи
  5. Вынести PLP в headless‑витрину, PDP оставить гибридно
  6. Добавить метрики, трассировку, алерты
  7. Прогнать нагрузочные сценарии и скорректировать лимиты

13. Итог

Ключевые опоры «большого» проекта на WordPress/WooCommerce:

  • База данных хранит факты. Поиск и фасеты — во внешнем индексе
  • Запись и интеграции — асинхронно через очереди
  • Чтение — через кэш и CDN
  • Производительность и стабильность — через метрики, трассировку и алерты

Такой подход масштабируется до миллионов единиц контента и выдерживает пики нагрузки с предсказуемыми SLA.

Фото аватара

Antony I

Веб разработчик, специализация на лучших мировых практиках: WordPress, WooCommerce, NextJS, Strapi, JAMStack ...

Основные типы проектов: CMS, eCommerce, SEO, LMS, ECM, BPM

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *