Висока завантаженість процесора, але низька середня завантаженість


28

Ми стикаємося з дивною поведінкою, коли ми бачимо високу ефективність використання процесора, але досить низьку середню завантаженість.

Поведінка найкраще проілюстрована наступними графіками нашої системи моніторингу.

Використання процесора та завантаження

Близько 11:57 використання процесора збільшується від 25% до 75%. Середня навантаження істотно не змінюється.

Ми запускаємо сервери з 12 ядрами по 2 гіперпотоки кожен. ОС розглядає це як 24 процесора.

Дані щодо використання процесора збираються /usr/bin/mpstat 60 1щомісяця. Дані для allрядка та %usrстовпця показані на діаграмі вище. Я впевнений, що це показує середнє значення даних на процесор, а не "складене" використання. Хоча ми бачимо 75% використання в діаграмі, ми бачимо процес, який демонструє використання близько 2000% "складених" процесорів в top.

Середня цифра навантаження приймається з /proc/loadavgкожної хвилини.

uname -a дає:

Linux ab04 2.6.32-279.el6.x86_64 #1 SMP Wed Jun 13 18:24:36 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux

Linux dist є Red Hat Enterprise Linux Server release 6.3 (Santiago)

Ми запускаємо пару веб-додатків Java під досить великим навантаженням на машини, подумайте 100 запитів / с на машину.

Якщо я правильно інтерпретую дані використання CPU, коли ми використовуємо 75% процесора, це означає, що наші процесори виконують процес в середньому 75% часу. Однак, якщо наші процесори зайняті 75% часу, чи не слід бачити вищу середню завантаженість? Як процесори можуть бути на 75% зайняті, поки у нас у черзі запуску лише 2-4 завдання?

Чи правильно ми інтерпретуємо наші дані? Що може спричинити таку поведінку?


Чи відображається система моніторингу нормалізованого завантаження процесора (load / #CPU)? Регулярне завантаження процесора Linux важко порівняти в системах з різними числами core / cpu, тому деякі інструменти використовують замість цього нормоване завантаження.
Брайан

Ви маєте на увазі поділ кожної точки даних на кількість процесорів? Тобто loadavg / 24 в нашому випадку? Я легко можу створити таку діаграму з даних, якщо це допоможе.
К Ерландссон

Я припускав, що ваша діаграма вже може це показувати.
Брайан

Ах, вибачте за те, що вас не зрозуміли. Це було б приємне пояснення, але, на жаль, показано середнє навантаження на всю систему. Я тільки потрійно перевірив.
K Ерландссон

Відповіді:


51

Щонайменше, у Linux середня завантаженість та використання процесора - це фактично дві різні речі. Середня завантаженість - це вимірювання того, скільки завдань чекає в черзі запуску ядра (не лише час процесора, але й активність диска) протягом певного часу. Використання процесора - це міра того, наскільки зайнятий процесор зараз. Найбільше навантаження, яку одна нитка процесора, прив’язана до 100% за одну хвилину, може "сприяти" середньому за 1 хвилину завантаження - 1. 4-ядерний процесор із гіперточенням (8 віртуальних ядер), на 100% за 1 хвилину, сприяв би 8 середня завантаженість за 1 хвилину

Часто ці два числа мають шаблони, які співвідносяться між собою, але ви не можете вважати їх однаковими. Ви можете мати високе навантаження при майже 0% використання процесора (наприклад, коли у вас багато даних IO застрягло в стані очікування), і ви можете мати завантаження 1 і 100% процесора, коли у вас є один процес з потоком потоків. повний нахил. Також за короткий проміжок часу ви можете бачити процесор на рівні майже 100%, але навантаження все ще нижче 1, оскільки середні показники ще не "наздогнали".

Я бачив, що сервер завантажує понад 15 000 (так, це справді не помилка) і CPU% близько 0%. Це сталося тому, що на акції Samba виникли проблеми, і багато-багато клієнтів почали застрявати в стані очікування IO. Швидше за все, якщо ви бачите звичайний номер із великим завантаженням без відповідної активності процесора, у вас виникає проблема зберігання. На віртуальних машинах це також може означати, що на цьому ж хості VM конкурентоспроможні ресурси, які сильно конкурують.

Високе навантаження також не обов'язково погана річ, більшість часу це просто означає, що система використовується на повну потужність або, можливо, виходить за рамки її можливостей не відставати (якщо кількість навантаження вище, ніж кількість ядер процесора). У місці, де я був сисадміном, у них був хтось, хто спостерігав за середнім навантаженням у своїй основній системі ближче, ніж це робив Нагіос. Коли навантаження велика, вони зателефонували б мені на 24/7 швидше, ніж можна сказати SMTP. Більшість випадків насправді нічого не було, але вони пов'язували номер навантаження з тим, що щось не було, і спостерігали за цим, як яструб. Після перевірки, моя відповідь була, як правило, система просто виконує свою роботу. Звичайно, це було те саме місце, де навантаження піднімалося понад 15000 (не той самий сервер), тому іноді це означає, що щось не так. Ви повинні врахувати призначення вашої системи. Якщо це робочий коник, то очікуйте, що навантаження буде природно високою.


Як ви маєте на увазі, що я можу мати 1 і 100% процесора за допомогою одного потокового процесу? Про які нитки ви говорите? Якщо ми розглянемо наші процеси Java, у них є багато ниток, але я був припущений, що потоки розглядаються як процеси з точки зору ОС (зрештою, вони мають окремі PID-адреси в Linux). Чи може бути так, що один багатопотоковий Java-процес вважається лише одним завданням із точки зору середнього навантаження?
К Ерландссон

Я щойно робив тест самостійно, потоки в процесі Java сприяють середньому навантаженню, як якщо б вони виконували окремі процеси (тобто клас java, який виконує 10 потоків у циклі зайнятого очікування, дає мені наближення до 10). Буду вдячний за роз'ясненням про процес різьблення, який ви згадали вище. Дякую!
K Ерландссон

Я маю на увазі, якщо у вас є не багатопотоковий процес (тобто такий, який використовує одночасно один процесор). Наприклад, якщо ви просто пишете просту програму на C, яка виконує зайнятий цикл, її працює лише один потік і використовує лише 1 процесор одночасно.
дельтарай

Уся інформація, яку я знайшов, говорить про те, що потоки вважаються окремими процесами, коли їх бачать з ядра та під час розрахунку навантаження. Отже, я не бачу, як я міг би здійснити багатопотоковий процес на повний нахил, що призвело до 1 завантаження та 100% процесора в системі з декількома процесорами. Не могли б ви допомогти мені зрозуміти, як ви це маєте на увазі?
К Ерландссон

Для тих, хто шукає докладнішої інформації: "Середні показники завантаження Linux: Розгадка таємниці" Брендана Грегга отримали всі відповіді, які мені колись потрібні.
Миколай

24

Навантаження - дуже оманливе число. Візьміть його з зерном солі.

Якщо ви породили багато завдань дуже швидко, які завершуються дуже швидко, кількість процесів у черзі запуску занадто мала, щоб зареєструвати навантаження на них (ядро рахує завантаження раз на п’ять секунд).

Розглянемо цей приклад, на моєму хості, який має 8 логічних ядер, цей сценарій python буде реєструвати велике використання процесора вгорі (близько 85%), але навряд чи будь-яке навантаження.

import os, sys

while True:
  for j in range(8):
    parent = os.fork()
    if not parent:
      n = 0
      for i in range(10000):
        n += 1
      sys.exit(0)
  for j in range(8):
    os.wait()

Інша реалізація, це дозволяє уникати waitу групах з 8 (що би перекосило тест). Тут батько завжди намагається утримати кількість дітей на кількості активних процесорів, тому це буде набагато навантаженіше першого методу і, сподіваємось, більш точним.

/* Compile with flags -O0 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <err.h>
#include <errno.h>

#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#define ITERATIONS 50000

int maxchild = 0;
volatile int numspawned = 0;

void childhandle(
    int signal)
{
  int stat;
  /* Handle all exited children, until none are left to handle */
  while (waitpid(-1, &stat, WNOHANG) > 0) {
    numspawned--;
  }
}

/* Stupid task for our children to do */
void do_task(
    void)
{
  int i,j;
  for (i=0; i < ITERATIONS; i++)
    j++;
  exit(0);
}

int main() {
  pid_t pid;

  struct sigaction act;
  sigset_t sigs, old;

  maxchild = sysconf(_SC_NPROCESSORS_ONLN);

  /* Setup child handler */
  memset(&act, 0, sizeof(act));
  act.sa_handler = childhandle;
  if (sigaction(SIGCHLD, &act, NULL) < 0)
    err(EXIT_FAILURE, "sigaction");

  /* Defer the sigchild signal */
  sigemptyset(&sigs);
  sigaddset(&sigs, SIGCHLD);
  if (sigprocmask(SIG_BLOCK, &sigs, &old) < 0)
    err(EXIT_FAILURE, "sigprocmask");

  /* Create processes, where our maxchild value is not met */
  while (1) {
    while (numspawned < maxchild) {
      pid = fork();
      if (pid < 0)
        err(EXIT_FAILURE, "fork");

      else if (pid == 0) /* child process */
        do_task();
      else               /* parent */
        numspawned++;
    }
    /* Atomically unblocks signal, handler then picks it up, reblocks on finish */
    if (sigsuspend(&old) < 0 && errno != EINTR)
      err(EXIT_FAILURE, "sigsuspend");
  }
}

Причина такої поведінки полягає в тому, що алгоритм витрачає більше часу на створення дочірніх процесів, ніж на виконання фактичного завдання (рахуючи до 10000). Завдання, які ще не створені, не можуть зараховувати до стану, який можна виконати, але вони займуть% sys за час процесора після їх породження.

Отже, відповідь справді може бути у вашому випадку, що яка б робота не була зроблена, породжує велику кількість завдань у швидкій послідовності (потоки чи процеси).


Дякую за пропозицію. Діаграма в моєму питанні показує% часу користувача (системний час виключається, ми бачимо лише незначне збільшення системного часу). Чи може чимало дрібних завдань бути поясненням взагалі? Якщо середнє значення завантаження відбирається через кожні 5 секунд, чи частіше відбираються дані про використання процесора, які надає mpstat?
К Ерландссон

Я не знайомий з тим, як робиться вибірка процесора там. Ніколи не читайте джерело ядра щодо цього. У моєму прикладі% usr було 70% +, а% sys - 15%.
Метью Іфе

Гарні приклади!
Ксав'є Лукас

5

Якщо середнє навантаження не сильно зростає, це просто означає, що ваші технічні характеристики та характер завдань, що підлягають обробці, приводять до хорошої загальної пропускної здатності, уникаючи їх накопичення в черзі завдань протягом деякого часу.

Якби явище суперечки було, оскільки, наприклад, середня складність завдання занадто висока або середній час обробки завдання займає занадто багато циклів процесора, то так, середнє навантаження збільшуватиметься.

ОНОВЛЕННЯ:

У моїй оригінальній відповіді це може бути не зрозуміло, тому я зараз уточнюю:

Точна формула розрахунку середнього навантаження є: loadvg = tasks running + tasks waiting (for cores) + tasks blocked.

Ви можете напевно мати хорошу пропускну здатність і наблизитись до середнього навантаження 24, але без штрафу за час обробки завдань. З іншого боку, ви також можете мати 2-4 періодичні завдання, які не виконуються досить швидко, тоді ви побачите, що кількість завдань, які чекають (для циклів процесора), зростає, і ви, зрештою, досягнете високої середньої навантаження. Інша річ, що може статися - це завдання, які виконують видатні синхронні операції вводу / виводу, а потім блокування ядра, зниження пропускної здатності та збільшення черги завдань очікування зростаючої (у цьому випадку ви можете побачити, що iowaitпоказник змінюється)


Наскільки я розумію, середнє навантаження включає також завдання, які виконуються в даний час. Це означатиме, що ми, безумовно, можемо збільшити середню завантаженість без фактичної суперечки для процесорів. Або я помиляюся / нерозумію вас?
К Ерландссон

@KristofferE Ви абсолютно праві. Фактична формула - loadavg = taks run + завдання очікування (для наявних ядер) + завдання заблоковані. Це означає, що ви можете мати середню завантаженість 24, не очікуючи чи блокуючи завдання, таким чином, ви маєте просто "повне використання" або апаратну потужність без будь-яких суперечок. Оскільки ви, здавалося, розгублені щодо середнього навантаження та кількості процесів, що працюють проти використання процесора, я в основному зосередив свою відповідь на поясненнях щодо того, як середня завантаженість може зростати при такій кількості запущених процесів в цілому. Це може бути не так зрозуміло після перечитування.
Ксав'є Лукас

2

Середнє навантаження включає завдання, які блокуються на IO диска, тому ви можете легко мати нульове використання процесора та середнє завантаження 10, маючи лише 10 завдань, які намагаються прочитати з дуже повільного диска. Таким чином, звичайно, що зайнятий сервер починає обмолочувати диск, і все, що шукає, викликає безліч заблокованих завдань, збільшуючи середнє навантаження, а використання процесора падає, оскільки всі завдання блоковані на диску.


1

Хоча відповідь Метью Іфе була дуже корисною та вела нас у правильному напрямку, не саме це спричинило поведінку в нашому випадку. У нашому випадку у нас є багатопотокова програма Java, яка використовує об'єднання потоків, чому не виконується робота над створенням власне завдань.

Однак фактична робота, яку виконують потоки, є короткотривалою і включає в себе очікування вводу-виводу або синхронізацію. Як згадує Метью у своїй відповіді, середня навантаження відбирається в ОС, тому короткочасні завдання можна пропустити.

Я зробив програму Java, яка відтворювала поведінку. Наступний клас Java генерує використання процесора на 28% (зі складеним 650%) на одному з наших серверів. При цьому середня навантаження становить приблизно 1,3. Ключовим тут є сон () всередині нитки, без неї розрахунок навантаження правильний.

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class MultiThreadLoad {

    private ThreadPoolExecutor e = new ThreadPoolExecutor(200, 200, 0l, TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(1000), new ThreadPoolExecutor.CallerRunsPolicy());

    public void load() {
        while (true) {
            e.execute(new Runnable() {

                @Override
                public void run() {
                    sleep100Ms();
                    for (long i = 0; i < 5000000l; i++)
                        ;
                }

                private void sleep100Ms() {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }

    public static void main(String[] args) {
        new MultiThreadLoad().load();
    }

}

Підводячи підсумок, теорія полягає в тому, що нитки в наших додатках багато простоюють, а потім виконують недовговічну роботу, чому завдання неправильно відбираються підрахунок середнього навантаження.


0

Середня завантаженість - це середня кількість процесів у черзі процесора. Це специфічно для кожної системи, ви не можете сказати, що один LA загалом високий у всіх системах, а інший - низький. Таким чином, у вас є 12 ядер, а для LA значно збільшити кількість процесів має бути дійсно високим.

Інше питання - що розуміється під графіком "Використання процесора". Якщо він узятий з SNMP, як це має бути, і ваша реалізація SNMP є net-snmp, то в декількох стеках завантажується процесор від кожного з ваших 12 процесорів. Так net-snmpщо загальна кількість завантаження процесора становить 1200%.

Якщо мої припущення є правильними, використання процесора значно не збільшилось. Таким чином, LA не зросла значно.


Використання процесора взято з mpstat, allрядок. Я впевнений, що це середній показник для всіх процесорів, він не є складним. Наприклад, коли виникає проблема, вгорі відображається 2000% використання ЦП для одного процесу. Це використання з накопиченням.
K Ерландссон

0

Сценарій тут не особливо несподіваний, хоча трохи незвичний. Що стосується Xavier, але не дуже розвивається, це те, що хоча Linux (за замовчуванням) та більшість ароматів Unix реалізують переважне багатозадачність, на здоровій машині завдання рідко будуть виключатися. Кожному завданню передбачено відрізок часу для зайняття процесора, він попередньо знімається, якщо він перевищує цей час і є інші завдання, які чекають запуску (зауважте, що завантаження повідомляє про середню кількість процесів як у процесорі, так і в очікуванні запуску) . Більшу частину часу процес даватиме результат, а не переривати його.

(загалом, вам потрібно переживати про навантаження лише тоді, коли вона наблизить кількість процесорів - тобто коли планувальник починає виконувати завдання).

якщо наші процесори зайняті 75% часу, чи не слід бачити вищу середню завантаженість?

Все, що стосується структури діяльності, явно збільшене використання процесора деякими завданнями (швидше за все, невеликою суттєвістю) не мало негативного впливу на обробку інших завдань. Якщо ви зможете виділити оброблювані транзакції, я би сподівався, що ви побачите, що під час уповільнення з'явиться нова група, тоді як існуючий набір завдань не впливає.

оновлення

Один загальний сценарій, коли високий процесор може відбуватися без великого збільшення навантаження, це те, коли завдання запускає одну (або послідовність) інших завдань, наприклад, після отримання мережевого запиту, обробник спрямовує запит на окрему нитку, окремий потік то робить деякі асинхронні виклики до інших процесів .... вибірка чергової черги призводить до того, що завантаження повідомляється нижчим, ніж є насправді - але воно не збільшується лінійно при використанні процесора - ланцюг запущених завдань не був би запущеним без початкова подія, і тому, що вони відбуваються (більш-менш) послідовно, черга запуску не завищена.


В ОР спочатку було вказано, що сукупний відсоток процесора становив "2000%", припускаючи, що існує багато завдань із використанням CPU, а не лише 1 зайнятий процес. Якби це було приблизно 2000% за хвилину, ти зазвичай передбачаєш, що навантаження буде 20-бальною.
Меттью Іфе

... в коментарі, не в питанні, і він не дуже впевнений у цьому. За відсутності опції 'ALL', mpstat повідомляє про загальне% використання, а не про середнє. Але це не змінює відповідь - мова йде про схему діяльності.
симбей

Я на 100% впевнений, що утилітом процесора, який ми бачимо на графіку, є "середнє значення на процесор". Mpstat запускається без ВСІХ, але це залишає лише інформацію про кожний процесор, у allрядку все ще відображається середнє значення на CPU. Я уточню питання.
К Ерландссон

Не могли б ви трохи розробити останній розділ Йору? Я не можу зрозуміти, що ви маєте на увазі, тоді як частина мого питання, яку ви цитували, - це частина, з якою я маю найбільше проблем з розумінням.
К Ерландссон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.