2013-03-15 8 views
6

Próbuję utworzyć pliki 300M z programu java, przełączyłem się ze starego interfejsu API pliku na nowy pakiet java 7 nio, ale nowy pakiet będzie działał nawet wolniej niż stary.Pakiet nio.file Java 7 jest bardzo wolny przy tworzeniu nowych plików

Widzę mniej wykorzystania procesora niż ja, gdy korzystałem ze starego interfejsu API pliku, ale używam tego prostego kodu i uzyskuję szybkość transferu plików 0,5 Mb/s, a zapisy z java czytają jeden zapisywanie i zapisywanie na innym dysku (zapis jest jedynym procesem uzyskującym dostęp do dysku).

Files.write(FileSystems.getDefault().getPath(filePath), fiveToTenKBytes, StandardOpenOption.CREATE); 

Czy są jakieś nadzieje na uzyskanie rozsądnej przepustowości?


Aktualizacja:

mam rozpakowaniu 300 milionów 5-10k bajtowych plików graficznych z dużymi plikami. Mam 3 dyski, 1 lokalny i 2 SAN (wszystkie mają typową przepustowość ~ 20MB/s na dużych plikach).

Próbowałem również tego kodu, który zwiększył prędkość do zaledwie mniej niż 2MB/s przepustowości (9 dni na rozpakowanie tych plików).

ByteBuffer byteBuffer = ByteBuffer.wrap(imageBinary, 0, (BytesWritable)value).getLength()); 
FileOutputStream fos = new FileOutputStream(imageFile); 
fos.getChannel().write(byteBuffer); 
fos.close(); 

Odczytuję z dysku lokalnego i zapisuję na podłączonym dysku SAN. Czytam z formatu Hadoop SequenceFile, hadoop jest zazwyczaj w stanie odczytać te pliki z prędkością 20 MB/s, używając w zasadzie tego samego kodu.

Jedyne, co wydaje się nie na miejscu, inne niż wolne spowolnienie, to to, że widzę więcej odczytu IO niż napisanie IO o około 2: 1, chociaż plik sekwencji jest gzipowany (obrazy uzyskują praktycznie współczynnik 1: 1 choć), więc skompresowany plik powinien wynosić ok. 1: 1 z wyjściem.


2-ty UPDATE

Patrząc na iostat widzę niektóre numery nieparzyste, patrzymy na xvdf tutaj, mam jeden proces java czytania i pisania od xvdb do xvdf i żadne procesy Ohter aktywny na xvdf

iostat -d 30 
Device:   tps kB_read/s kB_wrtn/s kB_read kB_wrtn 
xvdap1   1.37   5.60   4.13  168  124 
xvdb    14.80  620.00   0.00  18600   0 
xvdap3   0.00   0.00   0.00   0   0 
xvdf   668.50  2638.40  282.27  79152  8468 
xvdg   1052.70  3751.87  2315.47  112556  69464 

odczyty na xvdf są 10x pisze, że to niewiarygodne.

fstab 
/dev/xvdf  /mnt/ebs1  auto defaults,noatime,nodiratime  0  0 
/dev/xvdg  /mnt/ebs2  auto defaults,noatime,nodiratime  0  0 
+0

Jak duże są te pliki? – parsifal

+0

@parsifal "Próbuję utworzyć pliki 300M [...]" – Puce

+2

Czytam to jako "Próbuję utworzyć 300 milionów (lub tysięcy) plików", a nie "Próbuję utworzyć jeden plik, który jest 300 MB "(w przeciwnym razie, dlaczego używasz" M ", a nie" Mb "?). – parsifal

Odpowiedz

1

Myślę, że twoje powolne tempo pochodzi z tworzenia nowych plików, a nie z faktycznego transferu. Uważam, że tworzenie pliku jest operacją synchroniczną w systemie Linux: wywołanie systemowe nie powróci, dopóki plik nie zostanie utworzony i katalog nie zostanie zaktualizowany.Sugeruje to kilka rzeczy, które możesz zrobić:

  • Użyj wielu wątków do pisania z jednym wątkiem czytnika. Wątek czytnika odczyta dane z pliku źródłowego do byte[], a następnie utworzy plik Runnable, który zapisuje plik wyjściowy z tej tablicy. Użyj threadpool z dużą ilością wątków - może 100 lub więcej - ponieważ będą spędzać większość czasu, czekając na ukończenie creat. Ustaw pojemność kolejki wejściowej tej puli na podstawie ilości posiadanej pamięci: jeśli twoje pliki mają rozmiar 10 kB, pojemność kolejki na 1000 wydaje się rozsądna (nie ma żadnego powodu, aby pozwolić czytelnikowi znaleźć się zbyt daleko przed pisarzami , więc możesz nawet iść z pojemnością dwukrotnie większą niż liczba wątków).
  • Zamiast NIO użyj podstawowych BufferedInputStream s oraz BufferedOutputStreams. Twoim problemem tutaj są syscalls, a nie szybkość pamięci (klasy NIO mają na celu zapobieganie kopiom między stertą a stertą).

Zakładam, że już wiesz, nie próbuj przechowywać wszystkich plików w jednym katalogu. Lub nawet przechowywać więcej niż kilkaset plików w jednym katalogu.

Czy jako alternatywę rozważałeś S3 do przechowywania? Zgaduję, że jego klucze do wiaderek są znacznie wydajniejsze niż rzeczywiste katalogi, i istnieje filesystem, który umożliwia dostęp do zasobników tak, jakby były plikami (nie próbowałem samodzielnie).

+0

Utworzyłem 2 procesy robiące to, a prędkości dysków spadły dramatycznie, ale agregacja 2 procesów wynosiła 2MB/s, nieco lepiej, ale nie wyglądało na to, że więcej asynchronicznych procesów pomogłoby w tej sytuacji. Jeśli chodzi o S3, to była moja pierwsza myśl i nie udało się to z ogromną eksplozją. 2 tygodnie w Internecie z technikami starającymi się, aby pliki 300M do przesłania nie powiodły się i kosztowały mnie 10 tys. Opłat za użytkowanie, nawet jeśli działały po raz pierwszy (z czym na pewno nie). Mówisz 3k tylko po to, żeby przesłać pliki. Oglądaj te małe 0,10 USD/100 za szarżę, to skrada się na ciebie naprawdę szybko !! –

+0

Próbuję teraz dużych plików (które mogę utworzyć wspaniale szybko) i przechowywania wskaźnik do bajtów w dużym pliku. To wszystko idzie o wiele bardziej płynnie do tej pory, i to podejście facebook używa jak czytam. Będę pisać o jego sukcesie, kiedy skończę. –

+0

Wynik końcowy: Nie rób 300M małych plików. Przechodzimy do bardziej złożonego systemu, w którym ładujemy dane binarne do dużych plików i zachowujemy offset indeksu do danych binarnych. Eksperymentujemy również z dużymi tabelami mysql/myisam jako dobrą opcją. –

2

Jeśli dobrze zrozumiałem swój kod, jesteś dzielenie/zapisu plików 300M w małych kawałkach („fiveToTenKBytes”).

Rozważ użycie a Stream approach.

Jeśli piszesz na dysk, pomyśl o zawinięciu strumienia OutputStream w BufferedOutputStream.

E.g. coś takiego:

try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.getPath(filePathString), StandardOpenOption.CREATE))){ 

... 

} 
+0

@JoachimSauer Dzięki za edycję, ale StackOverflow ma problemy z łączami metod ... – Puce

+0

Wiem, ale dodany link działał dobrze (przynajmniej dla mnie). A ten, który teraz stoi, przenosi cię tylko do dokumentacji 'Files', ze względu na miejsce w niej. –

+0

Ah, to wydaje się być problemem w IE 8. W przeglądarce Firefox działa. – Puce

Powiązane problemy