더 큰 스레드 풀을 사용하는 대신 비동기 요청을 사용하는 이유는 무엇입니까?
네덜란드에서 Tech Days를 진행하는 동안 Steve Sanderson은 C#5, ASP.NET MVC 4 및 비동기식 웹에 대해 발표했습니다.
그는 요청이 완료되는 데 시간이 오래 걸리면 스레드 풀의 모든 스레드가 사용 중이 되고 새로운 요청이 기다려야 한다고 설명했습니다.서버가 부하를 처리하지 못하고 모든 것이 느려집니다.
그런 다음 비동기 웹 요청을 사용하면 작업이 다른 스레드로 위임되고 스레드 풀이 새 수신 요청에 신속하게 응답할 수 있기 때문에 성능이 향상되는 방법을 보여주었습니다.그는 이를 시연하기도 했고, 50개의 동시 요청이 처음에는 50*1초가 걸렸지만 비동기 동작은 총 1.2초에 불과하다는 것을 보여주었습니다.
하지만 이것을 보고도 여전히 몇 가지 의문점이 있습니다.
더 큰 스레드 풀을 사용할 수 없는 이유는 무엇입니까?비동기/대기를 사용하면 처음부터 스레드 풀을 늘리는 것보다 다른 스레드를 실행하는 속도가 느려지지 않습니까?우리가 실행하는 서버가 갑자기 더 많은 스레드를 얻는 것과 같은 것이 아닙니다.
사용자의 요청이 아직 비동기 스레드가 완료되기를 기다리는 중입니다.풀의 스레드가 다른 작업을 수행하는 경우 '은(는) 어떻게 됩니까?UI 스레드가 계속 사용 중입니까?스티브는 '어떤 일이 끝났을 때를 아는 똑똑한 커널'에 대해 언급했습니다.이것은 어떻게 작동합니까?
이것은 매우 좋은 질문이며, 비동기 IO가 왜 그렇게 중요한지 이해하는 것이 중요합니다.C# 5.0에 새로운 비동기/대기 기능이 추가된 이유는 비동기 코드 작성을 단순화하기 위해서입니다.서버에서 비동기 처리를 지원하는 것은 새로운 것이 아니지만 ASP.NET 2.0 이후에 존재합니다.
Steve가 보여준 것처럼, 동기식 처리에서는 ASP.NET(및 WCF)의 각 요청이 스레드 풀에서 스레드 하나를 가져옵니다.그가 데모한 문제는 "스레드 풀 기아"라고 불리는 잘 알려진 문제입니다.서버에서 동기 IO를 만들면 IO가 지속되는 동안 스레드 풀 스레드가 차단된 상태로 유지됩니다(아무 것도 하지 않음).스레드 풀의 스레드 수에 제한이 있기 때문에 로드 시 IO를 기다리는 동안 모든 스레드 풀 스레드가 차단되고 요청이 대기 중이기 때문에 응답 시간이 증가할 수 있습니다.모든 스레드가 IO가 완료되기를 기다리고 있기 때문에 응답 시간이 루프를 통과하더라도 CPU 점유율이 0%에 가깝습니다.
당신이 묻고 있는 것은 (왜 우리는 더 큰 스레드 풀을 사용할 수 없습니까?) 매우 좋은 질문입니다.사실, 이것이 지금까지 대부분의 사람들이 스레드 풀 기아 문제를 해결해온 방법입니다. 스레드 풀에 스레드를 더 많이 가지고 있어야 합니다.Microsoft의 일부 문서에서는 스레드 풀 부족이 발생할 수 있는 상황에 대한 해결책으로 이를 표시하기도 합니다.이것은 허용 가능한 솔루션이며, C# 5.0 이전까지는 코드를 완전히 비동기식으로 다시 쓰는 것보다 훨씬 쉬웠습니다.
이 접근 방식에는 몇 가지 문제가 있습니다.
모든 상황에서 사용할 수 있는 값은 없습니다. 필요한 스레드 풀 스레드 수는 IO 기간과 서버 로드에 따라 선형적으로 달라집니다.안타깝게도 IO 지연 시간은 대부분 예측할 수 없습니다.다음은 예입니다.ASP.NET 응용 프로그램의 타사 웹 서비스에 HTTP 요청을 한다고 가정해 보겠습니다. 이 요청은 완료하는 데 약 2초 정도 걸립니다.스레드 풀이 부족해지면 스레드 풀 크기를 200개의 스레드로 늘리기로 결정하고 다시 정상적으로 작동합니다.문제는 아마도 다음 주에 웹 서비스에 기술적인 문제가 발생하여 응답 시간이 10초로 증가할 것이라는 것입니다.갑자기 스레드 풀 부족이 다시 발생했습니다. 스레드가 5배 더 오래 차단되었기 때문입니다. 따라서 이제 그 수를 5배에서 1,000개의 스레드로 늘려야 합니다.
확장성 및 성능:두 번째 문제는 그렇게 해도 요청당 하나의 스레드를 계속 사용한다는 것입니다.스레드는 값비싼 리소스입니다..NET의 각 관리 스레드에는 스택에 대해 1MB의 메모리 할당이 필요합니다.5초 동안 지속되고 초당 500개의 요청을 로드하는 웹 페이지의 경우 스레드 풀에 2,500개의 스레드가 필요합니다. 즉, 아무것도 하지 않고 앉아 있는 스레드 스택에 2.5GB의 메모리가 필요합니다.그런 다음 컨텍스트 전환 문제가 발생하여 시스템 성능에 큰 영향을 미칩니다(웹 애플리케이션뿐만 아니라 시스템의 모든 서비스에 영향을 미칩니다).Windows(윈도우)는 대기 중인 스레드를 무시하는 작업을 상당히 잘 수행하지만 이렇게 많은 스레드를 처리하도록 설계되지 않았습니다.실행 중인 스레드 수가 시스템의 논리적 CPU 수(일반적으로 16개 이하)와 같을 때 가장 높은 효율성을 얻을 수 있습니다.
따라서 스레드 풀의 크기를 늘리는 것이 해결책이며, 사람들은 10년 동안 (마이크로소프트의 자체 제품에서도) 메모리 및 CPU 사용량 측면에서 확장성과 효율성이 떨어지고, 항상 IO 지연 시간이 갑자기 증가하여 굶주림을 초래할 수 있습니다.C# 5.0 이전까지 비동기 코드의 복잡성은 많은 사람들에게 문제가 될 만한 가치가 없었습니다.async/wait는 모든 것을 지금처럼 바꿔놓습니다. 비동기 IO의 확장성과 간단한 코드 작성의 이점을 동시에 누릴 수 있습니다.
자세한 내용: http://msdn.microsoft.com/en-us/library/ff647787.aspx "웹 서비스 호출이 진행되는 동안 추가 병렬 처리를 수행할 기회가 있을 때 비동기 호출을 사용하여 웹 서비스 또는 원격 개체를 호출합니다. 나가는 웹 서비스 호출은 ASP.NET 스레드 풀의 스레드를 사용하여 이루어지므로 가능한 경우 웹 서비스에 대한 동기식(차단) 호출을 방지합니다. 호출을 차단하면 다른 수신 요청을 처리하는 데 사용할 수 있는 스레드 수가 줄어듭니다."
- 비동기/대기는 스레드를 기반으로 하지 않으며 비동기 처리를 기반으로 합니다.ASP.NET에서 비동기 대기를 수행하면 요청 스레드가 스레드 풀로 반환되므로 비동기 작업이 완료될 때까지 요청을 처리하는 스레드가 없습니다.요청 오버헤드가 스레드 오버헤드보다 낮으므로 비동기/대기가 스레드 풀보다 더 잘 확장될 수 있음을 의미합니다.
- 요청에 미결된 비동기 작업 수가 있습니다.이 개수는 의 ASP.NET 구현에 의해 관리됩니다.
SynchronizationContext
자세한 내용은 다음을 참조하십시오.SynchronizationContext
내 MSDN 기사에서 - ASP.NET의 방법을 다룹니다.SynchronizationContext
원리 및 방법await
사용하다SynchronizationContext
.
wait 에는 ASP했습니다. 페이지를 할 수 ASP.NET과 요소를 사용할 수 있습니다. 비동기 페이지를 사용할 수 있으며 다음과 같은 EAP 구성 요소를 사용할 수 있습니다.WebClient
은 (이벤트 기반 비동기식 프로그래밍)을 비동기식 입니다.SynchronizationContext
도 )를 사용합니다. 비동기/대기도 사용합니다.SynchronizationContext
훨씬 쉬운 구문을 가지고 있습니다.
스레드 풀을 작업을 위해 고용한 작업자의 집합으로 상상해 보십시오.작업자가 코드에 대한 빠른 CPU 명령을 실행합니다.
이제 여러분의 작업은 다른 느린 사람의 작업에 의존하게 됩니다. 느린 사람은 디스크나 네트워크입니다.예를 들어, 여러분의 작업은 두 부분으로 구성될 수 있습니다. 하나는 느린 사람의 작업 전에 실행되어야 하고 다른 하나는 느린 사람의 작업 후에 실행되어야 합니다.
당신은 당신의 직원들에게 당신의 일을 어떻게 하라고 조언할 것입니까?각 직원에게 "이 부분을 먼저 하고, 그 느린 사람이 끝날 때까지 기다렸다가 두 번째 부분을 하세요."라고 말할 수 있습니까? 모든 직원이 그 느린 사람을 기다리고 있는 것처럼 보이고 새로운 고객을 만족시킬 수 없기 때문에 직원 수를 늘릴 수 있습니까?아니!
대신 각 작업자에게 첫 번째 파트를 부탁하고 작업이 끝나면 느린 사람에게 다시 와서 줄에 메시지를 놓으라고 요청합니다.각 작업자(또는 작업자의 전용 하위 집합)에게 대기열에서 완료된 메시지를 찾고 작업의 두 번째 부분을 수행하도록 지시합니다.
위에서 언급한 스마트 커널은 느린 디스크 및 네트워크 IO 완료 메시지를 위해 이러한 대기열을 유지할 수 있는 운영 체제 기능입니다.
언급URL : https://stackoverflow.com/questions/9453560/why-use-async-requests-instead-of-using-a-larger-threadpool
'source' 카테고리의 다른 글
눈금 레이블 값은 숨기지만 축 레이블은 유지 (0) | 2023.07.18 |
---|---|
기존 정보를 보존하면서 다른 유형 및 메시지로 예외 다시 발생 (0) | 2023.07.13 |
정수를 16진수로, 16진수를 정수로 변환 (0) | 2023.07.13 |
Oracle Solaris 11에 GCC 설치 (0) | 2023.07.13 |
R 메모리 관리 / 크기가 nMb인 벡터를 할당할 수 없습니다. (0) | 2023.07.13 |