2008-09-26 6 views
9

Mam problem, który wymaga przeanalizowania kilku plików dziennika z komputera zdalnego. Istnieje kilka komplikacje: 1) Plik może być używany 2) Pliki mogą być dość duże (100mb +) 3) Każdy wpis może być multi-lineJaki jest najlepszy sposób czytania i analizowania dużego pliku tekstowego przez sieć?

Aby rozwiązać ten problem w użyciu, Najpierw muszę go skopiować. Obecnie kopiuję go bezpośrednio ze zdalnego komputera na lokalny komputer i przetwarzam go tam. To prowadzi do wydania 2. Ponieważ pliki są dość duże, kopiowanie ich lokalnie może zająć sporo czasu.

Aby wydłużyć czas analizowania, chciałbym utworzyć wielowątkowy parser, ale to sprawia, że ​​obsługa wielowątkowych wpisów jest nieco trudniejsza.

Dwie główne kwestie: 1) Jak mogę przyspieszyć transfer plików (kompresja ?, Czy przeniesienie lokalnie nawet neccessary ?, Czy mogę przeczytać w pliku użytku w jakiś inny sposób) 2) W jaki sposób mogę radzić sobie z wpisami wielowierszowymi podczas dzielenia linii między wątkami?

AKTUALIZACJA: Powodem, dla którego nie zrobiłem oczywistego przetwarzania z powodu serwera jest to, że chcę mieć jak najmniejszy wpływ procesora. Nie chcę wpływać na wydajność testowania systemu.

Odpowiedz

2

Jeśli czytasz plik sekwencyjny, który chcesz odczytać wiersz po linii przez sieć. Potrzebujesz metody przesyłania strumieniowego. Aby to zrozumieć, musisz zapoznać się z technologią strumieniowania IO.

Duże operacje IO, takie jak te, nie przyniosą dużych korzyści w wyniku wielowątkowości, ponieważ prawdopodobnie można przetworzyć elementy tak szybko, jak można je odczytać w sieci.

Inną doskonałą opcją jest umieszczenie parsera raportów na serwerze i pobranie wyników.

+0

Jeśli skopiowanie pliku tekstowego o wielkości 100 MB bezpośrednio przez sieć zajmuje x sekund, a klient zdalny skompresuje i wyśle ​​plik, a następnie deflacja/odczyt zajmie x/4 sekundy, czy to nie jest tego warte? (Uwaga: właściwie nie wiem, ile czasu zajęłoby kompresowanie/wysyłanie/dekompresowanie/odczyt). – midas06

+0

Za wszelką cenę możesz (i powinieneś) użyć kompresji w sieci. Tak jak powiedziałem, przejrzyj opcje przesyłania strumieniowego IO - niektórzy sugerowali kilka bibliotek zip. OTOH, jeśli możesz umieścić program na zdalnym końcu, tam przetwarzanie tam! –

1

Najprostszym sposobem, biorąc pod uwagę, że już kopiujesz plik, jest skompresowanie go przed kopiowaniem i rozpakowanie po zakończeniu kopiowania. Otrzymasz ogromne zyski kompresując pliki tekstowe, ponieważ algorytmy zip działają na nich bardzo dobrze. Również istniejąca logika parsowania może pozostać nienaruszona, a nie musi być podłączona do zdalnego sieciowego czytnika tekstu.

Wadą tej metody jest to, że nie można uzyskać bardzo wydajnych aktualizacji linii po linii, co jest dobrym rozwiązaniem dla parsera dziennika.

+0

Chciałbym skompresować go, ale jeśli mój kod działa na lokalnej maszynie, zostanie skompresowany po przeniesieniu, co pokonuje cel. Sądzę, że źle skończy się pisanie klienta, który nie robi nic, tylko kompresuje i wysyła. – midas06

0

Użyłem SharpZipLib do kompresowania dużych plików przed ich przesłaniem przez Internet. To jedna opcja.

Innym pomysłem na 1) byłoby utworzenie zespołu, który działa na zdalnym komputerze i przeprowadza tam przetwarzanie. Dostęp do zespołu można uzyskać z komputera lokalnego za pomocą .NET. Zdalny zespół musiałby być usługą Windows lub być hostowany w IIS. Pozwoliłoby to zachować kopie plików dziennika na tym samym komputerze, a teoretycznie przetworzenie ich zajęłoby mniej czasu.

0

myślę użyciu kompresji (korekta/gzip) pomogłoby

1

to chyba zależy od „remote” jest. 100 MB na sieci LAN 100 Mb będzie wynosić około 8 sekund ... aż do gigabitów, a otrzymasz je w około 1 sekundę. 50 $ * 2 za karty, a 100 $ za zmianę to bardzo tania aktualizacja, którą możesz zrobić.

Ale zakładając, że jest dalej, powinieneś być w stanie otworzyć go w trybie tylko do odczytu (tak jak czytasz, gdy go kopiujesz). SMB/CIFS obsługuje czytanie bloków pliku, więc powinieneś przesyłać strumieniowo plik w tym miejscu (oczywiście, nie powiedziałeś, w jaki sposób uzyskiwałeś dostęp do pliku - po prostu zakładam SMB).

Wielowątkowość nie pomoże, ponieważ i tak będziesz mieć dysk lub sieć.

1

Użyj kompresji do transferu.

Jeśli parsowanie naprawdę spowalnia i masz wiele procesorów, możesz przerwać zadanie analizowania, musisz to zrobić w inteligentny sposób - mieć deterministyczny algorytm, za który odpowiedzialni są pracownicy z niepełnymi zapisami. Zakładając, że możesz określić, że linia jest częścią środka rekordu, możesz na przykład podzielić plik na segmenty N/M, z których każdy odpowiada za linie M; gdy jedno z zadań ustali, że jego rekord nie jest skończony, musi tylko czytać dalej, aż osiągnie koniec rekordu. Kiedy jedno z zadań ustali, że odczytuje rekord, dla którego nie ma początku, powinno pominąć rekord.

1

Lepszą opcją, z punktu widzenia wydajności, będzie wykonanie analizy składniowej na serwerze zdalnym. Oprócz wyjątkowych okoliczności, szybkość sieci zawsze będzie wąskim gardłem, więc ograniczenie ilości wysyłanych danych przez sieć znacznie poprawi wydajność.

Jest to jeden z powodów, dla których wiele baz danych korzysta z procedur przechowywanych uruchamianych po stronie serwera.

Ulepszenia szybkości analizowania (jeśli występują) za pomocą wielowątkowości zostaną spowolnione przez szybkość porównywalną transferu sieciowego.

Jeśli chcesz przesłać pliki przed ich analizowaniem, możesz rozważyć użycie kompresji podczas przesyłania plików. Dostępne są na przykład serwery sftp, które będą wykonywać kompresję w locie. Na lokalnym końcu można użyć czegoś takiego jak libcurl, aby wykonać stronę klienta transferu, która obsługuje również dekompresję "w locie".

1

Jeśli możesz skopiować plik, możesz go przeczytać. Dlatego nie ma potrzeby kopiowania go w pierwszej kolejności.

EDYTOWANIE: użyj FileStream class, aby mieć większą kontrolę nad trybami dostępu i udostępniania.

new FileStream("logfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite) 

powinien załatwić sprawę.

+0

Chciałbym się tam różnić. Z mojego doświadczenia wynika, że ​​kopiowanie w użyciu będzie działało, gdy próba przeanalizowania go w strumieniu nie będzie możliwa. Moja teoria mówi, że ta kopia używa innych api Windows, które na to pozwalają. – midas06

+0

Twoja teoria jest zła, imho. Eksplorator Windows używa tych samych API .NET (i FileStream). Spróbowałeś? – VVS

Powiązane problemy