針對評論的附加訊息

針對評論的附加訊息

我們的 java 系統已經運作了兩年多,從未出現過系統掛起的情況。我們有 2 台運行類似 java 軟體的實體伺服器(每台伺服器上有 2 個 JVM)形成一個叢集。據我所知,當我們為其中一台伺服器上的 2 個 JVM 之間的共享記憶體存取引入核心固定和mappedbus.io 時,崩潰才開始發生。系統掛起在兩週內只發生了 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 編號 2、4、6 固定在同一實體 CPU 上。超線程已開啟。

設定是這樣的。 JVM-A 有一個固定的繁忙自旋線程寫入內存映射文件X 並從內存映射文件Y 讀取。 Y。該訊息是最終發送到該worker上的市場的訂單指示。這是一個低延遲的交易平台。

這篇文章比我在這裡更好地探索了 LockSupport.parkNanoshttps://hazelcast.com/blog/locksupport-parknanos-under-the-hood-and-the-curious-case-of-parking/

我在 RAID 1 中有 2 個 10,000rpm HDD,帶有嵌入式 RAID 控制器。

關於目標延遲,是的,理論上我們可以將兩個 JVM 合併為一個,並完全擺脫這個記憶體映射檔案通道。不過,在這樣做之前還有其他考慮因素,所以我想先專注於了解這個技術問題。

最後,該伺服器上的 postgres 僅在復原模式下運行,它不是主伺服器。而且,我們的系統根本不做太多資料庫IO。它實際上只用於引導和一天的開始,並在夜間持續進行日間交易活動。其中一次崩潰發生在資料庫 IO 幾乎為零的時候。

答案1

在這種情況下,「阻塞」hung_task_timeout_secs意味著任務在這段時間內處於 D 不間斷狀態。 120 秒對於執行 I/O 來說是相當長的時間。

進行監控以取得該主機的指標。網路數據對此很有好處,它每秒都會在記憶體中收集大量內容,因此不會有大量磁碟 I/O。並且有漂亮的圖表。

檢查磁碟延遲,例如iostat -xz 1.等待單位數毫秒以上的時間不好。分享儲存是什麼:主軸、固態、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。

我們已經離開了美好並刪除了實時變化。這似乎已經解決了。傳統 RT 設定的最初目標可以透過改變我們的 busyspin/pinning/c-states/p-states 等方式來實現。

相關內容