serverfault가 이에 대해 질문하기에 적합한 장소인지는 확실하지 않지만 Java 웹 애플리케이션에 대해 새로운 CPU 유형을 선택해야 한다면 어떤 선택을 하시겠습니까?
a) 32개 코어와 2.5Ghz 클럭 속도를 갖춘 CPU
또는
b) 코어가 8개이지만 클럭 속도가 3.8Ghz인 CPU
웹 애플리케이션의 수신 HTTP 요청 각각이 무료 Java 스레드에 의해 제공된다는 사실을 고려하면 a)를 선택하는 것이 합리적일 수 있습니다. 동시에 4배 더 많은 HTTP 요청을 처리할 수 있기 때문입니다. 그러나 반면에 CPU b)는 단일 HTTP 요청 처리를 훨씬 빠르게 완료할 수 있습니다.
어떻게 생각하나요?
참고 사항:
- 물리적 머신이어야 하며 이 경우 VM 또는 클라우드 솔루션은 옵션이 아닙니다.
- RAM은 중요하지 않습니다. 서버는 결국 512GB RAM을 갖게 됩니다.
- 캐싱: Java 웹 애플리케이션은 광범위한 캐싱 프레임워크를 갖추고 있으므로 선택은 실제로 CPU에 달려 있습니다.
답변1
tldr;실제 대답은 아마도 "더 많은 RAM"일 것입니다. 그러나 귀하가 질문한 대로 대답은 물론 상황에 따라 다릅니다. 그리고 다시 말하지만, 32개 코어(2.5Ghz)는 8개 코어(3.8Ghz)를 거의 확실히 능가할 것입니다. 즉, 4배 더 많은 코어와 1.5배 더 빠른 클럭입니다. 그다지 공정한 싸움은 아닙니다.
고려해야 할 몇 가지 요소는 트랜잭션 응답 시간, 동시 사용자 및 애플리케이션 아키텍처입니다.
트랜잭션 응답 시간 Java 애플리케이션이 몇 밀리초 내에 대부분의 요청에 응답한다면 더 많은 동시 요청을 처리하기 위해 더 많은 코어를 확보하는 것이 아마도 좋은 방법일 것입니다. 그러나 애플리케이션이 주로 더 오래 실행되고 더 복잡한 트랜잭션을 처리하는 경우 더 빠른 코어가 도움이 될 수 있습니다. (또는 그렇지 않을 수도 있습니다 - 아래 참조)
동시 사용자 및 요청 Java 애플리케이션이 많은 수의 동시 요청을 수신하는 경우 더 많은 코어가 도움이 될 것입니다. 동시 요청이 많지 않다면 추가 유휴 코어에 대한 비용을 지불할 수도 있습니다.
애플리케이션 아키텍처 앞서 언급한 장기 실행 요청은 앱 서버가 웹 서비스, 데이터베이스, kafaka/mq/등의 응답을 기다리는 데 대부분의 트랜잭션 시간을 소비하는 경우 더 빠른 코어의 이점을 많이 얻지 못합니다. 저는 20~30초의 트랜잭션을 가진 많은 애플리케이션을 보았습니다. 이 애플리케이션은 응답 시간 중 극히 일부만 애플리케이션 자체에서 처리하고 나머지 시간은 데이터베이스와 웹 서비스의 응답을 기다리는 데 소비했습니다.
또한 애플리케이션의 다양한 부분이 서로 잘 맞는지 확인해야 합니다. 각각의 요청을 처리하는 32개 또는 64개의 스레드가 JDBC 풀의 10개 연결 중 하나(파이썬 문제의 돼지라고도 함)를 기다리는 대기 상태를 유지하는 것은 별로 좋지 않습니다. 이제 약간의 계획과 설계를 통해 나중에 성능 문제를 해결하는 데 드는 시간을 많이 절약할 수 있습니다.
마지막으로, 어떤 CPU를 비교할 수 있습니까? 내가 찾을 수 있는 가장 저렴한 32코어 2.5GHz CPU는 8코어 3.8Ghz CPU보다 최소 3~4배 더 비쌉니다.
답변2
Java 웹 서버가 적절하게 구성되어 있다고 가정하면 더 많은 코어를 선택해야 합니다.
코어 수나 속도에 관계없이 일부 스레드가 대기 중인 동시 액세스인 세마포어와 같은 종속성은 여전히 존재합니다. 하지만 OS(멀티스레딩)보다는 CPU(코어)로 관리하는 것이 더 좋습니다.
그리고 어쨌든 32개 코어 @2.5Ghz는 8개 코어 @3.8Ghz보다 더 많은 스레드를 처리하고 더 좋습니다.
또한 CPU에서 발생하는 열은 무엇보다도 주파수에 따라 달라지며 이는 선형적이지 않습니다. 즉, 3.8Ghz는 3.8/2.5x보다 더 많은 열을 발생시킵니다(정확한 CPU 유형/브랜드에 따라 확인해야 합니다... 많은 사이트에서 자세한 정보를 제공합니다).
답변3
요청을 실행하는 데 약 100-200ms가 걸리며 대부분 처리 시간이고(실제 CPU 실행과 실제 메모리 액세스를 구분하기는 어렵지만) I/O가 거의 없으며 대기 시간이 매우 짧습니다. 데이터베이스 등
두 CPU 각각에서 실제로 걸리는 시간을 벤치마킹해야 하지만, 느린 CPU(32개 코어 포함)에서는 150ms가 걸리고 더 빠른 CPU(8개 코어만 포함)에서는 100ms가 걸린다고 가정해 보겠습니다.
그러면 첫 번째 CPU는 초당 최대 32/0.15 = 213개의 요청을 처리할 수 있습니다.
두 번째 CPU는 초당 최대 8/0.1 = 80개의 요청을 처리할 수 있습니다.
따라서 가장 큰 질문은 초당 몇 개의 요청을 예상하십니까?입니다. 초당 수십 개의 요청이 거의 없다면 첫 번째 CPU가 필요하지 않으며 두 번째 CPU는 각 요청에 대해 더 빠른 실행 시간을 제공합니다. 초당 100개 이상의 요청이 필요한 경우 첫 번째 요청이 적합합니다(또는 서버가 두 개 이상인 것이 더 합리적일 수 있습니다).
이는 매우 대략적인 추정치라는 점에 유의하십시오. 확실히 알 수 있는 유일한 방법은 실제 부하로 각 서버를 벤치마킹하는 것입니다. 위에서 설명한 대로 빠른 CPU나 코어 수가 많은 CPU는 메모리 액세스가 빠르게 부족해질 수 있습니다. 여기서는 다양한 CPU 캐시의 크기와 각 요청의 "작업 세트"가 매우 중요합니다. 그리고 이는 시스템 호출, 공유 리소스, I/O가 없는 진정한 CPU 바인딩 작업을 고려하는 것입니다.
답변4
서문
나는 두 번째로하고 싶다@PossilyUseful아마도 아님'에스확실히 유용한 답변.
tldr; 진짜 대답은 아마도 "더 많은 RAM"일 것입니다.
특히 이 점.
경고
그 자체로는 관리자가 많지 않습니다.
아마도 소프트웨어 엔지니어링 관점에 더 가깝습니다.
측정 외에는 대안이 없음
우리가 아는 것
그래서 기계는
- (Enterprise?) Java 기반 백엔드 애플리케이션을 실행할 예정입니다.
- 공개적으로(어쨌든 규모가 큰 컨텍스트 내에서) 클라이언트 요청을 처리하는 HTTP API를 노출합니다.
- 아마도 어떤 형태의 데이터베이스가 연결되어 있을 것입니다.
- 그렇지 않으면 I/O 바인딩이 많지 않은 것으로 설명됩니다.
- 타사 서비스의 가용성, 대기 시간 또는 처리량에 의존하지 않습니다.
모호한 그림은 아니지만 OP는 그림입니다. 그러나 동시에 답변을 제공할 만큼 충분한 데이터는 없습니다.OP 개별 상황과 관련된.
물론, 클럭 속도의 2/3인 32개 코어는~할 것 같은비교적 작은 속도 이점으로 코어의 1/4보다 더 나은 성능을 발휘합니다. 물론 생성된 열은 4GHz 임계값을 초과하는 클럭 속도에서는 잘 확장되지 않습니다. 그리고 물론, 맹목적으로 계란을 한 바구니에 담아야 한다면 일주일 중 언제든지 32개의 코어를 선택할 것입니다.
우리가 모르는 것
아직도 너무 많아요.
하지만,이러한 단순한 진실을 넘어, 보다 구체적이고 객관적인 답을 얻으려는 가설적인 시도에는 매우 회의적입니다.. 만약에가능합니다(그리고 단위 시간당 작업이 유효한 문제라는 점을 확신할 충분한 이유가 있습니다). 시스템을 실행하려는 하드웨어를 손에 넣으십시오.처음부터 끝까지 측정하고 테스트하세요..
안알려진 결정관련된그리고믿을 수 있는 데이터.
OP는 다음과 같이 썼습니다. 램은 중요하지 않아요
대부분의 경우 기억력은~이다병목 현상.
물론, OP주로 묻는다CPU 코어와 클럭 속도따라서 기억은 주제에서 벗어난 가장자리에 나타납니다.
하지만 나는 그렇지 않다고 생각한다. 나에게는 잘못된 전제에 기초한 질문일 가능성이 훨씬 더 높아 보입니다. 오해하지 마세요, @OP. 귀하의 질문은 주제에 부합하고 잘 표현되었으며 귀하의 우려는 분명히 현실입니다. 나는 귀하의 사용 사례에서 어떤 CPU가 "더 나은" 성능을 발휘할 것인지에 대한 대답이 (귀하에게) 전혀 관련이 있다고 확신하지 않습니다.
메모리가 CPU에 중요한 이유
메인 메모리는엄청나게 느림.
역사적으로 우리는 하드 드라이브와 비교할 때 RAM을 "빠른 유형의 스토리지"로 생각하는 경향이 있습니다. 그 비교의 맥락에서 그것은 여전히 사실입니다. 그러나 최근 수십 년 동안 프로세서 속도는 DRAM 성능보다 훨씬 더 빠른 속도로 지속적으로 성장해 왔습니다. 시간이 지남에 따라 이러한 발전으로 인해 일반적으로 알려진 현상이 발생했습니다."프로세서-메모리-간격".
프로세서와 메모리 속도 사이의 차이(출처: Carlos Carvalho, Departamento de Informática, Universidade do Minho)
캐시 라인 가져오기메인 메모리에서 CPU 레지스터로의 시간은 약 100클럭 사이클을 차지합니다.시간의. 이 시간 동안 운영 체제는 x86 아키텍처의 4개(?) 코어 중 하나에 있는 두 개의 하드웨어 스레드 중 하나를 다음과 같이 보고합니다.바쁘다.
지금까지는유효성이 하드웨어 스레드에 관한 것은 당신의 OS가 거짓말을 하는 것이 아닙니다.기다리느라 바쁘다. 그러나 처리 장치 자체는 자신을 향해 크롤링하는 캐시 라인을 무시하고사실상 유휴 상태.
이 시간 동안에는 지침/작업/계산이 수행되지 않습니다.
+----------+---------------+---------------------------------------------------------------------------------------------------+
| Type of | size of | Latency due to fetching a cache line |
| mem / op | cache +--------+--------+------------+--------------------------------------------------------------------+
| | (register) | clock | real | normalized | now I feel it |
| | | cycles | time | | |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
| tick | 16KB | 1 | 0.25ns | 1s | Dinner is already served. Sit down, enjoy. |
| | *the* 64 Bits | | | | |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
| L1 | 64KB | 4 | 1ns | 4s | Preparations are done, food's cooking. |
| | | | | | Want a cold one to bridge the gap? |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
| L2 | 2048KB | 11 | ~3ns | 12s | Would you be so kind as to help me dice the broccoli? |
| | | | | | If you want a beer, you will have to go to the corner store. |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
| L3 | 8192KB | 39 | ~10ns | 40s | The car is in the shop, you'll have to get groceries by bike. |
| | | | | | Also, food ain't gonna cook itself, buddy. |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
| DRAM | ~20GB | 107 | ~30ns | 2min | First year of college. First day of the holiday weekend. |
| | | | | | Snow storm. The roommate's are with their families. |
| | | | | | You have a piece of toast, two cigarettes and 3 days ahead of you. |
+----------+---------------+--------+--------+------------+--------------------------------------------------------------------+
시리즈 칩 의 지연 시간 수치
Core-i7-9XX
(출처: 스콧 마이어스, 2010)
결론 코어와 클럭 속도에 대해 토론하는 대신 적절한 측정이 옵션이 아닌 경우과도한 하드웨어 예산에 대한 가장 안전한 투자는 CPU 캐시 크기입니다..
그렇다면 메모리가 정기적으로 개별 하드웨어 스레드를 유휴 상태로 유지한다면 확실히 더 많은 ~소종~ 코어가 해결책일까요?
이론적으로 소프트웨어가 준비되면 멀티/하이퍼스레딩~할 수 있었다빨리
지난 몇 년간의 세금 신고서(예: 총 8년간의 데이터)를 보고 있다고 가정해 보겠습니다. 연간(행)에 12개의 월별 값(열)을 보유하고 있습니다.
이제 바이트는 256개의 개별 값을 보유할 수 있습니다(8개의 개별 이진수로 각각 2개의 상태를 가정할 수 있으므로 8^2 = 256
고유한 상태의 순열이 발생합니다. 통화에 관계없이 256은 또한 논의를 위해 가장 작은 액면가("센트")는 중요하지 않다고 가정해 보겠습니다(모든 사람이 주요 액면가의 정수 값을 얻습니다). 마지막으로 고용주가 급여 격차를 알고 있다고 가정합니다. 고위 경영진과 정규 인력은 완전히 다른 회계 시스템에 선택된 소수를 유지합니다.
unsigned
따라서 이 단순화된 시나리오에서는 위에서 언급한 메모리 공간의 두 배, 즉 2바이트(또는 "하프워드")가 형식, 즉 범위를 나타내는 형식 으로 사용될 때 모든 직원의 월급 값을 표현하기에 충분하다고 가정해 보겠습니다 [0, 2^16 = 65536)
.
따라서 선택한 언어/RDBS/OS에서 이제 균일한 데이터 크기(2바이트/16비트) 값을 가진 행렬(일부 2차원 데이터 구조, "목록 목록")을 보유하고 있습니다.
C++에서는 std::vector<std::vector<uint16_t>>
. 나는 당신이 Java에서도 vector
of vector
를 사용할 것이라고 추측합니다.short
자, 여기에상품 질문:
인플레이션(또는 주소 공간에 쓰는 다른 임의의 이유)을 위해 8년 동안의 값을 조정하고 싶다고 가정해 보겠습니다. 우리는 16비트 값의 균일한 분포를 보고 있습니다. 매트릭스의 모든 값을 한 번 방문하여 읽고 수정한 다음 주소 공간에 써야 합니다.
데이터를 탐색하는 방법이 중요합니까?
정답은:응, 정말 그렇지. 먼저 행(내부 데이터 구조)을 반복하면 동시 실행 환경에서 거의 완벽한 확장성을 얻을 수 있습니다. 여기서는 추가 스레드로 인해 하나의 데이터 절반, 다른 하나의 데이터 절반이 작업을 두 배 빠르게 실행합니다. 스레드가 4개? 성능이 4배 향상됩니다.
그러나 열을 먼저 수행하기로 선택한 경우, 두 개의 스레드가 작업을 실행합니다상당히 느림. 주요 순회 방향 선택으로 인한 부정적인 영향을 완화(!)하기 위해서만 약 10개의 병렬 실행 스레드가 필요합니다. 그리고 코드가 단일 실행 스레드에서 실행되는 한 차이를 측정할 수 없습니다.
+------+------+------+------+------+------+------+
| Year | Jan | Feb | Mar | Apr | ... | Dec |
+------+------+------+------+------+------+------+
| 2019 | 8500 | 9000 | 9000 | 9000 | 9000 | 9000 | <--- contiguous in memory
+------+------+------+------+------+------+------+
| 2018 | 8500 | 8500 | 8500 | 8500 | 8500 | 8500 | <--- 12 * 16Bit (2Byte)
+------+------+------+------+------+------+------+
| 2017 | 8500 | 8500 | 8500 | 8500 | 8500 | 8500 | <--- 3 * (4 * 16Bit = 64Bit (8Byte)
+------+------+------+------+------+------+------+
| ... | 8500 | 7500 | 7500 | 7500 | 7500 | 7500 | <--- 3 cache lines
+------+------+------+------+------+------+------+
| 2011 | 7500 | 7200 | 7200 | 7200 | 7200 | 7200 | <--- 3 lines, likely from the same
+------+------+------+------+------+------+------+ virtual memory page, described by
the same page block.
OP는 다음과 같이 썼습니다. a) 코어가 32개이고 클럭 속도가 2.5Ghz인 CPU
또는
b) 코어가 8개 있지만 클럭 속도가 3.8Ghz인 CPU
다른 모든 조건은 동일합니다.
-->캐시 크기, 메모리 크기, 하드웨어의 예측적 프리페칭 기능 및 실제로 병렬화를 활용할 수 있는 소프트웨어 실행을 클럭 속도보다 더 중요하게 고려하십시오.
--> 타사 분산 시스템에 의존하지 않더라도프로덕션 환경에서 실제로 I/O에 묶여 있지 않은지 확인하세요.내부에 하드웨어가 있어야 하고 AWS/GCloud/Azure/Heroku/Whatever-XaaS-IsHipNow가 이러한 어려움을 처리하도록 할 수 없다면 DB에 설치한 SSD에 투자하세요. 당신이하는 동안~ 아니다데이터베이스가 애플리케이션과 동일한 물리적 시스템에 존재하도록 하려면 네트워크 거리(여기에서도 대기 시간 측정)가 가능한 짧은지 확인하십시오.
--> 동시성을 위해 구축된 의심의 여지가 없는 유명하고 검증된 최고급 "엔터프라이즈 수준" HTTP 서버 라이브러리를 선택하는 것만으로는 충분하지 않습니다. 경로에서 실행하는 타사 라이브러리가 있는지 확인하세요. 내부 코드도 있는지 확인하십시오.
이 경우 VM 또는 클라우드 솔루션은 옵션이 아닙니다.
나는 이것을 얻는다.
다양한 타당한 이유가 존재합니다.
그건 그래야만 해ㅏ물리적 머신 [...]
[...] 32개 코어와 2.5Ghz 클럭 속도를 갖춘 CPU
그러나 이것은 그리 많지 않습니다.
AWS나 Azure 모두 분산 시스템, 마이크로 클러스터링 또는 로드 밸런싱을 발명하지 않았습니다. MegaCorp 스타일 리소스 없이 베어메탈 하드웨어에 설정하는 것은 더 고통스럽습니다.~할 수 있다자신의 거실에서 바로 K8 클러스터의 분산 메시를 실행해 보세요. 또한 자체 호스팅 프로젝트에도 반복적인 상태 확인 및 최대 부하 시 자동 프로비저닝을 위한 도구가 있습니다.
OP는 다음과 같이 썼습니다. 램은 중요하지 않아요
다음은 ~가설적인~ 재현 가능한 시나리오입니다. zram을 스왑 공간으로 활성화하세요. 왜냐하면 RAM은 저렴하고 중요하지 않기 때문입니다. 이제 페이징이 자주 발생하지 않는 꾸준한 메모리 집약적 작업을 실행하세요. 심각한 LRU 반전 지점에 도달하면 팬이 시끄러워지고 CPU 코어가 뜨거워집니다. 메모리 관리(스왑 안팎으로 쓰레기 이동)를 처리하느라 바쁘기 때문입니다.
OP는 다음과 같이 썼습니다. 램은 중요하지 않아요
내가 충분히 명확하게 표현하지 않은 경우: 이 의견을 재고해야 한다고 생각합니다.
TL, DR?
32개 코어.
더~이다더 나은.