記一次NAS故障分析(ZFS NFS)

BFP發表於2022-03-11

問題:

         使用vdbench進行單層100w目錄,每個目錄30個檔案,共3000w檔案讀寫時,在建立檔案得時候IO會出現斷斷續續得情況。

 

分析過程:

1、  nfs抓包分析

  

使用vdbench建立一個檔案得流程eg: vdb_f0398.file:

Lookup call -> lookup reply ->create call ->create reply ->write call ->write reply

 

2、  當vdbench IO歸0時,觀察儲存端狀態

1)  read IO特別大,write IO為0

 

看4標識

2)  zfs arc到了limit點為,arc_prune數值增加,意味著頻繁得回收arc,但arc大小為變化

看上圖1是設定的arc_meta_limit,2是已經使用的arc_meta空間,一般觸發回收時會高出limit限制幾百M,3是回收次數。其在arc_meta使用觸發回收時短時間內多次回收呼叫,但是回收的arc空間很少,之後不再回收,導致arc一直是full的狀態。

 

3)  arc相關引數變化

 

 

 

沒有釋放arc

 

        看圖5標識,此處為有寫IO時,此時為readdir執行完了一次後,在對應的目錄下建立了30個檔案(vdbech配置的)。

 

4)  使用perf分析程式變化情況

 

 

 

發現程式lz4_decompress_zfs 程式變化比較明顯

5)  通過dump_stack列印lz4的呼叫棧:

 

 

 

從列印情況看兩個可疑點,出問題的時候zfs_readdir 和 reconnect_path被不停的呼叫

 

6)  從這兩個地方分析是否存在問題

1》  zfs_readdir其dump_stack情況

 

分析內部程式碼,列印事件發現:

 

 

 

會發現while執行的次數和時間會隨著目錄數的增加線性增長,100w目錄查詢一次一般會超過10s(8s-180s,當時應該受到arc回收影響,沒出現IO歸零時不會呼叫到此函式)

2》  reconnect_path情況

 

 

 

出現問題時,exportfs引數沒有收到期望的具體vdb.1_6795.dir目錄名,而是根目錄/(注意此處設定nfsd thread數為1,預設是32,會進行32次根目錄的呼叫,其造成阻塞的概率增大,並耗時非常長)

由此觸發了zfs_readdir

 

此處引出問題,為什麼引數會是根目錄????

7)  當arc快取開始執行回收操作時,出現問題

而多次回收記憶體並未釋放多少,前面圖示可以看出。

 

8)  由上聯合起來分析彙總:

當arc使用接近限制閾值的時候,觸發回收操作,而回收操作只回收一點,但將原來的目錄快取破壞掉,使用新建立的檔案後設資料來填充arc,大量的arc快取無法釋放。導致當伺服器端nfs執行 lookup確定要建立的檔案是否合法時,觸發了reconnect_path->zfs_readdir等操作,來進行所有目錄的重新匹配,而此時arc已經滿了無法快取,導致接下來的每次lookup都要執行一遍readdir。

 

   此處引出問題,為什麼快取釋放不了???

 

 

3、  由上分析,猜測伺服器vdbench快取了inode,dentry等資訊

通過在跑vdbench IO時,觀察伺服器記憶體使用情況發現,隨著建立資料夾和檔案,記憶體使用明顯

嘗試在儲存端arc接近快取閾值時,清除伺服器的快取,主要是dentry、inode資訊。多次測試發現問題不再重現。Arc可以正常釋放,並且釋放速度較快。

 

4、  綜上確定問題出現vdbenc IO,在建立資料夾和檔案的時候會影響zfs ARC快取釋放,引出問題:

1)  vdbench 在沒有建立完檔案之前會維護這些link?

2)  Nfs客戶端做的快取?

3)  此現象對其他公司nas產品是否一樣?

4)  需要儲存端解決此問題?如何解決?

 

5、arc小於2G回收會出問題這個大概率是之前的因素影響,還在分析程式碼並測試中~~。測試了一次1.5G的在伺服器端正常釋放快取後,沒啥問題。

 

相關文章