共用方式為


Azure NetApp Files 的 Linux 並行最佳做法 - 工作階段位置與位置表項目

本文可協助您瞭解 Azure NetApp Files NFS 通訊協定工作階段位置和位置表項目的並行最佳做法。

NFSv3

NFSv3 沒有交涉用戶端與伺服器之間並行存取的機制。 用戶端和伺服器都會定義自己的限制,不需要向對方查詢。 為了達到最佳效能,您應該將用戶端 sunrpc 位置表項目數上限設為與支援的數目一致,而不需在伺服器上回推。 當用戶端迫使伺服器網路堆疊無法處理工作負載時,伺服器會藉由縮短連線的時間長度來回應,這不是理想的效能情況。

根據預設,新式 Linux 核心會將每個連線 sunrpc 位置表項目大小 sunrpc.tcp_max_slot_table_entries 定義為支援 65,536 個未完成的作業,如下表所示。

Azure NetApp Files NFSv3 伺服器
每個連線的執行內容上限
Linux 用戶端
每個連線的 sunrpc 位置表項目預設上限
128 65,536

這些位置表項目會定義並行項目的上限。 將值設這麼高並非必要做法。 例如,使用稱為利特爾法則的佇列理論,您會發現 I/O 速率取決於並行 (也就是未完成的 I/O) 和延遲。 因此,演算法證明了 65,536 個位置,比起驅動極高工作負載需求實際所需的高出多個量級。

Littles Law: (concurrency = operation rate × latency in seconds)

並行等級 155 對於使用 Oracle Direct NFS 達到每秒 155,000 個 Oracle DB NFS 作業就已足夠,這是與 nconnect 掛接選項類似的技術:

  • 考慮延遲為 0.5 毫秒,需有 55 個並行才能達到 110,000 IOPS。
  • 考慮延遲為 1 毫秒,需有 155 個並行才能達到 155,000 IOPS。

Oracle DNFS latency curve

請參閱 Azure NetApp Files 單一磁碟區上的 Oracle 資料庫效能取得詳細資訊。

可調整的 sunrpc.tcp_max_slot_table_entries 是連線層級微調參數。 最佳做法是將此值設為每個連線 128 或更少,整個環境不超過 10,000 個位置。

根據並行建議的位置計數範例

本節中的範例會根據並行建議示範位置計數。

範例 1 – 一個 NFS 用戶端,65,536 個 sunrpc.tcp_max_slot_table_entries,沒有 nconnect,根據伺服器端的上限 128,並行上限為 128

範例 1 以 sunrpc.tcp_max_slot_table_entry 預設值 65,536 和單一網路連線的單一用戶端工作負載為基礎,也就是沒有 nconnect。 在此情況下,可達成到 128 個並行。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection (10.10.10.10:2049, 10.10.10.11:6543,TCP)
      • 理論上,用戶端透過每個連線可向伺服器發出的傳輸中要求不超過 65,536 個。
      • 來自這個單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。

範例 2 – 一個 NFS 用戶端,128 個 sunrpc.tcp_max_slot_table_entries,沒有 nconnect,並行上限為 128

範例 2 是以 sunrpc.tcp_max_slot_table_entry 值為 128 但不含 nconnect 掛接選項的單一用戶端工作負載為基礎。 透過此設定,可從單一網路連線達到 128 個並行。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection (10.10.10.10:2049, 10.10.10.11:6543,TCP)
      • 用戶端透過每個連線可向伺服器發出的傳輸中要求不超過 128 個。
      • 來自這個單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。

範例 3– 一個 NFS 用戶端,100 個 sunrpc.tcp_max_slot_table_entriesnconnect=8 的並行上限為 800

範例 3 是以單一用戶端工作負載為基礎,但 sunrpc.tcp_max_slot_table_entry 值為較低的 100。 這次 nconnect=8 掛接選項會用來將工作負載分散到 8 個連線。 透過此設定,可達到 800 個並行並分散到 8 個連線。 這是達到 400,000 IOPS 所需的並行數。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection 1 (10.10.10.10:2049, 10.10.10.11:6543,TCP), Connection 2 (10.10.10.10:2049, 10.10.10.11:6454,TCP)… Connection 8 (10.10.10.10:2049, 10.10.10.11:7321,TCP)
    • 連線 1
      • 用戶端透過這個連線可向伺服器發出的傳輸中要求不超過 100 個。
      • 用戶端若透過此連線傳來超過 128 個要求,預期伺服器不會接受。
    • 連線 2
      • 用戶端透過這個連線可向伺服器發出的傳輸中要求不超過 100 個。
      • 用戶端若透過此連線傳來超過 128 個要求,預期伺服器不會接受。
    • 連線 8
      • 用戶端透過這個連線可向伺服器發出的傳輸中要求不超過 100 個。
      • 用戶端若透過此連線傳來超過 128 個要求,預期伺服器不會接受。

範例 4 – 250 個 NFS 用戶端,8 個 sunrpc.tcp_max_slot_table_entries,沒有 nconnect,並行上限為 2000

範例 4 針對 250 機器計數 EDA 環境,每用戶端的 sunrpc.tcp_max_slot_table_entry 值使用縮減的 8。 在此案例中,整個環境的並行已達到 2000,此值對於驅動後端 EDA 的 4,000 MiB/秒工作負載而言綽綽有餘。

  • NFS_Server=10.10.10.10, NFS_Client1=10.10.10.11
    • Connection (10.10.10.10:2049, 10.10.10.11:6543,TCP)
      • 用戶端透過每個連線可向伺服器發出的傳輸中要求不超過 8 個。
      • 來自這個單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。
  • NFS_Server=10.10.10.10, NFS_Client2=10.10.10.12
    • Connection (10.10.10.10:2049, 10.10.10.12:7820,TCP)
      • 用戶端透過每個連線可向伺服器發出的傳輸中要求不超過 8 個。
      • 來自這個單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。
  • NFS_Server=10.10.10.10, NFS_Client250=10.10.11.13
    • Connection (10.10.10.10:2049, 10.10.11.13:4320,TCP)
      • 用戶端透過每個連線可向伺服器發出的傳輸中要求不超過 8 個。
      • 來自這個單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。

使用 NFSv3 時,應將儲存體端點位置的總計數維持在 10,000 或以下。 當應用程式跨多個網路連線 (一般是 nconnect 和 HPC,特別是 EDA) 而擴增時,最好將每個連線的 sunrpc.tcp_max_slot_table_entries 值設為小於 128。

如何計算最佳 sunrpc.tcp_max_slot_table_entries

使用利特爾法則,您可以計算出所需的總位置表項目計數。 一般而言,需考慮下列因素:

  • 擴增工作負載本質上通常是極大型的連續作業。
  • 資料庫工作負載 (特別是 OLTP) 本質上通常是隨機的。

下表顯示並行的範例研究,並提供任意延遲:

I/O 大小 Latency I/O 或輸送量 並行
8 KiB 0.5 毫秒 110,000 IOPS | 859 MiB/秒 55
8 KiB 2 毫秒 400,000 IOPS | 3,125 MiB/秒 800
256 KiB 2 毫秒 16,000 IOPS | 4,000 MiB/秒 32
256 KiB 4 毫秒 32,000 IOPS | 8,000 MiB/秒 128

如何依連線計數計算並行設定

例如,如果工作負載是 EDA 伺服器陣列,而 1,250 個用戶端全都會將工作負載驅動到相同的儲存體端點 (儲存體端點是儲存體 IP 位址),您便可計算必要的 I/O 速率,然後將並行分割到整個伺服器陣列中。

假設工作負載是 4,000 MiB/秒,使用 256-KiB 平均作業大小和平均延遲 10 毫秒。 若要計算並行數,請使用下列公式:

(concurrency = operation rate × latency in seconds)

計算轉譯為 160 個並行:

(160 = 16,000 × 0.010)

假設需要 1,250 個用戶端,您可以安全地設定為每個用戶端 sunrpc.tcp_max_slot_table_entries 至 2,以達到 4,000 MiB/秒。 不過,您可以決定將每個用戶端的數目設為 4 甚至是 8,以建立額外的空餘空間,維持不超過 10,000 個建議位置上限。

如何在用戶端上設定 sunrpc.tcp_max_slot_table_entries

  1. sunrpc.tcp_max_slot_table_entries=<n> 新增至 /etc/sysctl.conf 設定檔。
    進行微調期間,如果發現低於 128 的值是最佳值,請將 128 取代為適當的數目。
  2. 執行以下命令:
    $ sysctl -p
  3. 掛接 (或重新掛接) 所有 NFS 檔案系統,因為可調整變數只會套用至設定完可調整變數之後建立的掛接。

NFSv4.1

在 NFSv4.1 中,工作階段會定義用戶端與伺服器之間的關聯性。 無論掛接的 NFS 檔案系統位於一個連線還是多個連線 (如同 nconnect 的情況),工作階段的規則都適用。 在工作階段設定中,用戶端和伺服器會交涉工作階段的要求數上限,並採用兩個支援值中較低者。 Azure NetApp Files 支援 180 個未處理要求,而 Linux 用戶端預設為 64。 下表顯示工作階段數上限:

Azure NetApp Files NFSv4.1 伺服器
每個工作階段的命令數上限
Linux 用戶端
每個工作階段的預設命令數上限
工作階段的交涉命令數上限
180 64 64

雖然 Linux 用戶端預設為每個工作階段最多 64 個要求,但 max_session_slots 的值無法調整。 需要重新開機,變更才會生效。 使用 systool -v -m nfs 命令查看用戶端目前使用中的最大值。 若要讓命令運作,至少必須設置一個 NFSv4.1 掛接:

$ systool -v -m nfs
{
Module = "nfs"
...
  Parameters:
...
    max_session_slots   = "64"
...
}

若要調整 max_session_slots,請比照範例在 /etc/modprobe.d 底下建立設定檔。 請確定檔案中的行沒有任何「引號」存在。 否則此選項將不會生效。

$ sudo echo “options nfs max_session_slots=180” > /etc/modprobe.d/nfsclient.conf $ sudo reboot

Azure NetApp Files 會將每個工作階段的命令數上限設為 180。 因此,請將目前可設定的最大值視為 180。 除非工作階段分散在多個連線中,否則用戶端將無法達到超過 128 個並行,因為 Azure NetApp Files 會將每個連線的 NFS 命令數上限設為 128。 若要取得一個以上的連線,建議使用 nconnect 掛接選項,而且值需為二以上。

預期並行數上限的範例

本節中的範例示範預期的並行數上限。

範例 1 – 64 個 max_session_slots 且無 nconnect

範例 1 是以 max_session_slots 的預設值 64 為基礎,沒有 nconnect。 透過此設定,可從單一網路連線達到 64 個並行。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection (10.10.10.10:2049, 10.10.10.11:6543,TCP)
      • 用戶端針對該工作階段可向伺服器發出的傳輸中要求不超過 64 個。
      • 伺服器針對該工作階段可接受來自該用戶端的傳輸中要求不超過 64 個。 (64 是交涉出的值。)

範例 2 – 64 個 max_session_slotsnconnect=2

範例 2 是以 session_slots 最大值 64 為基礎,但新增了掛接選項 nconnect=2。 可達到 64 個並行,但分割至兩個連線中。 雖然在此案例中,多個連線不會帶來更多的並行,但每個連線的佇列深度減少對延遲有正面的影響。

max_session_slots 仍為 64 但有 nconnect=2,請注意,要求數上限會分割至不同連線中。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection 1 (10.10.10.10:2049, 10.10.10.11:6543,TCP) && Connection 2 (10.10.10.10:2049, 10.10.10.11:6454,TCP)
    • 連線 1
      • 用戶端透過這個連線可向伺服器發出的傳輸中要求不超過 32 個。
      • 用戶端若透過此連線傳來超過 32 個要求,預期伺服器不會接受。
    • 連線 2
      • 用戶端透過這個連線可向伺服器發出的傳輸中要求不超過 32 個。
      • 用戶端若透過此連線傳來超過 32 個要求,預期伺服器不會接受。

範例 3 – 180 個 max_session_slots 且無 nconnect

範例 3 卸除了 nconnect 掛接選項,並將 max_session_slots 值設為 180,符合伺服器的 NFSv4.1 工作階段並行數上限。 在此案例中,只有一個連線,且 Azure NetApp Files 每個 NFS 連線的未完成作業數上限為 128,工作階段的傳輸中作業數上限為 128。

雖然 max_session_slots 已設為 180,但單一網路連線的要求數上限為 128,例如:

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection (10.10.10.10:2049, 10.10.10.11:6543,TCP)
      • 用戶端針對該工作階段可向伺服器發出的傳輸中要求不超過 180 個。
      • 伺服器針對該工作階段可接受來自該用戶端的傳輸中要求不超過 180 個。
      • 單一連線的傳輸中要求若超過 128 個,伺服器就不會接受。

範例 4 – 180 個 max_session_slotsnconnect=2

範例 4 新增了 nconnect=2 掛接選項,並重複使用 max_session_slots 值 180。 由於整體工作負載分割至兩個連線,因此可達到 180 個未完成作業。

兩個連線進行中時,工作階段支援 180 個未完成要求的完整配額。

  • NFS_Server=10.10.10.10, NFS_Client=10.10.10.11
    • Connection 1 (10.10.10.10:2049, 10.10.10.11:6543,TCP) && Connection 2 (10.10.10.10:2049, 10.10.10.11:6454,TCP)
    • 連線 1
      • 預期用戶端可透過連線 1 向伺服器發出的傳輸中要求數會維持不超過 90 個。
      • 預期伺服器會維持讓用戶端在該工作階段中透過此連線傳來的要求數不超過 90 個。
    • 連線 2
      • 預期用戶端可透過連線 1 向伺服器發出的傳輸中要求數會維持不超過 90 個。
      • 預期伺服器會維持讓用戶端在該工作階段中透過此連線傳來的要求數不超過 90 個。

注意

針對並行數上限,將 max_session_slots 設為等於 180,這是目前 Azure NetApp Files 支援的最大工作階段層級並行。

如何檢查工作階段的未處理要求數上限

若要查看用戶端和伺服器所支援的 session_slot 大小,請在封包追蹤中擷取掛接命令。 尋找 CREATE_SESSION 呼叫和 CREATE_SESSION 回覆,如以下範例所示。 呼叫源自於用戶端,而回覆源自於伺服器。

使用下列 tcpdump 命令來擷取掛接命令:

$ tcpdump -i eth0 -s 900 -w /tmp/write.trc port 2049

使用 Wireshark 時,目標封包如下所示:

Screenshot that shows packets of interest.

在這兩個封包中,查看追蹤檔案中間區段內的 max_reqs 欄位。

  • 網路檔案系統
    • 作業
      • Opcode
        • csa_fore_channel_attrs
        • max reqs

封包 12 (用戶端要求數上限) 顯示用戶端的 max_session_slots 值為 64。 在下一個區段中,請注意伺服器針對工作階段支援的並行數為 180。 工作階段最終會交涉,採用所提供兩個值的較低者。

Screenshot that shows max session slots for Packet 12.

下列範例顯示封包 14 (伺服器要求數上限):

Screenshot that shows max session slots for Packet 14.

下一步