Наиболее распространенные узкие места

Рубрика:

Представляем вашему вниманию наиболее общий список из наиболее распространенных узких мест в разработке, который предложил программный архитектор Рассел Салливан, специализирующийся на разработке in-memory хранилищах данных, гуру масштабирования и виртуализации.

Естественно с опытом, у каждого разработчика собирается свой собственный список узких мест, с которыми приходилось иметь дело, и чем с большим типом проектов вы будете заниматься, тем больше полезных уроков будете добавлять в этот общий список:

Базы данных:

  1. Рабочий размер превышает доступную RAM
  2. Длинные и  короткие рабочие запросы
  3. Конфликты по совпадению обращений для записи
  4. Массивные join'ы, занимающие память

Виртуализация:

  1. При совместном использовании HDD, отказ поиска на диске
  2. Колебания сетевого ввода-вывода в облаке

Программирование:

  1. Потоки: взаимные блокировки, слишком тяжелые по сравнению с событиями, отладка, нелинейная масштабируемость, и т.д...
  2. Событийно-управляемое программирование: сложность обратного вызова, как сохранить состояние в вызовах функции и т.д...
  3. Недостаточное профилирование, недостаточная трассировка, недостаточное логирование
  4. Одна часть не может масштабироваться, единая точка отказа (SPOF), не горизонтально масштабируемый, и т.д...
  5. Динамические приложения
  6. Плохой проект: разработчики создают приложение, которое хорошо работает на их компьютере. Приложение выходит в продакшн и хорошо работает у нескольких пользователей. Несколько месяцев/лет спустя, приложение не может работать с тысячами пользователей и должно поменять архитектуру и быть полностью переписано.
  7. Сложность алгоритма
  8. Зависимые сервисы, как поиски DNS, и любые другие, которые могут вас заблокировать.
  9. Стековое пространство

Диск:

  1. Локальный доступ к диску
  2. Случайный дисковый ввод-вывод -> поиск на диске
  3. Дисковая фрагментация
  4. Падение производительности SSD дисков, если записанные данные больше, чем размер SSD

ОС:

  1. Сбрасывание Fsync, заполнение буфера кэша Linux
  2. Слишком маленькие буферы TCP
  3. Ограничения дескриптора файлов
  4. Бюджет по питанию

Кэширование:

  1. Не используется memcached (убивается база данных)
  2. В HTTP: заголовки, завершающие теги, нет сжатия GZIP, и т.д.
  3. Не достаточно используется кэш браузера
  4. Кэши байтового кода (например, PHP)
  5. L1/L2 Кэши. Это - огромное узкое место. Храните важные данные в L1/L2. Это охватывает очень многое: мгновенный сетевой ввод/вывод, столбцовые базы данных выполняют алгоритмы непосредственно на сжатых данных, и т.д. Потом есть способы, сохраняющие ваш буфер быстрого преобразования адреса (TLB). Самая важная идея состоит в том, чтобы иметь твердое понимание архитектуры ЭВМ с точки зрения многоядерности  CPU, L1/L2, совместно используемого L3, NUMA RAM, пропускная способность/задержка передачи данных от DRAM до микросхемы, кэши DRAM DiskPages, DirtyPages, движение пакетов TCP через CPU<->DRAM<->NIC.

CPU:

  1. Перегрузка CPU
  2. Контекстные переключения приводят к чрезмерному количеству потоков на ядре, системных вызовов, и т.д...
  3. Ожидания ввода/вывода -> все ожидания CPU происходят с одной скоростью
  4. Кэши CPU: Кэширование данных является мелкомодульным процессом  для того, чтобы найти правильный баланс между наличием нескольких экземпляров с различными значениями для данных и тяжелой синхронизацией и сохранять кэшированные данные непротиворечивыми.
  5. Пропускная способность основной платы

Сеть:

  1. Выдыхается NIC, насыщение IRQ, мягкие прерывания занимающие 100% CPU
  2. Поиски DNS
  3. Пропущенные пакеты
  4. Неожиданные маршруты в сети
  5. Сетевой доступ к диску
  6. Совместно использованный SAN'ы
  7. Отказ сервера -> нет больше ответов от сервера

Процесс:

  1. Время тестирования
  2. Время разработки
  3. Размер команды
  4. Бюджет
  5. Нехватка кода

Память:

  1. Выход из строя памяти -> уничтожается процесс, используется файл подкачки, прекращается работа
  2. Выход из строя памяти, приводящий к перегрузке диска (связанной с подкачкой)
  3. Издержки памяти
  4. Фрагментация памяти
  • В Java требуются паузы GC
  • В C, вечно запускается malloc
Автор: 
Russell Sullivan