2013-12-08 17 views
5

我們有bash腳本(作業包裝)寫入文件,啓動作業,然後在作業完成後追加到文件信息工作。包裝器在幾千個批處理節點中的一個上運行,但只有幾個批處理機器(我相信RHEL6)訪問一個NFS服務器,並且在不同的批處理節點上使用不同的批處理節點上的至少一個已知實例NFS服務器。在所有情況下,只有一個客戶端主機正在寫入有問題的文件。有些工作需要數小時才能完成,有些需要數分鐘。隨機破壞文件創建/更新從一個單一的客戶端上的shell腳本到NFS安裝

在發生這種情況的同一時間段內,10萬個工作中似乎有10-50個問題。

以下是我認爲有效地工作包裝的(蒸餾水)版本:

#!/bin/bash 
## cwd is /nfs/path/to/jobwd 
## This file is /nfs/path/to/jobwd/job_wrapper 

gotEXIT() 
{ 
    ## end of script, however gotEXIT is called because we trap EXIT 
    END="EndTime: `date`\nStatus: Ended」 
    echo -e "${END}" >> job_info 
    cat job_info | sendmail [email protected] 
} 
trap gotEXIT EXIT 

function jobSetVar { echo "job.$1: $2" >> job_info; } 
export -f jobSetVar 

MSG=「${email_metadata}\n${job_metadata}」 
echo -e "${MSG}\nStatus: Started" | sendmail [email protected] 
echo -e "${MSG}" > job_info 

## At the job’s end, the output from `time` command is the first non-corrupt data in job_info 
/usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command 

## 10-360 minutes later… 
RC=$? 
echo -e "ExitCode: ${RC}" >> job_info 

所以我認爲有兩種可能:

  1. echo -e "${MSG}" > job_info
    此命令拋出淘汰腐敗數據。

  2. /usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command
    這會損壞現有數據,然後正確輸出數據。

但是,有些工作,但不是全部,調用jobSetVar,它不會最終被損壞。

因此,我深入研究time.c(從GNU時間1.7開始),以查看文件何時打開。總之,time.c有效的是這樣的:

FILE *outfp; 

void main (int argc, char** argv) { 
    const char **command_line; 
    RESUSE res; 

    /* internally, getargs opens 「job_info」, so outfp = fopen ("job_info", "a」) */ 
    command_line = getargs (argc, argv); 
    /* run_command doesn't care about outfp */ 
    run_command (command_line, &res); 
    /* internally, summarize calls fprintf and putc on outfp FILE pointer */ 
    summarize (outfp, output_format, command_line, &res);/
    fflush (outfp); 
} 

所以,時間已經FILE *outfp(job_info手柄)打開作業的全部時間。然後它在作業結束時寫入摘要,然後實際上並沒有出現關閉文件(不確定這對fflush是否必要?)我不知道bash是否也同時打開了文件句柄。

編輯:

損壞的文件通常將結束由損壞的部分,隨後與非損壞的部分,其可以是這樣的:

損壞的部分,這將發生之前非損壞的部分,典型地是在很大程度上一堆0x0000時,其中混合有也許有些環狀垃圾:

以下範例hexdump都:

40000000 00000000 00000000 00000000 
00000000 00000000 C8B450AC 772B0000 
01000000 00000000 C8B450AC 772B0000 
[ 361 x 0x00] 

然後,在第409個字節,它繼續與未損壞部分:

Elapsed: 879.07 
User: 0.71 
System: 31.49 
ExitCode: 0 
EndTime: Fri Dec 6 15:29:27 PST 2013 
Status: Ended 

另一個文件是這樣的:

01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000 
[96 x 0x00] 
[Repeat above 3 times ] 
01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000 

其次是無損壞的部分:

Elapsed: 12621.27 
User: 12472.32 
System: 40.37 
ExitCode: 0 
EndTime: Thu Nov 14 08:01:14 PST 2013 
Status: Ended 

還有其他文件有更多的隨機腐敗部分,但超過一些是週期性類似於上述。

編輯2:echo -e聲明發送的第一封電子郵件通過罰款。由於沒有郵件元數據損壞,最後的電子郵件永遠不會被髮送。所以MSG在這一點上沒有被破壞。假設job_info 可能在這一點上也沒有損壞,但我們還沒有能夠驗證。這是一個沒有主要代碼修改的生產系統,我通過審計證實沒有任何作業可以同時運行,並且會觸及此文件。這個問題似乎是最近的(最近2個月),但它有可能發生在之前,並且滑落。此錯誤確實會阻止報告,這意味着作業被視爲失敗,因此通常會重新提交作業,但特定用戶中有一位用戶具有約9小時的作業,其中此錯誤尤其令人沮喪。我希望我能夠提供更多信息或隨意重現這一點,但我希望有人可能會看到類似的問題,特別是最近。我不管理NFS服務器,但我會嘗試與管理員交談,以瞭解在發生這些問題時(RHEL6,我相信)哪些更新NFS服務器正在運行。

+0

有趣的效果!你能否包含一個破壞文件通常看起來像什麼的例子? –

+0

我已經添加了幾個示例 – Brian

回答

1

那麼,與損壞的job_info文件相對應的電子郵件應該告訴你什麼是味精(這可能會像往常一樣業務)。您可能想要檢查NFS是如何運行的:遠程可能性是您在沒有校驗和的情況下通過UDP運行NFS。這可以解釋一些腐敗的數據。我也聽說UDP/TCP校驗和不夠強大,數據仍然會損壞 - 也許你遇到了這樣的問題(我曾經看到腐敗的數據包至少在網絡堆棧中滑過一次,而且我很安靜確定一些校驗和正在進行)。據推測味精會作爲一個單獨的數據包出去,並且可能會有一些關於它使得校驗和與你更可能看到的垃圾衝突。當然,它也可能是一個NFS錯誤(客戶端或服務器),一個服務器端文件系統錯誤,一塊RAM內存......可能性在這裏幾乎是無窮無盡的(儘管我看到總是MSG被破壞的事實使得一些那些相當不可能)。問題可能與尋找有關(發生在追加期間)。你也可能在系統的其他地方有一個錯誤,導致多個客戶打開同一個job_info文件,使其成爲混亂。

+0

我已經添加了更多信息。我將在明天與管理員進行覈對以嘗試查找有關操作系統和NFS客戶端和服務器版本的信息。我不相信它是RAM,因爲它發生在至少六個不同的批處理節點和兩個單獨的服務器上(都有ECC,FWIW)。我不認爲它是網絡相關的,它只在這個特定的文件和這兩個服務器上表現出自己的AFAIK。所以這非常令人困惑,因爲我至少希望這會顯示在系統中的其他地方,因爲寫入這個文件是相當基本的。 – Brian

0

您還可以嘗試使用不同的文件進行「時間」輸出,然後在腳本結尾將它們與job_info合併在一起。這可能有助於進一步隔離問題。

Shell打開'job_info'文件進行寫入,輸出MSG,然後在啓動主要作業之前關閉其文件描述符。 '時間'程序打開相同的文件作爲流追加,我懷疑通過NFS尋找不正確,這可能會導致垃圾。無法解釋爲什麼,但通常情況下不會發生(並且沒有發生)。這種罕見的情況可能指向某處的某種競爭條件,可能是由於無序數據包傳遞(由於網絡延遲尖峯)或重新傳輸而導致重複數據或某處的錯誤。首先看我會懷疑一些錯誤,但是這個錯誤可能是由一些網絡行爲觸發的,例如,非常大的延遲或數據包丟失的峯值。

不同進程之間的文件訪問被內核序列化,但是爲了額外的安全措施,值得添加一些人爲延遲 - 例如輸出之間的睡眠定時器。

網絡不透明,尤其是大的。可能存在廣域網優化設備,這些設備有時會導致應用程序問題。通過本地緩存文件系統操作,CIFS和NFS是WAN上優化的理想選擇。可能值得尋找最近與網絡管理員的變化..

另一件嘗試,雖然可能是困難的,因爲罕見的事件是通過tcpdump或wireshark捕獲有趣的NFS會話。在非常困難的情況下,我們在客戶端和服務器端同時進行捕獲,然後比較協議邏輯以證明網絡是否工作正常。這本身就是一個整體,需要充分的準備和運氣,但通常是絕望故障排除的最後手段:)

相關問題