2009-03-20 20 views
5

Prowadzę bardzo wymagającą obliczeniowo pracę naukową, która wypluwa wyniki co jakiś czas. Zadanie polega na tym, aby symulować to samo całą masę razy, więc jest podzielone na kilka komputerów, które używają różnych systemów operacyjnych. Chciałbym skierować dane wyjściowe ze wszystkich tych instancji do tego samego pliku, ponieważ wszystkie komputery mogą widzieć ten sam system plików za pośrednictwem NFS/Samba. Oto ograniczenia:Blokowanie plików niezależne od platformy?

  1. Musi pozwalać na bezpieczne jednoczesne dołączenia. Należy zablokować, jeśli jakieś inne wystąpienie na innym komputerze jest obecnie dołączane do pliku.
  2. Wydajność ma nie jest liczbą. We/wy dla każdej instancji jest tylko kilka bajtów na minutę.
  3. Prostota się liczy. Cały sens tego (oprócz czystej ciekawości) polega na tym, że mogę zatrzymać zapisywanie każdego wystąpienia do innego pliku i ręczne scalanie tych plików razem.
  4. Nie może zależeć od szczegółów systemu plików. Musi pracować z nieznanym systemem plików na urządzeniu NFS lub Samba.

Język, którego używam, to D, w przypadku, gdy ma to znaczenie. Spojrzałem, nie ma nic w standardowej bibliotece, która wydaje się to robić. Zarówno odpowiedzi specyficzne dla D, jak i ogólne, niezwiązane z językiem są w pełni akceptowane i doceniane.

Odpowiedz

7

W systemie operacyjnym NFS występują problemy z buforowaniem po stronie klienta i nieaktualnymi danymi. Napisałem niezależny od systemu operacyjnego moduł blokady do pracy z NFS. Prosty pomysł utworzenia pliku [datafile] .lock nie działa dobrze w systemie plików NFS. Podstawowym pomysłem na obejście tego jest utworzenie pliku blokady [plik_z danych] .lock, który jeśli obecny oznacza, że ​​plik NIE jest zablokowany, a proces, który chce uzyskać blokadę, zmienia nazwę pliku na inną nazwę, na przykład [plik danych] .lock. [ nazwa hosta]. [pid]. Zmiana nazwy jest wystarczająco operacją atomistyczną, która działa wystarczająco dobrze na NFS, aby zagwarantować wyłączność blokady. Reszta to w zasadzie pakiet bezpiecznych pętli, pętli, sprawdzania błędów i pobierania blokad w przypadku, gdy proces zakończy działanie przed zwolnieniem blokady i zmiana nazwy pliku blokady z powrotem na [plik z danymi] .lock

1

Nie znam D, ale wydaje mi się, że używanie pliku mutex do wykonania zadania może działać. Oto niektóre pseudo-kod może okazać się przydatne:

do { 
    // Try to create a new file to use as mutex. 
    // If it's already created, it will throw some kind of error. 
    mutex = create_file_for_writing('lock_file'); 
} while (mutex == null); 

// Open your log file and write results 
log_file = open_file_for_reading('the_log_file'); 
write(log_file, data); 
close_file(log_file); 

close_file(mutex); 
// Free mutex and allow other processes to create the same file. 
delete_file(mutex); 

Tak, wszystkie procesy spróbuje utworzyć plik mutex lecz ten, kto wygra będzie mógł kontynuować. Po zapisaniu wyników zamknij i usuń muteks, aby inne procesy mogły zrobić to samo.

+0

Musisz przegapić część, w której powiedział, że potrzebuje synchronizacji między różnymi komputerami. –

+0

To rozwiązanie nie działa w systemie plików NFS, ponieważ zażądał. –

+0

Dlaczego nie wykonalibyśmy tej pracy? Nie chodzi mi o pisanie pliku lokalnie na każdym komputerze, ale w jednym miejscu dla nich wszystkich. – Seb

2

Klasycznym rozwiązaniem jest użycie blokady plik lub dokładniej katalog blokady. Na wszystkie powszechne systemy operacyjne tworząc katalog jest operacją atomową więc procedura jest:

  • próby utworzenia katalogu blokady ze stałą nazwą w stałym miejscu
  • jeśli create powiodło się, należy odczekać sekundę lub tak i spróbuj jeszcze raz - powtarzać aż sukcesu
  • napisać swoje dane do pliku danych rzeczywistych
  • usunąć katalog blokady

ten został wykorzystany w programach takich jak CVS od wielu lat na całym wieloma platformami. Jedyny problem występuje w rzadkich przypadkach, gdy aplikacja ulega awarii podczas pisania i przed usunięciem blokady.

2

Blokada plików o skręcie

Podobnie jak inne odpowiedzi wspomniałem, najprostszym sposobem jest utworzenie pliku blokady w tym samym katalogu, co pliku danych.

Ponieważ chcesz mieć dostęp do tego samego pliku na wielu komputerach, najlepszym rozwiązaniem, jakie mogę sobie wyobrazić, jest dołączenie identyfikatora komputera zapisującego do pliku danych.

Zatem sekwencja do pisania do pliku danych będzie:

  1. Sprawdź, czy istnieje plik blokady obecny

  2. Jeśli istnieje plik blokady, zobacz, czy jestem jedynym posiadanie go poprzez sprawdzenie, czy jego zawartość ma mój identyfikator.
    Jeśli tak jest, po prostu zapisz w pliku danych, a następnie usuń plik blokady.
    Jeśli tak nie jest, po prostu odczekaj sekundę lub małą losową długość czasu i spróbuj ponownie całego cyklu.

  3. Jeśli nie ma pliku blokady, utwórz go z moim identyfikatorem i spróbuj ponownie cały cykl, aby uniknąć sytuacji wyścigowej (ponownie sprawdź, czy plik blokady jest naprawdę mój).

Wraz z identyfikatorem, chciałbym nagrać znacznik czasu w pliku blokady i sprawdzić, czy jest starszy niż podana wartość limitu czasu.
Jeśli znacznik czasu jest zbyt stary, należy założyć, że plik blokady jest nieaktualny i po prostu go usunąć, ponieważ spowodowałoby to awarię jednego z zapisanych na komputerze plików do pliku danych lub utratę połączenia.

Innym rozwiązaniem

Jeśli jesteś w kontroli formatu pliku danych, może być zarezerwować strukturę na początku pliku do zapisu czy jest zablokowane lub nie.
Jeśli tylko zarezerwujesz bajt do tego celu, możesz założyć, na przykład, że plik 00 oznaczałby, że plik danych nie jest zablokowany, a inne wartości będą reprezentować identyfikator aktualnie zapisywanego komputera.

Problemy z NFS

OK, jestem dodając kilka rzeczy, ponieważ Jiri Klouda prawidłowo wskazał, że NFS uses client-side caching że spowoduje rzeczywistego pliku zamka będącego w stanie nieustalonym.

Kilka sposobów, aby rozwiązać ten problem:

  • zamontować katalog NFS z noac lub sync opcji. Jest to łatwe, ale nie gwarantuje pełnej spójności danych między klientem a serwerem, więc nadal mogą występować problemy, chociaż w twoim przypadku może być OK.

  • Otwórz plik blokady lub plik danych, używając atrybutów O_DIRECT, O_SYNC lub O_DSYNC. To ma na celu całkowite wyłączenie buforowania.
    Spowoduje to obniżenie wydajności, ale zapewni spójność.

  • Ty może móc korzystać flock() zablokować plik danych, ale jego realizacja jest rzadki i trzeba będzie sprawdzić, czy dany system operacyjny faktycznie korzysta z usługi blokowania NFS. W przeciwnym razie może nic nie robić.
    Jeśli plik danych jest zablokowany, to inny klient otwierający go do zapisu nie powiedzie się.
    O tak, i wydaje się, że nie działa na udziałach SMB, więc najlepiej jest po prostu o tym zapomnieć.

  • Nie używaj NFS i po prostu użyj Samby zamiast: istnieje good article on the subject i dlaczego NFS prawdopodobnie nie jest najlepszą odpowiedzią na twój scenariusz użycia.
    W tym artykule znajdziesz również różne metody blokowania plików.

  • Rozwiązanie Jiri jest również dobre.

Zasadniczo, jeśli chcesz zachować prostotę, nie używaj NFS do często aktualizowanych plików, które są współużytkowane przez wiele komputerów.

Coś innego

Użyj małego serwera bazy danych do zapisania danych do i ominąć problemy blokujące NFS/SMB całkowicie lub utrzymać aktualny wielobiegunowy układ plików danych i po prostu napisać mały narzędzie do łączenia wyników.
To wciąż może być najbezpieczniejsze i najprostsze rozwiązanie twojego problemu.

+1

To rozwiązanie, działając dobrze na pojedynczym komputerze, będzie działać w warunkach wyścigowych z powodu buforowania po stronie klienta NFS. –

+0

Należy pamiętać, że NFSv4 rozwiązuje wiele problemów ze starszymi wersjami protokołu. – janneb

2

Dlaczego nie zbudować prostego serwera, który znajduje się pomiędzy plikiem a innymi komputerami?

Jeśli kiedykolwiek chciałeś zmienić format danych, musiałbyś tylko zmodyfikować serwer, a nie wszystkich klientów.

Moim zdaniem budowa serwera byłaby znacznie łatwiejsza niż próba użycia sieciowego systemu plików.

+0

Albo po prostu użyj bazy danych i przechowuj dane we właściwej bazie danych i rozwiązuj problemy z blokowaniem. –

+0

Nie mam skonfigurowanej bazy danych i nie chcę jej konfigurować, aby rozwiązać tak prosty problem. – dsimcha