linux 호스트 load average 의 개념 & & 계산 과정 & & 주의사항

6097 단어 linuxloadaverage
        최근 에 개 발 된 모듈 은 기계실 각 노드 의 부하 상황 (예 를 들 어 네트워크 카드 IO, load average 등 기준) 에 따라 임 무 를 배정 해 야 한다. 처음에 리 눅 스 기계 load average 라 는 기준 에 대해 잘 알 지 못 했 고 조사 연 구 를 통 해 그 계산 방법 과 영향 요 소 를 밝 혀 필기 로 기록 했다.1. load average         셸 터미널 에서 top 명령 을 입력 할 때 기본 값 으로 출력 내용 의 첫 줄 에 load average 라 는 지표 값 이 있 습 니 다. 다음 과 같 습 니 다.
top - 19:10:32 up 626 days,  4:58,  1 user,  load average: 7.74, 5.62, 6.51
Tasks: 181 total,   8 running, 173 sleeping,   0 stopped,   0 zombie
Cpu(s):  4.0% us,  0.5% sy,  0.0% ni, 95.4% id,  0.0% wa,  0.0% hi,  0.0% si
        uptime 명령 을 입력 하면 load average 도 출력 됩 니 다:
19:15:10 up 129 days,  5:12, 15 users,  load average: 0.01, 0.09, 0.05    
        man uptime 의 설명 에 따 르 면
load average 에 포 함 된 3 개의 값 은 각각 past 1, 5 and 15 minutes 내의 시스템 평균 부 하 를 나타 낸다.
        그렇다면 이 세 개의 값 은 어떻게 계 산 된 것 일 까?다음은 리 눅 스 소스 코드 에서 답 을 찾 아 보 자.
2. Liux 기계 load average 의 계산 과정
        위 키 백과 가 load 에 대한 설명 (여기 참조) 에서 Liux 시스템 이 load 에 대한 계산 방법 을 언급 했 습 니 다. 직접 검증 하기 위해 저 는 Liux 소스 코드 (Liux kernel 2.6.9) 의 관련 코드 를 체크 했 습 니 다. 위 에서 아래로 검증 하 는 과정 은 다음 과 같 습 니 다.
        원본 트 리 kernel/timer. c 파일 에서 시스템 load 를 계산 하 는 함수 코드 는 다음 과 같 습 니 다.
// 源码树路径:kernel/timer.c
/*
 * Hmm.. Changed this, as the GNU make sources (load.c) seems to
 * imply that avenrun[] is the standard name for this kind of thing.
 * Nothing else seems to be standardized: the fractional size etc
 * all seem to differ on different machines.
 *
 * Requires xtime_lock to access.
 */
unsigned long avenrun[3];

/*
 * calc_load - given tick count, update the avenrun load estimates.
 * This is called while holding a write_lock on xtime_lock.
 */
static inline void calc_load(unsigned long ticks)
{
	unsigned long active_tasks; /* fixed-point */
	static int count = LOAD_FREQ;

	count -= ticks;
	if (count < 0) {
		count += LOAD_FREQ;
		active_tasks = count_active_tasks();
		CALC_LOAD(avenrun[0], EXP_1, active_tasks);
		CALC_LOAD(avenrun[1], EXP_5, active_tasks);
		CALC_LOAD(avenrun[2], EXP_15, active_tasks);
	}
}
        위의 코드 에서 알 수 있 듯 이 정 의 된 배열 avenrun [] 은 3 개의 요 소 를 포함 하고 각각 past 1, 5 and 15 minutes 의 load average 값 을 저장 하 는 데 사 용 됩 니 다.calc_load 는 구체 적 인 계산 함수 로 그 매개 변수 ticks 는 샘플링 간격 을 표시 합 니 다.함수 체 에서 현재 활성 화 된 프로 세 스 수 (active tasks) 를 가 져 온 다음 매개 변수 로 CALC 를 호출 합 니 다.LOAD 는 각각 3 가지 load average 를 계산한다.
        함수 호출 체인 을 따라 count 를 볼 수 있 습 니 다.active_tasks () 정 의 는 다음 과 같 습 니 다 (kernel/timer. c 파일 에서 도).
/*  
 * Nr of active tasks - counted in fixed-point numbers
 */
static unsigned long count_active_tasks(void)
{
	return (nr_running() + nr_uninterruptible()) * FIXED_1;
}

        원본 코드 에서 볼 수 있 습 니 다, countactive_tasks () 는 현재 실행 중인 프로 세 스 (nr running) 를 포함 하여 현재 활성 프로 세 스 수 를 되 돌려 줍 니 다.2) 중단 할 수 없 는 sleeping 프로 세 스 (예 를 들 어 IO 작업 을 수행 하고 있 는 마 운 트 된 프로 세 스).        nr 에 대하 여running 프로 세 스 와 nruninteruptible 프로 세 스 의 계산 방법 은 원본 트 리 kernel/schde. c 에서 관련 코드 를 볼 수 있 습 니 다.
// 源码树路径:kernel/sched.c
/*
 * nr_running, nr_uninterruptible and nr_context_switches:
 *
 * externally visible scheduler statistics: current number of runnable
 * threads, current number of uninterruptible-sleeping threads, total
 * number of context switches performed since bootup.
 */
unsigned long nr_running(void)
{
	unsigned long i, sum = 0;

	for (i = 0; i < NR_CPUS; i++)
		sum += cpu_rq(i)->nr_running;

	return sum;
}

unsigned long nr_uninterruptible(void)
{
	unsigned long i, sum = 0;

	for_each_cpu(i)
		sum += cpu_rq(i)->nr_uninterruptible;

	return sum;
}

        함수 호출 체인 을 따라 계속 보면 include/linux/sched. h 에서 CALC 를 볼 수 있 습 니 다.LOAD 의 정의:
// 源码树路径:include/linux/sched.h
/*
 * These are the constant used to fake the fixed-point load-average
 * counting. Some notes:
 *  - 11 bit fractions expand to 22 bits by the multiplies: this gives
 *    a load-average precision of 10 bits integer + 11 bits fractional
 *  - if you want to count load-averages more often, you need more
 *    precision, or rounding will get you. With 2-second counting freq,
 *    the EXP_n values would be 1981, 2034 and 2043 if still using only
 *    11 bit fractions.
 */
extern unsigned long avenrun[];		/* Load averages */

#define FSHIFT		11		/* nr of bits of precision */
#define FIXED_1		(1<<FSHIFT)	/* 1.0 as fixed-point */
#define LOAD_FREQ	(5*HZ)		/* 5 sec intervals */
#define EXP_1		1884		/* 1/exp(5sec/1min) as fixed-point */
#define EXP_5		2014		/* 1/exp(5sec/5min) */
#define EXP_15		2037		/* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
	load *= exp; \
	load += n*(FIXED_1-exp); \
	load >>= FSHIFT;
        보 입 니 다. CALCLOAD 는 매크로 정의 입 니 다. load average 의 값 은 3 개의 매개 변수 와 관련 이 있 습 니 다. 그러나 하나의 기준 값 (예 를 들 어 past 5 minutes 의 load average) 만 고려 하면 이 값 은 현재 활성 프로 세 스 수 (active tasks) 의 영향 을 받 을 뿐 활성 프로 세 스 수 는 두 가 지 를 포함 합 니 다. 현재 실행 중인 프로 세 스 와 중단 할 수 없 는 마 운 트 프로 세 스 입 니 다.
        이것 은 제 관찰 결과 에 부합 합 니 다. 세 대의 하드웨어 가 같은 Liux 기기 (8 cup, 16GB memory, 1.8T disk) 를 설정 하고 현재 전체 프로 세 스 수의 차이 가 많 지 않 은 (모두 170 +) 상황 에서 그 중 1 대의 기 계 는 1 개의 일반 프로 세 스 (여기 의 '일반' 은 CPU 형 도 아니 고 IO 형 도 아 닌) 가 실행 되 고 나머지 는 모두 sleeping 입 니 다.두 번 째 기 계 는 5 개의 cpu 형 프로 세 스 가 있 고 cpu 의 점용 율 은 모두 99% 에 달 하 며 나머지 프로 세 스 는 sleeping 입 니 다.세 번 째 기 계 는 두 번 째 프로 세 스 가 하 드 디스크 를 읽 고 나머지 sleeping 을 쓴다.세 번 째 기계 의 load average 지표의 3 개 수 치 는 모두 가장 크 고 두 번 째 기 계 는 그 다음 이 며 첫 번 째 기계 의 3 개 수 치 는 모두 0 에 가깝다.
        이 를 통 해 running 형식의 프로 세 스 에 비해 uninteruptible 형식의 프로 세 스 (예 를 들 어 IO 작업 중) 가 시스템 load 에 미 치 는 영향 이 크다 고 추정 할 수 있다.(
주: 이 추정 은 데이터 나 코드 기반 이 없 으 며, 오류 가 있 으 면 지적 을 환영 합 니 다)
3. load average 뒤의 의 미 를 이해한다.        위 에서 load average 의 개념 과 Liux 시스템 이 이 지표 에 대한 계산 과정 을 소개 했다. 그러면 이 기준 치 는 도대체 어떻게 해석 합 니까?이 글 은 상세 하고 형상 적 인 설명 을 하 였 으 니, 여기 서 더 이상 군말 하지 않 겠 다.
[참고 자료]
1. wikipedia: Load (computing)  2. Liux 소스 코드 (커 널 버 전 2.6.9)
3. Understanding Linux CPU Load - when should you be worried? 
================== EOF ===================

좋은 웹페이지 즐겨찾기