Soru Yüksek CPU kullanımı ancak düşük yük ortalaması


Yüksek CPU kullanımı gördüğümüz, ancak oldukça düşük yük ortaladığımız garip bir davranış sergiliyoruz.

Davranış, izleme sistemimizden aşağıdaki grafiklerde en iyi şekilde görülmektedir.

CPU usage and load

Yaklaşık 11: 57'de CPU kullanımı% 25'ten% 75'e çıkıyor. Yük ortalaması önemli ölçüde değişmedi.

Her biri 2 hiper dişe sahip 12 çekirdekli sunucuları çalıştırıyoruz. OS bunu 24 CPU olarak görüyor.

CPU kullanım verileri çalıştırılarak toplanır. /usr/bin/mpstat 60 1 her dakika. İçin veriler all satır ve %usr Yukarıdaki grafikte sütun gösterilir. Bunun CPU verisi başına ortalama olduğunu gösterdiğinden eminim. değil "yığılmış" kullanımı. Grafikte% 75'lik bir kullanım görseler de,% 2000 oranında "yığınlanmış" CPU kullanımını gösteren bir işlem görüyoruz. top.

Ortalama yük ortalaması alınır. /proc/loadavg her dakika.

uname -a verir:

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 dağıtımı Red Hat Enterprise Linux Server release 6.3 (Santiago)

Makinelerde oldukça ağır yük altında birkaç Java web uygulaması çalıştırıyoruz, her makine için 100 istek / sanırım.

Eğer CPU kullanım verilerini doğru olarak yorumluyorsam,% 75 CPU kullanımımız olduğunda, CPU'larımız ortalama% 75'lik bir işlem yürütüyor demektir. Ancak, eğer CPU'larımız zamanın% 75'ini meşgul ediyorsa, daha yüksek yük ortalamasını görmemeliyiz? İşlem kuyruğunda sadece 2-4 işimiz olurken, CPU'lar% 75 meşgul olabilir mi?

Verilerimizi doğru olarak yorumluyor muyuz? Bu davranışa ne sebep olabilir?


19
2018-02-12 11:53


Menşei


İzleme sistemi normalleştirilmiş CPU yükünü gösteriyor mu (load / #CPUs)? Düzenli Linux CPU yükü, farklı çekirdek / işlemci sayılarına sahip sistemlerde karşılaştırmak zor olduğundan, bazı araçlar normalleştirilmiş bir CPU yükü kullanır. - Brian
Her veri noktasını CPU sayısı ile bölmeyi mi kastediyorsunuz? Yani bizim durumumuzda loadavg / 24? Eğer yardımcı olursa, bu türden verileri kolaylıkla oluşturabilirim. - K Erlandsson
Grafiğin zaten bunu gösteriyor olabilirdi. - Brian
Ah, seni yanlış anladığım için özür dilerim. Güzel bir açıklama olurdu, ancak ne yazık ki gösterilen sistem çapında yük ortalamasıdır. Sadece üç kere kontrol ettim. - K Erlandsson


Cevaplar:


Linux'ta en azından, yük ortalaması ve CPU kullanımı aslında iki farklı şeydir. Yükleme ortalaması, bir zaman diliminde bir çekirdek çalıştırma kuyruğunda kaç işlemin beklendiğinin (yalnızca CPU zamanı değil, disk etkinliği) bir ölçüsüdür. CPU kullanımı, CPU'nun şu an ne kadar meşgul olduğunun bir ölçüsüdür. Tek bir CPU ipliğinin bir dakika boyunca% 100 oranında sabitlendiği en yüksek yük, 1 dakikalık yük ortalamasına "katkıda bulunabilir". 1 hiper-iş parçacığına sahip (8 sanal çekirdek) 4 çekirdekli bir işlemci 1 dakika boyunca% 100'e 8 1 dakika yük ortalaması.

Çoğu zaman bu iki sayının birbiriyle ilişkili kalıpları vardır, ama onları aynı şekilde düşünemezsiniz. Yaklaşık% 0 CPU kullanımı ile yüksek bir yüke sahip olabilirsiniz (bekleme durumunda çok fazla IO verisi olduğu zaman gibi) ve tek bir dişli işleminiz olduğunda% 1 ve% 100 CPU yüküne sahip olabilirsiniz. tam eğilme. Ayrıca, kısa süreler için, CPU'yu% 100'e yakın bir zamanda görebilirsiniz, ancak yük hala 1'in altındadır, çünkü ortalama ölçümler henüz "yakalanmadı".

Bir sunucunun 15.000'den fazla yüke sahip olduğunu gördüm (evet bu bir yazım hatası değil) ve% 0'a yakın bir CPU%. Bir Samba paylaşımının sorun yaşadığı ve bir çok müşterinin IO bekleme durumunda kalmaya başlaması nedeniyle oldu. Şanslar, ilgili CPU aktivitesine sahip olmayan normal bir yüksek yük numarası görüyorsanız, bir tür depolama probleminiz var demektir. Sanal makinelerde bu, aynı VM ana bilgisayarında depolama kaynakları için yoğun şekilde rekabet eden başka VM'lerin olduğu anlamına da gelebilir.


30
2018-02-12 21:38



Tek bir iş parçacığıyla% 1 ve% 100 CPU yüküne sahip olabileceğimi nasıl kastediyorsunuz? Ne tür konularda konuşuyorsun? Java süreçlerimizi düşünürsek, onlarca iş parçacığı vardır, ancak iş parçacıklarının işletim sistemi perspektifinden süreçler olarak ele alındığı varsayımı altındaydım (her şeyden önce Linux'ta ayrı PID'ler var). Tek bir çok iş parçacıklı java işleminin, yalnızca bir yük ortalama perspektifinden bir görev olarak sayılması mümkün olabilir mi? - K Erlandsson
Kendi başıma bir test yaptım, bir Java sürecindeki iş parçacıkları, yükün ortalamasına ayrı işlemlerin yapıldığı yere katkıda bulunuyorlar (örneğin, meşgul beklemeli bir döngüde 10 iş parçacığını çalıştıran bir java sınıfı bana 10'a yakın bir yük verir). Yukarıda bahsettiğiniz işlenmiş süreç hakkında bir açıklama isterim. Teşekkür ederim! - K Erlandsson
Demek istediğim, çoklu iş parçacığına sahip olmayan bir işleminiz varsa (yani, bir kerede yalnızca bir CPU kullanan). Örneğin, yoğun bir döngü çalıştıran basit bir C programı yazarsanız, sadece tek bir iş parçacığı çalışır ve her seferinde yalnızca 1 CPU kullanır. - deltaray
Bulduğum tüm bilgiler, çekirdeğin çekirdekten bakıldığında ve yükü hesaplarken ayrı işlemler olarak sayıldığını söylüyor. Bu nedenle, çok yüklü bir sistemde 1 yük ve% 100 CPU ile sonuçlanan tam bir eğim üzerinde çok parçalı bir işleme nasıl sahip olabileceğimi göremiyorum. Nasıl anladığını anlamama yardım eder misin? - K Erlandsson
Daha fazla ayrıntı isteyen herkes için: "Linux Yük Ortalamaları: Gizemi Çözmek" Brendan Gregg İhtiyacım olan tüm cevapları aldım. - Nickolay


Yük çok aldatıcı bir sayıdır. Bir tane tuzla al.

Çok çabuk tamamlanan çok hızlı bir şekilde birçok görevi gerçekleştirirseniz, çalışma kuyruğundaki süreçlerin sayısı yükü kaydetmek için çok küçüktür (çekirdek sayıları her beş saniyede bir kez yüklenir).

Bu örneği düşünün, 8 mantıksal çekirdeği olan ana bilgisayarımda, bu python betiği büyük bir CPU kullanımını en üstte (yaklaşık% 85), ancak neredeyse hiç yükte kaydedecektir.

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()

Başka bir uygulama, bu bir önler wait 8 grupta (testi çarpacaktı). Burada ebeveyn her zaman, aktif CPU'ların sayısına göre çocuk sayısını tutmaya çalışır, böylece ilk yöntemden çok daha yoğun olacak ve umarım daha doğru olacaktır.

/* 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");
  }
}

Bu davranışın nedeni, algoritmanın çocuk işlemlerini gerçek görevi yerine getirmekten (10000'e kadar) daha fazla zaman geçirmesidir. Henüz oluşturulmamış görevler 'runnable' durumuna doğru sayılmaz, ancak henüz üretildiklerinde CPU saatinde% sys alacaktır.

Bu yüzden, cevabınız, işiniz her ne olursa olsun, hızlı bir şekilde ardı ardına (iş parçacığı veya süreçler) çok sayıda görevi ortaya çıkarır.


20
2018-02-12 13:05



Öneri için teşekkürler. Benim sorumdaki grafik% kullanıcı zamanını gösterir (CPU sistem zamanı hariç tutulur, sadece sistem zamanında çok az bir artış görürüz). Yine de birçok küçük görev açıklama olabilir mi? Yük ortalaması her 5 saniyede bir örnekleniyorsa, mpstat tarafından verilen CPU kullanım verileri daha sık örneklenmiş midir? - K Erlandsson
CPU örneklemenin orada nasıl yapıldığını bilmiyorum. Çekirdek kaynağını asla okumayın. Benim örneğimde% usr% 70 + ve% sys% 15 idi. - Matthew Ife
İyi örnekler! - Xavier Lucas


Yük ortalamasının çok fazla artmaması, donanım özelliklerinin ve işlenecek olan işlerin doğasının iyi bir genel iş hacmine yol açtığı ve bir süre için görev kuyruğunda biriktirilmelerinin önlendiği anlamına gelir.

Bir çekişme fenomeni olsaydı, örneğin ortalama görev karmaşıklığı çok yüksek veya görev ortalama işlem süresi çok fazla CPU döngüsü gerektiriyorsa, evet, yük ortalaması artar.

GÜNCELLEME:

Orijinal cevabımda net olmayabilir, bu yüzden şimdi netleştiriyorum:

Yük ortalama hesaplamanın tam formülü şöyledir: loadvg = tasks running + tasks waiting (for cores) + tasks blocked.

Kesinlikle iyi bir iş hacmine sahip olabilirsiniz ve 24 saatlik bir yük ortalamasına yaklaşabilir, ancak işlem süresi üzerinde ceza gerektirmez. Öte yandan, 2-4 periyodik görevlerinizin de yeterince hızlı tamamlanmamasını sağlayabilirsiniz, o zaman görev bekletme sayısını (CPU döngüleri için) büyüyecek ve sonunda yüksek bir yük ortalamasına ulaşacaksınız. Olabilecek diğer bir şey, olağanüstü senkronize G / Ç işlemlerini çalıştıran, daha sonra bir çekirdeği engelleyen, iş akışını azaltan ve bekleyen görev sırasının büyümesini sağlayan görevler (bu durumda iowait metrik değiştirme)


5
2018-02-12 13:00



Yük ortalamasının şu anda yürütmekte olan görevleri de içerdiği anlayışım. Bu, CPU'lar için gerçek çekişme olmadan kesinlikle yük ortalamasında bir artışa sahip olabileceğimiz anlamına gelir. Yoksa yanılıyor muyum? - K Erlandsson
@KristofferE Tamamen haklısınız. Asıl formül, loadavg = çalıştırılıyor + bekleyen görevler (kullanılabilir çekirdekler için) + görevler engellendi. Bu, 24 saatlik bir yüke sahip olabileceğiniz, herhangi bir görev beklemediğiniz veya engellenemeyeceğiniz anlamına gelir, bu nedenle herhangi bir çekişmeden yalnızca "tam kullanım" veya donanım kapasitesine sahip olursunuz. Yük ortalamaları ve CPU kullanımıyla çalışan süreçlerin sayısı hakkında kafanız karıştığında, genel olarak bir yük ortalamasının genel olarak çok az çalışan süreçle nasıl büyüyebileceğine dair açıklamalara odaklanmam gerekiyor. Gerçekten tekrar okuduktan sonra o kadar açık olmayabilir. - Xavier Lucas


Yük ortalaması disk IO'da engellenen görevleri içerir, böylece çok yavaş bir diskten okumayı deneyen 10 görevi gerçekleştirerek sıfır cpu kullanımı ve 10'luk bir yük ortalamasına sahip olursunuz. Bu nedenle yoğun bir sunucunun diskin başlamasını ve yaygın olarak tüm arama işlemlerinin diskte engellendiğinden, cpu kullanımı düşerken, tüm arama işleminin çok sayıda engellenmiş görevlere neden olduğunu, yük ortalamasını yükselttiğini görmek yaygındır.


2
2018-02-12 20:34





Matthew Ife'nin cevabı çok yardımcı oldu ve bizi doğru yönde yönlendirirken, davamızdaki davranışa tam olarak neden gelmiyordu. Bizim durumumuzda, iş parçacığı gerçek işlerini oluştururken neden iş parçacığı havuzu kullanan çok iş parçacıklı bir Java uygulamasına sahibiz.

Bununla birlikte, iş parçacığının yaptığı asıl iş kısa ömürlüdür ve IO beklemeler veya senkronizasyon beklemelerini içerir. Matta'nın cevabında bahsettiği gibi, yük ortalaması işletim sistemi tarafından örneklenir, böylece kısa ömürlü görevler gözden kaçırılabilir.

Davranışı yeniden üreten bir Java programı yaptım. Aşağıdaki Java sınıfı, sunucularımızdan birinde% 28 (% 650 istiflenmiş) CPU kullanımı üretir. Bunu yaparken, yük ortalaması yaklaşık 1.3'tür. Buradaki anahtar, iplik hesaplamasındaki uyku () olup, yük hesabı doğru değildir.

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();
    }

}

Özetle, teori, uygulamalarımızdaki iş parçacıklarının çok fazla boşta kalması ve daha sonra kısa ömürlü çalışmayı gerçekleştirmesidir, bu nedenle görevlerin yük ortalama hesaplamasıyla neden doğru şekilde örneklenmediği.


1
2018-02-17 08:45





Yük ortalaması, CPU kuyruğundaki ortalama işlem sayısıdır. Her sisteme özgüdür, bir LA'nın tüm sistemlerde jenerik olarak yüksek olduğunu ve diğerinin de düşük olduğunu söyleyemezsiniz. Yani 12 çekirdeğe sahipsin ve LA için süreçlerin sayısının önemli ölçüde artması gerçekten çok yüksek olmalı.

Başka bir soru, "CPU Kullanımı" grafiği ile kastedilen şeydir. SNMP'den alınmışsa, olması gerektiği gibi ve SNMP uygulamanız net-snmpdaha sonra, sadece 12 CPU'unuzun her birinden CPU yükünü yığar. İçin böylece net-snmp toplam CPU yükü miktarı% 1200'dür.

Varsayımlarım doğruysa, CPU kullanımı önemli ölçüde artmadı. Böylece LA anlamlı bir şekilde artmadı.


0
2018-02-12 12:21



CPU kullanımı mpstattan alınır, all kürek çekmek. Tüm CPU'larda ortalama bir ortalama olduğundan emin değilim, yığılmış değil. Örneğin, sorun oluştuğunda, bir işlem için% 2000 CPU kullanımını gösterir. Bu yığılmış kullanımdır. - K Erlandsson


Bu senaryo, biraz sıra dışı olmasına rağmen, özellikle beklenmedik değildir. Xavier'in üzerine yazdığı, ama çok fazla geliştirmediği, Linux'un (varsayılan olarak) ve Unix'in çoğu aromalarının, önleyici çok görevli uygulamayı sağlamasına rağmen, sağlıklı bir makinede, görevlerin nadiren önceden boşaltılacağıdır. Her bir görev, CPU'yu işgal etmek için bir zaman dilimi ayrılır, yalnızca bu süreyi aşarsa önceden çalıştırılır ve çalışmayı bekleyen diğer görevler vardır (yükün CPU'da hem ortalama işlem sayısı raporlarını hem de çalışmayı beklediğini unutmayın) . Çoğu zaman, bir süreç kesintiye uğramak yerine verim verecektir.

(genel olarak, sadece CPU'ların sayısı yaklaştığında yük hakkında endişelenmeniz gerekir - yani programlayıcı önyükleme görevlerini başlattığında).

Eğer CPU'larımız zamanın% 75'ini meşgul ediyorsa, daha yüksek yük ortalamasını görmemeliyiz?

Her şeyden önce, faaliyet örüntüsü, bazı görevlerin (muhtemelen küçük bir küçüklük) CPU'ların kullanımının açıkça artması, diğer görevlerin işlenmesi üzerinde olumsuz bir etkiye sahip değildi. İşlenmekte olan işlemleri izole edebilecek olsaydınız, bu görevde yavaşlama sırasında ortaya çıkan yeni bir grup görmeyi beklerdim.

güncelleştirme

Yüklemede büyük bir artış olmadan yüksek CPU'nun ortaya çıkabileceği ortak bir senaryo, bir görevin bir başka görevi (örneğin, bir dizi) tetiklediği yerdir. Bir ağ isteğinin alınması üzerine, işleyici isteği ayrı bir iş parçacığına yönlendirir, ayrı iş parçacığı diğer işlemlere bazı zaman uyumsuz çağrıları yapar. ... iş akışının örneklemesi, yükün gerçekte olduğundan daha düşük olarak bildirilmesine neden olur - ancak CPU kullanımı ile doğrusal olarak yükselmez - tetiklenen görevlerin zinciri ilk olay olmadan çalıştırılamazdı ve ardışık olarak (daha fazla veya daha az) meydana geldikleri için çalışma sırası şişirilmez.


0
2018-02-12 13:55



OP, ilk olarak, toplam CPU% 'sinin "% 2000" olduğunu ve yalnızca 1 meşgul işlemden ziyade CPU'yu kullanan birçok görev olduğunu gösteren belirtiler sağlamıştır. Bir dakika için% 2000 tutarlı olsaydı, normalde yükün 20-ish olduğunu tahmin edersiniz. - Matthew Ife
... bir yorumda, soruda değil, ve bundan emin değil. 'TÜM' seçeneğinin yokluğunda mpstat, toplam kullanımın ortalamasını değil,% olduğunu bildirir. Ancak bu, cevabı değiştirmez - bu etkinlik paterni hakkındadır. - symcbean
Grafikte gördüğümüz CPU kullanımının "CPU başına ortalama" olduğunu% 100 olumlu buluyorum. Mpstat ALL olmadan çalışır, ancak bu sadece CPU başına bilgi verir, all satır hala CPU başına ortalama gösterir. Soruyu açıklığa kavuşturacağım. - K Erlandsson
Son bölümü biraz detaylandırır mısınız lütfen? Ne demek istediğini anlayamıyorum, benim attığım sorunun bir kısmı benim en çok anlayabileceğim kısım. - K Erlandsson