2013-12-08 28 views
5

Mamy skrypt bash (wrapper zadania), który zapisuje do pliku, uruchamia zadanie, a następnie przy zakończeniu zadania dołącza do pliku informacje o praca. Owijarka jest uruchamiana na jednym z kilku tysięcy węzłów przetwarzania wsadowego, ale pojawiła się tylko w kilku maszynach wsadowych (uważam, że RHEL6) uzyskujących dostęp do jednego serwera NFS i co najmniej jednej znanej instancji innego zadania wsadowego w innym węźle wsadowym przy użyciu innego Serwer NFS. We wszystkich przypadkach tylko jeden host klienta zapisuje dane pliki. Niektóre zadania trwają kilka godzin, inne trwają minutę.Uszkodzenie losowe w pliku utworzonym/zaktualizowanym ze skryptu powłoki na pojedynczym kliencie na mount NFS

W tym samym okresie, w którym to się wydarzyło, wydaje się, że istnieje 10-50 spraw z ponad 100 000 nowych miejsc pracy.

Oto co wierzę, aby skutecznie być (destylowana) wersja owijki pracy:

#!/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 

Więc myślę, że istnieją dwie możliwości:

  1. echo -e "${MSG}" > job_info
    Komenda ta rzuca z uszkodzonych danych.

  2. /usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command Spowoduje to uszkodzenie istniejących danych, a następnie prawidłowe wyprowadzenie danych.

Jednak niektóre zadania, ale nie wszystkie, wywołują funkcję jobSetVar, która nie kończy się uszkodzeniem.

Tak więc, kopie w time.c (z GNU czas 1,7), aby zobaczyć, kiedy plik jest otwarty. Podsumowując, time.c jest skutecznie to:

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); 
} 

więc czas ma FILE *outfp (uchwyt job_info) otworzyć cały czas pracy. Następnie zapisuje podsumowanie na końcu zadania, a następnie faktycznie nie wydaje się, aby zamknąć plik (nie jestem pewien, czy jest to konieczne z fflush?) Nie mam pojęcia, czy bash ma również uchwyt pliku otwarty jednocześnie .

Edycja:

uszkodzonych plików zwykle kończy się składać z uszkodzonej części, a następnie z nie uszkodzonych części, która może wyglądać następująco:

uszkodzonych części, które występują przed non-uszkodzony odcinek jest zazwyczaj głównie pęczek 0x0000, z może pewnym cyklicznego śmieci miesza się:

Oto przykład hexdump:

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

Następnie, na 409. bajt, to nadal z non-uszkodzone części:

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

Kolejny plik wygląda tak:

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

Obserwowani przez nie uszkodzonych części:

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

Istnieją inne pliki, które mają o wiele więcej przypadkowych sektorów korupcji, ale więcej niż kilka miało cykliczne cechy podobne do powyższych.

EDYCJA 2: Pierwszy e-mail wysłany z oświadczenia echo -e przechodzi przez prawo. Ostatni e-mail nie zostanie nigdy wysłany z powodu braku metadanych wiadomości e-mail z powodu uszkodzenia. Tak więc MSG nie jest uszkodzony w tym momencie. Zakładamy, że job_info prawdopodobnie nie jest uszkodzony w tym momencie, ale nie byliśmy jeszcze w stanie tego zweryfikować. Jest to system produkcyjny, który nie miał dużych modyfikacji kodu i zweryfikowałem poprzez audyt, że żadne zadania nie zostały uruchomione jednocześnie, co mogłoby dotknąć tego pliku. Problem wydaje się być nieco aktualny (ostatnie 2 miesiące), ale możliwe, że zdarzył się wcześniej i przeszedł. Ten błąd uniemożliwia raportowanie, co oznacza, że ​​zadania są uznawane za zakończone niepowodzeniem, dlatego zwykle są one przesyłane ponownie, ale jeden użytkownik w konkretnym przypadku ma ~ 9 godzin pracy, w których ten błąd jest szczególnie frustrujący. Chciałbym wymyślić więcej informacji lub sposób ich reprodukcji do woli, ale miałem nadzieję, że ktoś może widział podobny problem, szczególnie ostatnio. Nie zarządzam serwerami NFS, ale spróbuję porozmawiać z administratorami, aby zobaczyć, jakie aktualizacje zostały uruchomione przez serwery NFS w czasie tych problemów (jak sądzę RHEL6).

+0

ciekawy efekt! Czy możesz podać przykład tego, jak zwykle wygląda uszkodzony plik? –

+0

Dodałem kilka przykładów. – Brian

Odpowiedz

1

Cóż, wiadomości e-mail odpowiadające uszkodzonym plikom job_info powinny informować o tym, co było w MSG (co prawdopodobnie będzie działało jak zwykle). Możesz sprawdzić, w jaki sposób uruchamiany jest NFS: istnieje możliwość zdalnego uruchamiania systemu NFS przez UDP bez sum kontrolnych. To mogłoby wyjaśnić niektóre zepsute dane. Słyszałem również, że sumy kontrolne UDP/TCP nie są wystarczająco silne, a dane wciąż mogą zostać uszkodzone - być może trafiasz na taki problem (widziałem uszkodzone pakiety prześlizgujące się przez stos sieci przynajmniej raz wcześniej i jestem całkiem pewna część kontroli była w toku). Przypuszczalnie MSG wychodzi jako pojedynczy pakiet i może być w tym coś, co powoduje, że suma kontrolna powoduje konflikty ze śmieciami, które są bardziej prawdopodobne. Oczywiście może to być również błąd NFS (klient lub serwer), błąd systemu plików po stronie serwera, uszkodzony plik RAM ... możliwości są tu prawie nieskończone (chociaż widzę, że fakt, że to zawsze MSG, który ulega uszkodzeniu, powoduje, że niektóre tych mało prawdopodobnych). Problem może być związany z poszukiwaniem (co dzieje się podczas dodawania). Możesz również mieć błąd w innym miejscu systemu, powodując, że wielu klientów otworzy ten sam plik job_info, co spowoduje, że będzie to zbieg okoliczności.

+0

Dodałem więcej informacji. Zamierzam jutro skontaktować się z administratorami, aby dowiedzieć się o wersjach klienta i serwera OS i NFS. Nie wierzę, że to RAM, tak jak to miało miejsce w co najmniej sześciu różnych węzłach wsadowych i dwóch oddzielnych serwerach (wszystkie mają ECC, FWIW). Nie sądzę, że jest to związane z siecią i przejawia się tylko AFAIK na tym konkretnym pliku i tych 2 serwerach. Jest to dość mylące, ponieważ przynajmniej spodziewam się, że pojawi się gdzie indziej w systemie, biorąc pod uwagę, że pisanie do tego pliku jest dość proste. – Brian

0

Możesz również spróbować użyć innego pliku dla wyjścia "time", a następnie połączyć je z job_info na końcu skryptu. To może pomóc w dalszym wyizolowaniu problemu.

Powłoka otwiera plik job_info do zapisu, generuje MSG, a następnie zamyka deskryptor pliku przed uruchomieniem głównego zadania. Program "time" otwiera ten sam plik dla dołączenia jako stream i podejrzewam, że przeszukiwanie przez NFS nie zostało wykonane poprawnie, co może spowodować te śmieci. Nie potrafię wyjaśnić dlaczego, ale normalnie tak się nie stanie (i nie dzieje się to). Takie rzadkie sytuacje mogą wskazywać na pewne warunki rasowe gdzieś, mogą być spowodowane przez dostarczenie pakietów poza kolejnością (ze względu na skok latencji sieci) lub retransmisje, które powodują duplikowanie danych lub gdzieś błąd. Na pierwszy rzut oka podejrzewałbym jakiś błąd, ale ten błąd może być wywołany przez pewne zachowanie sieciowe, np. niezwykle duże opóźnienie lub skok utraty pakietów.

Dostęp do plików między różnymi procesami jest serializowany przez jądro, ale dla dodatkowej ochrony warto dodać pewne sztuczne opóźnienia - na przykład wyłączniki czasowe pomiędzy wyjściami.

Sieć nie jest przezroczysta, szczególnie duża. Mogą istnieć urządzenia optymalizujące sieć WAN, o których wiadomo, że czasami powodują problemy z aplikacją. CIFS i NFS są dobrymi kandydatami do optymalizacji w sieci WAN z lokalnym buforowaniem operacji systemu plików. Może warto szukać ostatnich zmian u administratorów sieci ..

Kolejną rzeczą do wypróbowania, choć może być trudna ze względu na rzadkie zdarzenia, jest przechwytywanie interesujących sesji NFS za pośrednictwem tcpdump lub wireshark. W naprawdę trudnych przypadkach wykonujemy jednoczesne przechwytywanie po stronie klienta i serwera, a następnie porównujemy logikę protokołu, aby udowodnić, że sieć działa lub działa nieprawidłowo. Sam w sobie jest to temat wymagający gruntownych przygotowań i szczęścia, ale zwykle jest to ostatnia szansa na desperackie rozwiązywanie problemów :)