一般 JSOR 問題 (僅限Linux )
使用 Java™ Socket over Remote Direct Memory Access (JSOR) 來利用高效能網路基礎架構 (例如 InfiniBand)。 若要使用 JSOR ,您必須設定、配置及調整各種資源。 如果未正確執行,可能會發生問題。
RDMA Socket 或執行緒建立失敗
無法建立執行緒或「遠端直接存取記憶體 (RDMA)」Socket 時,可能會發生 JSOR 問題。 此問題可能是透過 RDMA 傳輸執行並行連線所導致。
可能原因
- 依預設, RDMA Socket 緩衝區已固定或已鎖定記憶體。 環境中的受限 memlock 設定可能會導致無法建立或登錄新的 RDMA Socket。
- 當您執行並行連線時,每一個 RDMA Socket 都會隱含地使用檔案描述子進行事件追蹤。 如果使用者開啟檔案數上限限制太低,則 Socket 建立可能會失敗。
- 當您執行並行連線時,執行緒建立失敗的原因可能是使用者處理程序上限太低。 如需相關資訊,請參閱下列 Technote: java.lang.OutOfMemoryError。
緩解
- 若要避免 Socket 建立失敗,請檢查
ulimit -l設定,並根據 Socket 緩衝區的用量將 memlock 設定變更為適當的值。 - 若要在執行並行連線時避免 Socket 建立失敗,請檢查
ulimit -n設定,並根據應用程式的可調整性需求將 nofile 設定變更為適當的值。 - 若要在執行並行連線時避免執行緒建立失敗,請檢查
ulimit -u設定,並根據應用程式的可調整性需求將 nproc 設定變更為適當的值。
RDMA 網路提供者起始設定失敗
當您執行 32 位元 JVM 時,如果在 64 位元 Linux 作業系統上「遠端直接存取記憶體 (RDMA)」網路提供者起始設定失敗,則可能會發生 JSOR 問題。
在 RDMA 網路起始設定階段期間, JSOR 執行時期環境會檢查相容 OFED 執行時期程式庫的可用性。 如果執行時期環境找不到並載入 librdmacm.so 和 libibverbs.so 32 位元程式庫,您可能會看到這個問題。 若要避免此問題,請在 64 位元 Linux® 機器上安裝 32 位元 OFED 執行時期程式庫以及一般 64 位元程式庫。
RDMA 連線失敗
當「遠端直接存取記憶體 (RDMA)」用戶端無法連接至 RDMA 伺服器時,可能會發生 JSOR 問題。
相同主機上的用戶端和伺服器
如果用戶端和伺服器位於相同的主機上,則預期會有此行為,因為目前不支援 RDMA 迴圈回復。 若要成功連線,用戶端和伺服器都應該位於透過 RDMA 網路介面配接卡由 InfiniBand 交換器連接的不同主機上。
不同子網路上的用戶端和伺服器
RDMA 用戶端及伺服器應該位於相同的網路上,由一般 InfiniBand 交換器連接,並由單一子網路管理程式管理。 如果 RDMA 用戶端及伺服器必須位於不同的子網路上,請確定已在軟硬體層次啟用網路間交換及封包轉遞。
相同子網路上的用戶端和伺服器
如果用戶端及伺服器位於相同的子網路上,則連線失敗可能是由不正確的用戶端或伺服器配置檔或一部或兩部主機上不正確的 InfiniBand 設定所導致。
請確定已正確定義配置檔中的規則項目,如 -Dcom.ibm.net.rdma.conf (僅限Linux )。
- 請確定通訊所涉及的每一部主機都有適當的 InfiniBand 主機通道配接卡或 RDMA 網路介面卡,且具有有效的 InfiniBand 位址 (以字首 ib開頭的介面)。
- 請確定每一個 InfiniBand 埠都在作用中,且已適當地設定最大傳送裝置。 若要檢查最大傳送單元,請執行下列其中一個 OFED 執行時期指令: ibstat 或 ibv_devinfo。
- 請確定 ifconfig 指令會列出所有 InfiniBand 介面,且每一個介面都有有效的 IP 位址。
- 選擇兩個向子網路管理程式登錄的有效 InfiniBand 位址,以用於訊框 JSOR 配置規則,然後以您選擇的 InfiniBand 位址執行 rping 指令,來驗證主機與用戶端機器之間是否可以進行基本 RDMA 通訊。
- 同樣地,執行 ibv_rc_pingpong 指令。
- 同樣地,執行 ib_read_bw 和 ib_write_bw 指令。
RDMA 連線重設異常狀況
嘗試將小型資料區塊數百萬次傳送至單一 RDMA 伺服器的「並行遠端直接存取記憶體 (RDMA)」用戶端可能會擲出連線重設異常狀況。
Java Sockets over Remote Direct Memory Access (JSOR) 使用 R-Socket 通訊協定作為在 RDMA 之上實作 Socket 層次 API 的基礎。 R-Socket 通訊協定使用傳送及接收佇列大小作為基礎,在傳送端與接收端之間實作資料流程及事件控制。 當數個平行用戶端嘗試傳送少量資料百萬次時,由於佇列大小不足,它們可能會遇到連線重設異常狀況。 此行為是因為佇列大小指定可在任一端排入佇列的工作量。
因為預設佇列大小很大 (請參閱 JSOR 環境設定 (僅限Linux )) ,所以只有在極少數情況下才需要調整佇列大小。 您應該根據應用程式的工作量性質來決定佇列大小。 傳送及接收作業的數目上限及頻率特別重要。 沒有用於判定最佳佇列大小的一般公式。
RDMA 通訊似乎當掉
當您以無法預期的訊息大小執行 RPC 型工作量時,用戶端與伺服器之間的「遠端直接存取記憶體 (RDMA)」通訊似乎當掉。
Java Sockets over Remote Direct Memory Access (JSOR) 使用 R-Socket 通訊協定作為在 RDMA 之上實作 Socket 層次 API 的基礎。 為了適當地傳送資料, R-Socket 通訊協定需要協調傳送端和接收端兩者。 接收端必須備妥可讓傳送端放入資料的接收緩衝區。 此行為不同於 TCP/IP ,在 TCP/IP 中視需要動態配置緩衝區。 如果事先沒有足夠的接收緩衝區可用,則 RDMA 接收作業會失敗。 如需相關資訊,請參閱 Remote Direct Memory Access Transport for Remote Procedure Call之 IETF 草稿的流程控制區段。
依預設, JSOR 實作提供小於 50 KB 大小的小型傳送及接收緩衝區。 當 RDMA 用戶端或伺服器嘗試以區塊 (例如 1 KB) 傳送大型有效負載 (例如 2 MB 或 4 MB) 時,在端點之間沒有同步資料流程的單一方向,接收緩衝區可能會耗盡,導致當掉狀況。 R-Socket 通訊協定嘗試回收接收緩衝區,但如果補貨速率小於資料傳送速率,則無法進行進度。 當數百個平行用戶端嘗試在相同的 RDMA 傳輸上執行相同的作業時,這些效果會更明顯,因為用戶端會競爭相同的實體網路資源集。 R-Socket 通訊協定需要很長時間才能從此狀況回復,因為它依賴重試及接收端未備妥的負面確認來進行進度。 在最差的情況下,此行為可能會導致端點之間的死鎖狀況。
同樣地,傳送緩衝區的大小應該足以將資料傳送至對應的接收緩衝區。
緩解
若為 Java RPC 應用程式,在正式作業環境中部署應用程式之前,請先調整緩衝區大小。 根據應用程式的工作量性質及有效負載大小上限來設定緩衝區大小。 沒有用於判定最佳緩衝區大小的一般公式。 如需相關資訊,請參閱 JSOR 環境設定 (僅限Linux )。
啟用應用程式或執行時期資料傳送逾時,可讓用戶端取消並重試資料傳送,並在必要時增加緩衝區大小。 請參閱下列 APAR 以取得範例: PM52124: eXtreme Scale 用戶端上的 OutOfMemoryError 錯誤可能會導致網格失敗。 在此範例中,記憶體不足導致伺服器執行緒停留在 socketWrite() 方法中。 建議的解決方案是設定 com.ibm.CORBA.SocketWriteTimeout 內容。
零複製功能發生問題
啟用零複製功能時 Java 應用程式當掉
當您使用零複製功能時,由於資料來源與資料接收槽之間需要內部同步化,如果您只對一個端點啟用零複製功能,用戶端或伺服器應用程式可能會當掉。
- 當您使用零複製功能時,請避免使用相同的 Socket 描述子來進行平行讀取及寫入作業。
- 請確定已在兩個端點上啟用零複製功能。 如需相關資訊,請參閱 -Dcom.ibm.net.rdma.zeroCopy (僅限Linux )。
- 確保在兩個端點上設定相同的零複製臨界值。 如需相關資訊,請參閱 -Dcom.ibm.net.rdma.zeroCopyThreshold (僅限Linux )。
Java 應用程式未使用零複製功能
即使在您指定 -Dcom.ibm.net.rdma.zeroCopy=true 參數之後, Java 應用程式也可能不會使用零複製功能。
- 您已指定 -Dcom.ibm.net.rdma.zeroCopy=true 參數。
- 在 Java 讀取和寫入呼叫內傳遞的緩衝區大小超出 -Dcom.ibm.net.rdma.zeroCopyThreshold 參數指定的值。 如需此參數的相關資訊,請參閱 -Dcom.ibm.net.rdma.zeroCopyThreshold (僅限Linux )。
- socketRead0Direct
- socketWrite0Direct
- RDMA_ReadDirect
- RDMA_SendDirect
Java 應用程式不調整
零複製功能設計用於大型資料傳送,一次幾個。 由於內部同步化以及資源配置和管理額外需要,因此可調整性受到所傳送資料大小的限制。
請確保使用實務範例接近零複製模式中資料傳送的檔案傳送 (FTP) 類型。
Fork 相容模式遇到問題
在 Java 用戶端與原生分出伺服器之間,以分出相容模式運作可能有幾個相關問題。
原生伺服器錯誤訊息 librdmacm: Fatal: unable to open RDMA
device
- POWER ® PC 系統,搭配 Mellanox RDMA over converged ethernet (RoCE) MT26448 配接卡
- Redhat Enterprise Linux (RHEL) v6.4
- MLNX_OFED_LINUX-2.0-3.0.0
如果您遇到此問題,請升級至最新版本的作業系統及 OFED 軟體。 如果問題持續存在,請考量升級至最新版本的 Mellanox RoCE 配接卡。
Java 用戶端當掉
在分出相容模式中,當系統連接至原生分出伺服器時, Java 用戶端可能會當掉。 此問題與 RSocket 預載程式庫相關聯。 在內部處理 fork() 支援時,程式庫會建立具名號誌 /rsocket_fork。 不過,完成時, R-Socket 程式庫不會移除號誌,該號誌會持續保存,直到系統重新開機為止。 先前呼叫中此具名號誌的任何陳舊鏈結或值都會封鎖原生伺服器,使其無法接受遠端用戶端連線。
若要暫時解決此問題,請在 fork() 預載開始之前,使用 rm 指令來解除鏈結 /rsocket_fork 具名號誌。 在 Red Hat Enterprise Linux (RHEL) 上,您可以在 /dev/shm目錄中找到具名號誌。 這些檔案的字首為 sem.。
Java 用戶端不調整
RSocket 通訊協定目前只對在理想條件下執行的簡式應用程式提供分出預載支援。 在預先載入分出的處理程序時, RSocket 程式庫會使用封鎖語意,將連線移轉至 RDMA。
因此, RSocket 中 fork() 方法的現行支援本質上是不可調整的。 嘗試使用原生交互作業能力功能連接至原生分出伺服器的 Java 多執行緒用戶端可能會遇到大量失敗連線。 若要緩解此問題,請將用戶端連線重試次數增加到多個。