의견에 대한 추가 정보

의견에 대한 추가 정보

우리는 시스템 중단 없이 2년 넘게 Java 시스템을 실행해 왔습니다. 클러스터를 형성하기 위해 유사한 Java 소프트웨어(각 서버에 2개의 JVM)를 실행하는 2개의 물리적 서버가 있습니다. 내가 알 수 있는 한, 서버 중 하나에 있는 2개의 JVM 간의 공유 메모리 액세스를 위해 코어 고정 및 mappedbus.io를 도입했을 때만 충돌이 발생하기 시작했습니다. 시스템 정지는 2주 동안 4번만 발생했으며 JVM 간 코어 고정 및 메모리 매핑 파일 액세스를 구성한 시스템에서만 발생했습니다. 해당 구성을 비활성화했기 때문에 메모리 매핑된 파일을 읽을 때 회전하기 위해 코어를 고정하지 않고 기본 앱 스레드를 고정하지 않습니다. 내가 핀이라고 말하면 고정된 코어에서 실행되는 스레드를 돌리느라 바쁘다는 것입니다.

그러나 그것은 완전히 일화입니다. 시스템이 매일 멈추지 않기 때문에 이것이 코어 고정이나 공유 메모리 액세스와 관련이 있다고 확신할 수 없습니다. 그러나 고정(및 바쁜 회전)이 비활성화되고 LockSupport.parkNanos(5000)를 사용하여 루프에서 공유 메모리에 액세스하면 시스템이 중단되지 않는 것 같습니다.

대기 시간은 우리에게 매우 중요하므로 이 "사용 중이 아닌" 설정은 일시적인 해결 방법일 뿐입니다.

또한 응용 프로그램을 동일한 서버로 옮겼으며 전체 시스템이 중단되는 현상도 경험할 수 있었습니다. 따라서 이것이 하드웨어 오류라고 볼 수는 없습니다.

그래서 충돌 전후의 로그를 파헤쳐 본 결과 이것이 나와 관련이 있는 것 같습니다. 이러한 스택이 여러 개 있습니다. 나는 여기에 첫 번째 것을 게시하고 있습니다. (즉, 이것이 postgres 자체와 관련이 있다고 생각하지 않습니다.)

kernel: [25738.874778] INFO: task postgres:2155 blocked for more than 120 seconds.
kernel: [25738.874833]       Not tainted 5.4.0-050400-generic #201911242031
kernel: [25738.874878] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
kernel: [25738.874928] postgres        D    0  2155   2056 0x00004000
kernel: [25738.874931] Call Trace:
kernel: [25738.874942]  __schedule+0x2e3/0x740
kernel: [25738.874948]  ? __wake_up_common_lock+0x8a/0xc0
kernel: [25738.874951]  schedule+0x42/0xb0
kernel: [25738.874957]  jbd2_log_wait_commit+0xaf/0x120
kernel: [25738.874961]  ? wait_woken+0x80/0x80
kernel: [25738.874965]  jbd2_complete_transaction+0x5c/0x90
kernel: [25738.874969]  ext4_sync_file+0x38c/0x3e0
kernel: [25738.874974]  vfs_fsync_range+0x49/0x80
kernel: [25738.874977]  do_fsync+0x3d/0x70
kernel: [25738.874980]  __x64_sys_fsync+0x14/0x20
kernel: [25738.874985]  do_syscall_64+0x57/0x190
kernel: [25738.874991]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
kernel: [25738.874993] RIP: 0033:0x7f96dc24b214
kernel: [25738.875002] Code: Bad RIP value.
kernel: [25738.875003] RSP: 002b:00007fffb2abd868 EFLAGS: 00000246 ORIG_RAX: 000000000000004a
kernel: [25738.875006] RAX: ffffffffffffffda RBX: 00007fffb2abd874 RCX: 00007f96dc24b214
kernel: [25738.875007] RDX: 00005635889ba238 RSI: 00005635889a1490 RDI: 0000000000000003
kernel: [25738.875009] RBP: 00007fffb2abd930 R08: 00005635889a1480 R09: 00007f96cc1e1200
kernel: [25738.875010] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
kernel: [25738.875011] R13: 0000000000000000 R14: 000056358899c5a0 R15: 0000000000000001

ps. 이 문제는 16.04와 커널 4.15에서도 발생했습니다. 18.04 및 5.0으로의 업그레이드는 시스템 중단을 해결하려는 시도였지만 아무런 변화가 없었습니다.

제가 고려한 또 다른 점은 아마도 이 흔적은 문제가 아니라 단지 증상일 뿐이라는 것입니다. 즉, 내 애플리케이션이 서버를 바인딩하여 다른 프로세스가 io를 차단하고 이러한 오류를 수신하게 했습니다. 하지만 서버가 완전히 멈추기 때문에 당시 애플리케이션의 상태를 알 수 없습니다.

의견에 대한 추가 정보

첫째, 다시 한번 강조하자면 코어 고정 + 공유 메모리가 낙타의 속담을 무너뜨리는 지푸라기라는 확실한 증거는 없지만 이는 변경 내역 및 중단을 기반으로 한 최선의 추측입니다.

CPU 모델은 Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz(터보 부스트 포함)입니다. 서버에는 2개가 있습니다. 동일한 물리적 CPU에 있는 것으로 생각되는 CPU 번호 2,4,6을 고정하고 있습니다. 하이퍼스레딩이 켜져 있습니다.

설정은 이렇습니다. JVM-A에는 메모리 매핑된 파일 X에 쓰고 메모리 매핑된 파일 Y에서 읽는 고정된 사용 중 스핀 스레드가 있습니다. JVM-B에는 메모리 매핑된 파일 X에서 읽고 메모리 매핑된 파일 Y에 다시 쓰는 고정된 사용 중인 스핀 스레드가 있습니다. JVM- B 고정된 읽기 스레드는 고정된 바쁜 스핀 작업자와 함께 방해자 링 버퍼에 메시지를 게시합니다. 메시지는 이 작업자에 대해 최종적으로 시장에 전송되는 주문 명령입니다. 이것은 대기 시간이 짧은 거래 플랫폼입니다.

이 게시물은 여기에서 할 수 있는 것보다 LockSupport.parkNanos에 대한 더 나은 탐색을 제공합니다.https://hazelcast.com/blog/locksupport-parknanos-under-the-hood-and-the-curious-case-of-parking/

RAID 컨트롤러가 내장된 RAID 1에 2개의 10,000rpm HDD가 있습니다.

목표 대기 시간에 관해서는 그렇습니다. 이론적으로는 두 개의 JVM을 하나로 병합하고 이 메모리 매핑 파일 채널을 완전히 제거할 수 있습니다. 하지만 그러기 전에 고려해야 할 다른 사항이 있기 때문에 먼저 이 기술적인 문제를 이해하는 데 집중하고 싶습니다.

마지막으로 이 서버의 Postgres는 복구 모드에서만 실행되고 있으며 기본이 아닙니다. 또한 우리 시스템은 데이터베이스 IO를 전혀 수행하지 않습니다. 실제로는 부트스트랩과 하루의 시작에만 사용되며 밤새도록 거래 활동을 지속합니다. 충돌 중 하나는 데이터베이스 IO가 거의 없을 때 발생했습니다.

답변1

이 경우 "차단됨"은 hung_task_timeout_secs작업이 오랫동안 중단할 수 없는 상태에 있었다는 의미입니다. 120초는 I/O를 수행하는 데 상당히 긴 시간입니다.

이 호스트에서 측정항목을 가져올 수 있는 모니터링을 진행하세요.순데이터이것은 좋습니다. 메모리에서 매초마다 많은 양의 항목을 수집하므로 디스크 I/O가 많지 않습니다. 그리고 좋은 그래프가 있습니다.

와 같은 디스크 대기 시간을 검토합니다 iostat -xz 1. 한 자리 ms 이상의 대기는 좋지 않습니다. 스핀들, 솔리드 스테이트, SAN LUN 등 스토리지가 무엇인지 공유하십시오.

회전 및 고정과 관련하여 스케줄러를 굶기게 만드는 것 같습니다. 문제의 특정 CPU 모델과 어떤 코어를 고정하여 무엇을 하는지 공유하세요. 어떻게 LockSupport.parkNanos()구현되나요?

검토 vmstat 1. 지속적으로 많은 작업을 실행 중이 r 거나 중단할 수 없는 b상태로 유지하는 것은 좋지 않습니다.

BPF를 설치하고 스크립트를 사용하여 작업 진단을 수집하는 것을 고려하세요.runqslower특정 임계값을 초과하는 대기 작업을 표시합니다. 매우 빠른 것이 이상적입니다. 임계값 단위는 마이크로초입니다.


잠시 뒤로 물러나서 이 제품의 디자인을 생각해 보세요.

지연 시간 목표는 정확히 무엇이며, 무엇을 얼마나 빠르게 수행합니까?

postgres가 동일한 호스트에서 실행되는 이유가 있습니까? 원격이고 TCP를 통해 액세스되는 경우 해당 I/O는 JVM 애플리케이션에 문제가 되지 않습니다.

답변2

좋아, 결국 문제는 아주 간단했습니다. 내 테스트 코드에서 이 요소 하나가 누락되었기 때문에 격리된 테스트에서는 컴퓨터가 충돌할 수 없었습니다. 문제는 공유 메모리나 코어 고정 자체와는 관련이 없습니다. 코어를 분리하면 스케줄러가 고갈될 수 있는 지점까지 사용 가능한 공유 리소스가 약간 줄어들었습니다. 왜냐하면...

두 JVM 모두 다음을 사용하여 실시간 우선순위로 설정되었습니다.

sudo renice -n -20 $!
sudo chrt -r -a -p 99 $!

전체 JVM이 최대 우선순위로 총 300개에 가까운 스레드로 범프되었습니다. 상대적으로 낮은 CPU 사용률에서도 150,000/s 이상의 컨텍스트 전환이 가능합니다.

우리는 niceness를 남겨두고 실시간 변경을 제거했습니다. 이것으로 해결된 것 같습니다. 레거시 RT 설정의 원래 목표는 바쁜 회전/고정/c-상태/p-상태 등의 방식을 변경하여 달성할 수 있습니다.

관련 정보