Skip to content
isdnetworks
Go back

대상이 늘면 장비가 늘어야 했다

수집 대상을 여덟에서 스물로 늘리기로 했다. 지금 장비로 되는지 물었을 때 답을 못 했다.

Table of contents

Open Table of contents

사전 준비 — 대상당 자원을 쟀다

늘리기 전에 지금 도는 것부터 쟀다.

$ ps -o pid,rss,pcpu,args -C collector
  PID   RSS %CPU ARGS
 2841 184320  6.2 collector --target=a
 2847 179104  5.8 collector --target=b
 ...

대상 하나에 collector 프로세스 하나가 뜨고 RSS 가 180MB쯤 %CPU 가 6쯤이다.

8 대상 → 메모리 1.4GB, CPU 48%
20 대상 → 메모리 3.6GB, CPU 120%

코어가 둘이라 상한이 200%이니 20 대상 의 120%는 아직 여유가 있어 보인다.

다만 이 숫자는 %CPU 의 평균이라 평균으로 계산하면 충분해 보이는 것이 실제로는 모자라는 경우가 있다. 그래서 몰리는 때를 따로 봐야 했다.

몰리는 때를 봤다

수집이 언제 도는지부터 봤다.

* * * * * /usr/local/bin/collect-all.sh

collect-all.sh 하나에 여덟 대상이 전부 매분 0초에 함께 시작한다.

$ sar -u 1 60 | sort -k8 -n | head -3
14:22:00   all  91.20   0.00   6.10   1.90   0.00   0.80

sar 로 보니 시작하는 몇 초 동안 프로세서가 91%까지 올라간다.

평균 48%와 순간 91%의 차이가 이 구조의 성격이고 대상이 스물이 되면 그 몇 초가 다음 주기까지 밀린다.

장비가 견뎌야 하는 값은 평균이 아니라 이 순간의 합계이고 나머지 시간에는 자원이 대부분 놀고 있었다.

조치 — 시작 시각 흩기

전부 같은 초에 시작할 이유가 없었다.

#!/bin/sh
i=0
for t in $TARGETS; do
    ( sleep $(( i * 2 )); /usr/local/bin/collector --target="$t" ) &
    i=$(( i + 1 ))
done

sleep 으로 2초씩 밀어 시작하니 스물이면 40초에 걸쳐 흩어진다.

같은 일을 같은 만큼 하는데 최대치만 내려갔고 장비를 안 늘리고 얻은 여유라 값이 쌌다.

다만 이 방법은 수집 주기가 1분일 때만 성립한다. 주기가 짧아지면 흩을 자리 자체가 없고 40초를 흩으면 다음 주기와 겹친다.

제약 — 대상 수가 곧 자원인 구조

sleep 으로 시작을 흩는 것은 최대치만 낮추고 총량은 그대로 둔다.

collector 하나가 대상 하나를 맡으면 대상 수가 곧 자원이다. 이 구조로는 늘릴 때마다 장비를 늘려야 한다.

프로세스가 실제로 무엇을 하는지 봤다.

- 대상에 접속해 값을 읽는다  (대기가 대부분)
- 파싱한다                    (짧다)
- 저장소에 넣는다             (대기)

파싱은 짧고 도는 시간의 대부분이 응답을 기다리는 시간이었다.

이런 일은 collector 하나가 여럿을 맡아도 된다.

for (;;) {
    int n = poll(fds, ntargets, 1000);
    for (int i = 0; i < ntargets; i++) {
        if (fds[i].revents & POLLIN) { handle(i); }
    }
}

poll 로 여러 대상을 한 프로세스가 돌면 메모리가 대상 수에 비례하지 않는다.

선택지 — 격리와 자원

대신 내주는 것이 있었다.

[대상마다 프로세스]  하나가 죽어도 나머지가 산다. 자원이 대상 수에 비례한다
[하나가 전부]        자원이 적게 든다. 하나가 죽으면 전부 멈춘다

앞은 격리를 얻고 자원을 쓰며 뒤는 자원을 아끼고 격리를 내주는 쪽이다.

그래서 중간을 골라 대상을 넷씩 묶어 collector 하나가 맡게 했다.

20 대상 → 프로세스 5개

RSS 합이 3.6GB에서 1GB 아래로 내려갔고 하나가 죽어도 네 대상만 멈춘다.

묶는 크기는 설정으로 뺐는데 지금 넷이 맞는지는 돌려 봐야 알고 나중에 다시 정할 여지를 남겨 두는 편이 낫다.

대응 — 대상당 자원을 계속 기록

다음에도 같은 질문이 올 것이다.

* * * * * ps -o rss= -C collector | awk '{s+=$1} END {print strftime("%s"), s, NR}' >> /var/log/collector-usage

rss 합과 프로세스 수를 collector-usage 에 매분 남기고 대상 수로 나누면 대상당 값이 나온다.

물었을 때 재기 시작하면 며칠이 걸리고 그동안 답을 못 하는데 이미 재 둔 것이 있으면 그 자리에서 답한다.

이번에 여덟에서 스물 을 두고 답을 못 한 것도 재 둔 것이 없었기 때문이다. 늘릴지 말지를 정하는 자리에서 필요한 것은 정확한 예측이 아니라 근거가 되는 숫자였다.

정리


Share this post on:

Previous Post
지금 규약과 어긋난 옛 설정
Next Post
성공이 아니었던 200