2012-03-02 4 views
4

우리 서버 중 하나가 응용 프로그램에 매우 높은 CPU로드를 경험하고 있습니다. 다양한 통계를 살펴보고 문제의 원인을 찾는 데 문제가 있습니다.높은 CPU, 컨텍스트 전환으로 인한 것일 수 있습니까?

현재 이론 중 하나는 너무 많은 스레드가 관련되어 있으며 동시에 실행중인 스레드의 수를 줄이려고한다는 것입니다. 3000 개의 쓰레드가있는 하나의 메인 쓰레드 풀과 그것으로 작업하는 WorkManager가 있습니다 (이것은 Java EE - Glassfish입니다). 임의의 주어진 순간에 병렬로 수행해야하는 약 620 개의 개별 네트워크 IO 작업이 있습니다 (java.NIO 사용은 옵션이 아님). 또한 IO가 포함되지 않은 병렬 처리가 약 100 개 수행됩니다.

이 구조는 효율적이지 않으며 실제로 손상을 일으키는 지보고 싶거나 단순히 나쁜 습관입니다. 어떤 변화가이 시스템에서 (인력면에서) 상당히 비싸다는 이유로 어떤 문제에 대한 증거가 필요합니다.

이제 우리는 필요한 동시 작업보다 훨씬 많은 스레드가있는 경우 스레드의 컨텍스트 전환이 원인인지 궁금해합니다. 로그를 보면 평균적으로 주어진 초에 14 개의 다른 스레드가 실행되는 것을 볼 수 있습니다. 우리가 두 개의 CPU (아래 참조)의 존재를 고려한다면, 그것은 CPU 당 7 개의 쓰레드입니다. 이것은 너무 많이 들리지는 않지만 우리는 이것을 검증하기를 원했습니다.

문맥 전환이나 너무 많은 스레드를 문제로 배제 할 수 있습니까?

일반 세부 :

  1. 자바 1.5 (예, 그것은 옛날의), CentOS는 5, 64 비트, 리눅스 커널에서 실행되는 2.6.18-128.el5
  2. 하나의 단일 자바 프로세스가 그 기계에는 아무것도 없다.
  3. 두 개의 CPU, VMware 기반.
  4. 8GB RAM
  5. 시스템에서 프로파일 러를 실행할 수있는 옵션이 없습니다.
  6. Java 또는 OS를 업그레이드 할 수있는 옵션이 없습니다. 아래의 조언, 우리는 평균 부하 (사용 가동 시간)과 CPU의 캡처를 수행 한 것처럼

UPDATE (vmstat를 사용하여 1 120) 다양한 부하와의 테스트 서버에서. 우리는 시스템이 새로운 부하 주위에 안정화되도록 각 부하 변화와 그 측정 사이 15 분 기다렸는데 부하 평균 번호는 업데이트됩니다 : 프로덕션 서버의 워크로드의

50 % : http://pastebin.com/GE2kGLkk

(34) 프로덕션 서버의 작업 부하 % http://pastebin.com/V2PWq8CG

프로덕션 서버의 워크로드의

25 % : http://pastebin.com/0pxxK0Fu

CPU 사용량이 부하가 감소로 감소하지만 25~50%에서 매우 급격한 수준 (변화 것으로 보인다 %는 실제로 50 %가 아닙니다. CPU 사용량 감소). 로드 평균은 작업량과 관련이없는 것 같습니다.

우리의 테스트 서버가 VM이기 때문에 동일한 호스트에서 실행중인 다른 VM이 CPU 측정에 영향을 줄 수 있습니까?http://pastebin.com/DvNzkB5z

2 부 : http://pastebin.com/72sC00rc

파트 3 : http://pastebin.com/YTG9hgF5

+0

그럼 스레드 풀의 스레드 수를 줄이고 도움이되는지 확인해보십시오. – Voo

+0

CPU 사용률이 높을 수 있습니다. 즉, CPU 리소스 사용률이 최적이라는 의미입니다. 스레드가 I/O 또는 잠금을 기다리지 않고 뭔가를 계산하고 있습니다. 불필요하게 CPU를 소비하는 엄격한 루프가 아니라면 달성해야하는 높은 수준의 동시성에 만족해야합니다. – dasblinkenlight

+1

@dasblinkenlight 컨텍스트 스위칭과 같은 낭비가 없다는 것을 증명할 수 있다면 사실입니다.우리가 그렇게 할 수 있다면 시스템 팀에게 더 많은 CPU를 추가하고 그 이유를 정당화 할 수 있습니다. 그러나 우선, 우리는 숙제를해야합니다. – Yon

답변

2

문제는 무엇보다도 100 개 CPU 바운드 쓰레드 더 나에게 보인다. 3000 스레드 풀은 기본적으로 유휴 스레드가 많은 것을 소비하지 않으므로 빨간색 청어입니다. I/O 스레드는 컴퓨터 작업과 관련하여 지질 학적 시간 척도로 측정되기 때문에 "대부분의 시간"대기 상태가 될 가능성이 큽니다.

100 개의 CPU 스레드가 수행하는 작업이나 그 지속 시간은 언급하지 않지만 컴퓨터 속도를 줄이려면 "타임 슬라이스까지 실행"이라는 100 개의 스레드를 전용으로 지정하면됩니다. . "항상 실행할 준비가되었습니다"100 개가 있기 때문에 시스템은 스케줄러가 허용하는 한 빨리 컨텍스트를 전환합니다. 유휴 상태 시간은 거의 없습니다. 문맥 전환은 당신이 그렇게 자주하고 있기 때문에 영향을 줄 것입니다. CPU 쓰레드가 CPU 시간의 대부분을 소비하기 때문에, I/O "바운드 (bound)"쓰레드는 실행 대기열에서 I/O를 기다리는 시간보다 오래 대기하게됩니다. 그래서 더 많은 프로세스가 기다리고 있습니다 (I/O 프로세스는 I/O 장벽을 빨리 밟을 때 더 자주 빠져 나가 다음 프로세스를 유휴 상태로 만듭니다).

효율을 향상시키기 위해 여기 저기 비틀기가 있지만 의심의 여지가 있지만 100 CPU 스레드는 100 CPU 스레드입니다. 별로 거기에서 할 수는 없습니다.

+0

통찰력을 가져 주셔서 감사합니다. 질문에 대한 두 번째 업데이트에 게시 된 스레드 스택을 보면 어떻게 생각하십니까? – Yon

+0

스레드 스택을 검토하고 스레드 풀 크기 등을 가지고 놀아 본 후에 여기에서 올바른 것으로 결론을 냈습니다. 스레드 풀 크기를 줄이지 않고 I/O가 필요없고 아무 것도 기다리지 않는 작업이 연속적으로 실행되도록 일부 코드를 변경했습니다. 다른 작업은 병렬로 실행되지만 주어진 순간에 RUNNABLE 상태에있을 스레드 수에 대한 추정에 따라 병렬로 실행되는 작업 수에 대한 특정 제한이 있습니다. – Yon

2

UPDATE 2 세 부분 (페이스트 빈 제한)

제 1 스레드의 스냅 장착

컨텍스트 스위칭을 배제 할 수 있습니까? 또는 너무 많은 스레드가 문제가됩니까?

당신이 걱정하는 것은 당신이 걱정하는 것입니다. 2 CPU VMware 인스턴스 에서 확실하게 스레드 (3000 개 이상의 동시 작업)가있는 스레드 풀은 컨텍스트 전환 과부하 및 성능 문제의 원인이 될 수있는 문제인 것 같습니다. 스레드 수를 제한하면 은 성능을 향상시킬 수 있지만 올바른 숫자를 결정하는 것은 어려울 것이며 많은 시행 착오를 거치게됩니다.

우리는 문제의 증거가 필요합니다.

  • 시계 VM의 OS와 JVM의로드 평균 :

나는 몇 가지 아이디어를 가장 좋은 방법은 대답을 잘 모르겠어요하지만 여기에 있습니다. 높은 부하 값 (20+)이 표시되는 경우 이는 실행 대기열에 너무 많은 항목이 있음을 나타냅니다.

  • 테스트 환경에서로드를 시뮬레이트 할 방법이 없으므로 스레드 풀 번호로 재생할 수 있습니까? 풀 크기가 X 인 테스트 환경에서 시뮬레이션 된로드를 실행 한 다음 X/2로 실행하면 최적 값을 결정할 수 있어야합니다.
  • 높은로드 시간과 낮은로드 시간을 비교할 수 있습니까? 이 시간 동안 대기 시간에 대한 응답 수를 그래프로 표시하여 스 래싱 관점에서 전환점을 볼 수 있습니까?
  • 하중을 시뮬레이션 할 수있는 경우 "소방 호스에서 마시"방법으로 테스트하지 않았는지 확인하십시오. 위아래로 전화를 걸 수있는 시뮬레이션 된로드가 필요합니다. 10 %에서 시작하고 느려지면 처리량과 대기 시간을 보면서 시뮬레이션 된 부하가 증가합니다. 처리량 병합 또는 그렇지 않은 편향을 관찰하여 팁점을 볼 수 있어야합니다.
  • +0

    여기에 믹스를 추가하려면 시스템 팀이 제어하지 않고 CPU 수를 변경할 수 있으므로 부팅 할 때마다 다시 조정해야합니다. – Yon

    +1

    @Yon 부팅시 구성되는 1 ~ 2 개의 여분의 CPU가 차이를 만들지는 않을 것이라고 생각합니다. 당신은 어딘가에 8 또는 16 코어 시스템에서 시스템을 실행 해 보았습니까? – Gray

    +0

    우리는 당신의 주장을 증명하고 관련된 일을 어떻게 정당화합니까? – Yon

    1

    일반적으로 스레드의 컨텍스트 전환은 컴퓨터를 사용하는 경우 매우 저렴하지만이 스레드가 많은 경우에는 알 수 없습니다. Java 1.6 EE 로의 업그레이드는 문제가되지 않지만 일부 하드웨어 업그레이드는 어떻게됩니까? 아마도 빠른 픽스를 제공 할 것이고 값 비싸지 않아야합니다 ...

    +0

    시스템 팀은 왜 자원의 변화가 정당한 지 설명하는 증거가 필요합니다. – Yon

    0

    예 : 유사한 시스템에서 프로파일 러를 실행하십시오.

    • 자바 6 또는 7의 최신 버전 (그것은, 차이가 나지 않을 수 있습니다이 경우 업그레이드 생산을 귀찮게하지 않습니다)
    • VM웨어를 사용하지 않는 시도를 CentOS 6.x에서 시도를하려고합니다.
    • 스레드 수를 줄이십시오. 당신은 8 개의 코어 만 가지고 있습니다.

    많은 위와 같은 옵션을 사용하면 차이가 있지만, 알려진/반복적 인 작업 부하로 시스템을 테스트 할 수있게되면 알 수 없습니다.

    +0

    우리는 대략 절반의 부하를 테스트 환경에서 실행합니다. Java 버전을 변경해도 영향을받지 않으며 스레드 수를 줄이지도 않았습니다. – Yon

    +0

    그러면 Java 버전 업그레이드가 도움이되지 않으며 스레드 수가 문제가되지 않는다고 결론 내릴 수 있습니다. –

    +0

    질문 중 하나는 다음과 같습니다.로드 된 서버가 더 많은 스레드를 깨우고이 컨텍스트 스위칭이 문제를 일으킬 가능성이 있습니까? 큰 풀을 사용하더라도 대부분의 스레드가 대기열에서 대기 중임을 기억해야합니다. – Yon

    4

    나는 귀하의 제약이 부당하다고 생각합니다. 기본적으로 당신이 말하는 것은 :

    1.I can't change anything 
    2.I can't measure anything 
    

    내 문제가 무엇인지 추측해볼 수 있습니까?

    실제 응답은 응용 프로그램에 적절한 프로파일 러를 연결해야하며 CPU 사용, 디스크/네트워크 I/O 및 메모리와 관련된 내용을 연관시켜야한다는 것입니다.

    80/20 성능 조정 규칙을 기억하십시오. 80 %는 응용 프로그램 조정에서 나옵니다. 하나의 VM 인스턴스에 너무 많은 부하가 걸릴 수 있으며 시스템에 더 많은 리소스를 제공하여 수평 또는 수직 확장을위한 솔루션을 고려할 시간이 될 수 있습니다. 30 억 개의 JVM 설정 중 하나가 응용 프로그램의 실행 세부 사항과 인라인되지 않을 수 있습니다.

    3000 스레드 풀이 더 많은 스레드 = 더 많은 동시성 = 더 많은 성능 이론에서 나온 것으로 가정합니다. 진정한 대답은 변경 전후의 처리량과 응답 시간을 측정하고 결과를 비교하지 않는 한 튜닝 변경이 아무 가치도 없다는 것입니다.

    +0

    우리가 일을 할 수 없다는 논리는 서버가 지구 반대편에있는 몇 가지 보호 조치를 취하고 있다는 것입니다. 우리는 거기로 날아갈 필요가 있고 심지어 인터넷에 접속할 필요가 없기 때문에 상황이 꽤 복잡합니다. 우리는 그렇게하지 않는 것이 좋습니다. 더 많은 리소스를 제공하려면 로컬 시스템 팀을 설득해야합니다. 즉, 우리는 증거가 필요하다는 것을 의미합니다. – Yon

    +0

    스레드 풀은 다음과 같습니다. 동시 IO 작업의 수는 우리가 제어하지 않고 커질 수 있습니다. 시스템을 조금만 이해하면이 증가를 유발할 수있는 다른 사람이 있습니다.그래서 우리는이 연산자가 시스템에 던질 수있는 작업량에 충분한 숫자로 3000을 설정합니다. 글래스 피쉬의 스레드 풀에있는 문제는 런타임에 크기를 조정할 수 없다는 것입니다. – Yon

    +2

    당신의 칭의가 완전히 무효입니다. 스레드 풀 크기는 자녀에게주는 허용치가 아닙니다. 왜 40 억으로 설정하지 않습니까? 물리적 인 운영 환경 및 제한 사항에 대한 응용 프로그램의 지표입니다. 올바른 번호 찾기는 시행 착오의 과정입니다. 작업량과 작업량에 따라 대기열과 코어가 유휴 상태로 유지되므로 스레드 간 전환 비용이 동시 실행의 이점보다 많습니다. 올바른 숫자를 찾으려면 과학의 힘을 사용해야합니다. – nsfyn55

    관련 문제