叢集架構當中,NFS 恐怕是一個很麻煩的瓶頸點
鳥哥的研究當中,經常需要使用到叢集架構 (cluster) 的系統來進行平行協作處理,這種情況底下,簡單的系統架構, 大多是將所有的重要資料通通放置到一個 Storage 當中,再將其他的運算主機透過 NFS 連線到該系統,就簡單的達到了平行處理可以操作的環境。 簡易架構示意圖如下:
NFS (/home, /data) +------+----+-------+--------+ Node1 Node2 Node3 Node4 Node5
請注意,為了『平行處理』的機制,所有的上面系統,全部的系統架構都需要相同!最好 node1~node5 這 5 部能夠是相同的硬體設備, 能夠擁有相同的帳號/密碼 (連 UID/GID 等等都需要相同),相同的作業系統 (連核心版本都要相同),這樣運作程式時, 比較不容易出現問題。當然,還需要其他額外的平行處理函式庫,那個不在這裡討論,有興趣的自行 google 一下 mpi 與平行化, 大概就有很多文章說明了。
既然感覺這麼簡單,系統操作上面應該沒啥問題吧?對啊!如果以每一部 node 自行運算,使用了自己的 mpi 程式自己的 cpu 核心計算, 那幾顆 CPU 核心都沒啥問題!可以安全的處理所有的程式,不會被中斷。鳥哥使用的最新的系統,是 AMD 64 核心的架構, 這種架構下,最多可以用到 64 核心來跑程式,速度還不賴,很是開心。
問題是,既然有這麼多部系統,如果只要跑一個案例,能不能大家一起來跑?例如上面說得,如果我有 64 核心的系統 3 部, 難道不能拿 192 個核心來跑嘛?理論上,應該是可以的!所以,鳥哥就拿來跑啦!但是...先不管跑出來的速度會不會比較快, 光是 3 台 64 核心同時跑,就出問題了!沒辦法順利運作結束!老是可能隨機斷到某個運算日期...非常怪。
基本上,運算這種平行處理,大概有兩種機制,一種是連續跑,一種是分日跑。假設我要運作的平行處理程式,需要運作 30 日模擬, 第一種方式是,30 日的模擬量,一次跑完,從第 1 日跑到第 30 日這樣連續跑;第二種則是分 30 次跑,每次跑 1 日的份量。
各有優缺點,只是站在開發者的角度,目前大多使用 1 日跑的情境來處理。那麼這種情境會發生什麼問題呢?為什麼這種方法老是產生中斷呢? 大致上我們可以這樣看:
上述的問題發生在第 2 及第 5 點,當系統初始化的情況。基本上,檔案系統為了加速,通常資料不會立刻寫入到磁碟當中,而是暫時存放於記憶體。 這種機制在單一系統上面是沒問題的,但是如果用於上述的狀況,那就慘了:
看到問題的發生了嘛?這是資料存取的問題~當 node1 初始化並且產生大家都要讀寫的資料時,為了加速,所以尚未寫入 NFS storage 當中。 結果這時卻又要 node2, node3 去 NFS 讀取剛剛創見的檔案!夭壽啦!又要馬兒跑,又要馬兒不吃草,所以,這個時候就掛點了...
那麼該如何處理這個問題呢?鳥哥測試過每一部 node 系統上面使用 NFS 掛載的 lookupcache=none 的參數,結果雖然有好一些, 不過,還是有可能會隨機中斷。為什麼呢?明明 NFS 文件說, lookupcache=none 代表隨時去抓 NFS storage 的 cachec 而不是使用自己的 cache 啊! 話是這麼說沒錯,針對 node2, node3 這點是沒問題的!但是針對主辦單位的 node1 來說,除非你修改了 Linux kernel 的 filesystem 設定參數, 否則的話,那個 lookupcache 指的是針對 NFS 的讀寫而已,並不是針對自己本身系統的操作,所以, node1 在 NFS 掛載為 lookupcache=none 的情境下, 依舊會將自己產生的檔案暫存於自己的記憶體中,並不會立刻直接寫回 NFS storage 喔!
NFS mount 有個機制,透過 sync 這個機制來處理,那麼 node1 使用到任何 NFS 的裝置資料時,都會同步寫入到 NFS 檔案系統中, 這不像 lookupcache 喔!只是,如此一來, node1 的讀寫,就會非常的延遲!因為 sync 對於 NFS 的效能來說,影響非常大!但是,這種設計方式最簡單! 而且幾乎不會出錯!
這樣說好了,既然大家都要讀寫 node1 這個主事者的系統,那麼將 storage 換到 node1 不就好了?好啊!但是, NFS storage 通常不會在運算主機上, 這是因為很多很多考量...這裡就不寫了。那怎辦?沒關係,我們可以將已經掛載到 node1 的 NFS 目錄,再次分享出去,然後讓 node2, node3 掛載 node1 的資料,這樣 node2, node3 就不需要 lookupcache,而 node1 也不需要 sync 喔! 只是從 node1 分享的 NFS 目錄,需要在 /etc/exports 裡面加上 crossmnt 這個參數才行!否則就可能讀不到掛載的資訊。 這點比較需要留意而已。
過去開機都是先將 Storage 開機完畢,之後每部 node 都是獨立運作可以自由開機!但是如果使用這種方式,那麼就得要先從 NFS storage 開機, 完成之後才能開機 node1,之後才能 node2 與 node3 等其他系統...尤其,如果你想要從 node2 作為主事者,那麼整個掛載就得要重來... 在系統的運作上面,就會產生許多困擾!雖然效能上面會比較好一些。