Wie schon im ersten Teil beschrieben, muss man trotz der Platform Unabhängikeit von Java etwas über die Zielsysteme wissen, um grobe Fehler zu vermeiden:
In diesem Fall wird zwar richtigerweise im Fehlerfall der Output Stream geschlossen und die dabei eventuell auftretende Exception ignoriert, aber viel kritischer ist der Fall in dem im try block keine Exception aufgetreten ist, aber dafür dann das close() fehlschlägt.
Es muss damit gerechnet werden dass im close() auf einem OutputStream eine IOException auftreten kann - sogar sehr häufig - der Grund dafür ist, dass zum einen der Stream einen flush() vor dem close() durchführen wird. Dazu kommt noch, dass die close() Methode der letzte Zeitpunkt ist, in dem ein IO Fehler gemeldet werden kann. Bei NFS ist es z.B. so, dass der client wartet bis der Server den Empfang bestätigt hat. Und dabei kann natürlich eine Menge schiefgehen. Auch quota Überschreitungen können zu einer IOException führen.
Es hilft etwas als letztes Statement im try-block einen flush() durchzuführen, aber es besteht weiterhin ein Risiko dass close() fehlschlägt. Eine wichtige Regel lautet also: bei Streams in die geschrieben wird kann close() einen Fehler werfen, diese darf nicht ignoriert werden (sonst gehen Daten verloren)!
Im Falle von NFS ist obiger Code ausreichend. Nach dem close() ist es garantiert, dass die Daten permanent gespeichert sind. Bei lokalen Filesystemen wird diese Garantie von den gängigen Betriebsystemen NICHT gegeben. Die Daten können auch nach einem close() nur im lokalen Buffer Cache des Filesystems (RAM) liegen und erst nach einiger Zeit (typischerweise 5 Sekunden) an die Hardware Schicht übergeben werden. Dies ist zwar gut für die Performance, aber ein potentielles Fenster für Datenverlust - und eventuell Korruption des Anwendungszustandes.
Wie dies zu vermeiden ist, betrachte ich im nächsten Teil (der kein Jahr auf sich warten lassen wird:)
/** save data as UTF-8 string to file. */
saveFile(String data, File file) throws IOException, UnsupportedEncodingException {
OutputStream out = null;
bytes[] b = data.getBytes("UTF-8");
try {
out = new FileOutputStream(file);
out.write(b);
} catch(IOException ioe) {
System.err.println("Cannot save data in UTF-8 to file " + file + ": " + ioe);
throw ioe; // notify upper layer about problem
} finally {
silentClose(out); out = null; // BANG, problem unterdrückt.
}
}
silentClose(OutputStream out) {
if (out != null)
try { out.close(); } catch (Exception ignored) { }
}In diesem Fall wird zwar richtigerweise im Fehlerfall der Output Stream geschlossen und die dabei eventuell auftretende Exception ignoriert, aber viel kritischer ist der Fall in dem im try block keine Exception aufgetreten ist, aber dafür dann das close() fehlschlägt.
Es muss damit gerechnet werden dass im close() auf einem OutputStream eine IOException auftreten kann - sogar sehr häufig - der Grund dafür ist, dass zum einen der Stream einen flush() vor dem close() durchführen wird. Dazu kommt noch, dass die close() Methode der letzte Zeitpunkt ist, in dem ein IO Fehler gemeldet werden kann. Bei NFS ist es z.B. so, dass der client wartet bis der Server den Empfang bestätigt hat. Und dabei kann natürlich eine Menge schiefgehen. Auch quota Überschreitungen können zu einer IOException führen.
Es hilft etwas als letztes Statement im try-block einen flush() durchzuführen, aber es besteht weiterhin ein Risiko dass close() fehlschlägt. Eine wichtige Regel lautet also: bei Streams in die geschrieben wird kann close() einen Fehler werfen, diese darf nicht ignoriert werden (sonst gehen Daten verloren)!
saveFile(String data, File file) throws IOException, UnsupportedEncodingException {
OutputStream out = null;
bytes[] b = data.getBytes("UTF-8");
try {
out = new FileOutputStream(file);
out.write(b);
out.close(); out = null;
} catch(IOException ioe) {
System.err.println("Cannot save data in UTF-8 to file " + file + ": " + ioe);
throw ioe;
} finally {
silentClose(out); out = null;
}
}Im Falle von NFS ist obiger Code ausreichend. Nach dem close() ist es garantiert, dass die Daten permanent gespeichert sind. Bei lokalen Filesystemen wird diese Garantie von den gängigen Betriebsystemen NICHT gegeben. Die Daten können auch nach einem close() nur im lokalen Buffer Cache des Filesystems (RAM) liegen und erst nach einiger Zeit (typischerweise 5 Sekunden) an die Hardware Schicht übergeben werden. Dies ist zwar gut für die Performance, aber ein potentielles Fenster für Datenverlust - und eventuell Korruption des Anwendungszustandes.
Wie dies zu vermeiden ist, betrachte ich im nächsten Teil (der kein Jahr auf sich warten lassen wird:)
Trackbacks
Trackback für spezifische URI dieses Eintrags
Keine Trackbacks
Kommentare
Ansicht der Kommentare:
(Linear | Verschachtelt)
"Im Falle von NFS ist obiger Code ausreichend. Nach dem close() ist es garantiert, dass die Daten permanent gespeichert sind."
Das halte ich aber für gewagt, wer sagt denn, dass der Dateiserver nicht ebenso die Daten zwischenspeichert? http://java.sun.com/j2se/1.5.0/docs/api/java/nio/channels/FileChannel.html#force(boolean) sagt z.B. gerade, dass bei nicht-lokalen Speichern diese Garantie nicht gegeben wird.
"Die Daten können auch nach einem close() nur im lokalen Buffer Cache des Filesystems (RAM) liegen"
Unter Windows abzuschalten unter Eigenschaften der Festplatte - Richtlinien - Schreibcache aktivieren. Deaktivieren dieses Caches hat in persönlichen Tests mit Stecker-ziehen ergeben, dass Daten die aus Programmsicht geschrieben waren danach dann auch wirklich vom Schreibkopf auf die Scheibe übergegangen waren.
Deswegen muss der NFS Client bei einem close ein COMMIT machen, welches im NFS Protkoll (falls der Server dies richtig implementiert) nicht nur dazu fuhert dass die Puffer zum Server übertragen werden, sondern dort auch festgeschrieben werden.
Layout by Ricky Wilson | Serendipity Template by Carl Galloway | Login
Impressum
Bernd Eckenfels
Mörscher Str. 8
76185 Karlsruhe
bernd-08(a)eckenfels.net
Read More
Suche
Verlinkung
Eingehende Links
Umfrage
Inhouse Coding?
Archive
Archive
Kommentare
Bernd Eckenfels zu Terminkonflikt
2008-07-21 20:44
Hallo Beate,
ich war leider nich
t dort. Und mich ärgert es auch, da
ss so ein Verein es nicht auf die R
eihe beko [...]
2008-07-21 20:44
Beate zu Terminkonflikt
2008-07-18 21:17
Warst du bei der Vereinsgründung? W
ie wars? Ich finde aber auch nirgen
ds was drüber. Und angeschrieben ha
tte ich a [...]
2008-07-18 21:17
wolfgang bernsdorf zu Arbeitsplatz Schönheit bei der AxelSpringer AG
2008-07-15 19:00
Umstellung auf apple pc. So schöne
pc`s
kann es nicht geben, um gerne
bei Springer zu arbeiten (Spandau)
.
2008-07-15 19:00
Bernd Eckenfels zu Review: Team Beam
2008-07-01 04:35
Es gibt ein kleines Java Programm m
it dem man auf seinen Amazon S3 Acc
ount hochladen kann. Das tool kann
auch time [...]
2008-07-01 04:35
Christian Geisert zu Nostalgie in Sachen DatenFernÜbertragung
2008-06-12 14:47
grummel Registrierung grummel l
ahme Website grummel Download sch
lecht implementiert (falscher Datei
name, kei [...]
2008-06-12 14:47
Bernd Eckenfels zu Kündigungswellen trotz Rekordumsätze
2008-05-30 00:44
Fixed :) Danke Jennifer. Ich hatte
das Archiv gesehen aber da waren ir
gendwie nicht alle Artikel zu sehen
?
2008-05-30 00:44
Dana zu Kündigungswellen trotz Rekordumsätze
2008-05-29 11:14
Örx ... :-)
Bitte das /Blog/ in
der URL durch /Archive/ ersetzen. I
ch hätte das Permalink-URL-Schema a
nders wäh [...]
2008-05-29 11:14
Bernd Eckenfels zu Kündigungswellen trotz Rekordumsätze
2008-05-29 10:10
Ja, Jennifer hat wohl ihr Blog entf
ernt und nicht alle Artikel archivi
ert, ich frag Sie mal...
Gruss
Bernd
2008-05-29 10:10
visitor zu Kündigungswellen trotz Rekordumsätze
2008-05-27 23:44
Schade, bekomme unter dem angegeben
en Link leider nur "404 Resource no
t found" zu sehen :-(
2008-05-27 23:44
Bernd Eckenfels zu Sun Cluster
2008-05-21 00:43
Ich vermut mal 32-128 Knoten. Aber
da es sich hier ja um HA und nicht
MP/HPC Cluster Knoten handelt dürft
en die se [...]
2008-05-21 00:43
Blog abonnieren
Blogsphere
Letzten Monat...
Mi, 09.07.2008Optimierungen beim Java Threading
So, 06.07.2008Arbeitsplatz Schönheit bei der AxelSpringer AG
Fr, 04.07.2008DoD über CC
Do, 03.07.2008Null returns in Java
Mo, 30.06.2008Oracle EL: Gut Gemeint
So, 06.07.2008Arbeitsplatz Schönheit bei der AxelSpringer AG
Fr, 04.07.2008DoD über CC
Do, 03.07.2008Null returns in Java
Mo, 30.06.2008Oracle EL: Gut Gemeint
Top Referers
www.google.de (32)
gamingslots.webng.com (3)
www.eckes.org (2)
www.google.com (2)
www.keywordspy.com (2)
www.yasni.de (2)
de.search.yahoo.com (1)
search.live.com (1)
suche.t-online.de (1)
www.google.at (1)
gamingslots.webng.com (3)
www.eckes.org (2)
www.google.com (2)
www.keywordspy.com (2)
www.yasni.de (2)
de.search.yahoo.com (1)
search.live.com (1)
suche.t-online.de (1)
www.google.at (1)
