Benutzer mit den meisten Antworten
Schreiben einer Text-Datei via Out-File - schlechte Performance

Frage
-
Hallo zusammen,
ich untersuche aktuell ein Storage-seitiges Performance-Problem in unserer Organisation.
Das Problem hat nicht direkt etwas mit Powershell zu tun, aber ich möchte hier starten.Wir haben eine spezielle Software (Hauptanwendung für einen Standort), welche immer wieder Performance Probleme hat.
Jeder Benutzer hat ein Konfigurationsfile (ini) mit ca. 1000 Zeilen. Das Konfigurationsfile liegt zentral am Home-Laufwerk des jew. Users. Die Home-Laufwerke liegen auf der Storage (3rd Party).Ich habe festgestellt, dass wenn das Konfigurationsfile auf der lokalen Disk des Endgerätes liegt, sich die Performance um ca. 50% verbessert. Eine ähnliche Verbesserung erhalte ich, wenn das Konfigurationsfile auf einem Microsoft Windows File-Share liegt.
Ich habe das auch soweit es mir möglich ist mit WireShark getracet und erhebliche Unterschiede festgestellt.
Die Storage ist schon lange Hauptverdächtig für viele Probleme. Das Storage-Team hat bis jetzt nichts auf die Reihe gebracht und ich möchte eine handfeste Analyse erstellen und dann zum Storage-Team werfen.Im Moment versuche ich mit Powershell das Szenario zu reproduzieren. Ich schreibe eine Text-Datei mit xxxx-Zeilen via "Out-File" auf diverse Ziele. Das Ergebnis sieht folgendermaßen aus:
Es wurde eine Text-Datei mit den folgenden Eigenschaften geschrieben: Dateigröße: 0,30 MB Zeilenzahl: 13248 Die folgenden Zeiten wurden gemessen ... Write-Time Lokal: 0,8997679 Sekunden (C:\...) Write-Time Storage: 17,9524958 Sekunden (\\Domain.local\...) Write-Time MS_Share: 16,8436178 Sekunden (\\Domain.local\...) Das Schreiben auf die Storage ist im Vergleich um ca. 1895 Prozent langsamer!
Was mich dabei stört ist, dass das Schreiben auf einen Microsoft-Share auch extrem langsam ist.
Die Endgeräte laufen auf Windows 7. (SMB2)
Auf einem Endgerät mit Windows 10 (SMB3) ist die Performance beim Schreiben auf einen Netzwerk-Share nahezu gleich performant wie beim Schreiben auf die lokale Disk.
Die Performance unter Windows 7 verbessert sich auch nicht, wenn ich die Settings der üblichen Verdächtigen ändere. (SMB2 deaktivieren, Offloading deaktivieren, Chimney deaktivieren, IPv6 deaktiveren, ...)Bevor ich hier weiter mache, wollte ich fragen, ob es aus Programmiertechnischer Sicht eine logische Erklärung gibt, dass das Schreiben einer Textdatei auf eine Netzwerkfreigabe so extrem langsam ist?
Habt Ihr auch via SMB2 beim Schreiben auf einen Netzwerkshare via Out-File ähnlich schlechte Performance?
Via WireShark denke ich erkennen zu können, dass hier Zeilenweise geschrieben wird und nicht alles am Stück.Vielen Dank im Voraus
- Bearbeitet Panteraa Dienstag, 17. Januar 2017 07:14
- Typ geändert Denniver ReiningMVP, Moderator Donnerstag, 19. Januar 2017 11:23 .....
- Typ geändert Denniver ReiningMVP, Moderator Freitag, 20. Januar 2017 14:06 .....
Antworten
-
Also was Powershell betrifft, ist "out-file" wahrscheinlich die langsamste Art eine Datei zu schreiben.
Das liegt unter anderem daran, das hier vor jeder geschriebenen Zeile die Datei gesperrt und nach jeder Zeile freigegeben wird, was den gleichzeitigen Zugriff von anderen Prozessen auf das File erlaubt, aber massiv Performance kostet. Diverse .NET-Methoden, aber auch z.B. Set-Content ist deutlich schneller, u.a. weil es die Datei über die komplette Zeit sperrt. (hier sind noch mehr Unterschiede LINK)
Übers Netzwerk verschärft sich das Problem nochmals. In meinem Test war kein Unterschied bei Set-Content zwischen lokal und SMB2, allerdings auch unter LAB-Bedingungen mit sehr flotter Netzanbindung und quasi keinem anderen Traffic.
1MB Textfile ASCII Out-File Lokal 1,3101044 Set-Content Lokal 0,4239831 Out-File SMB2 11,7188623 Set-Content SMB2 0,4118863
Damit hast du dann auch deine Vergleichswerte. Das Encoding sollte sich hier nur insofern auswirken, als das z.B eine (ungewollte) Konvertierung in ein anderes Encoding, bei gleichem Text eine deutlich größere Datei erzeugen kann und damit die Performance sinkt.
SMB3 kann meiner Erfahrung nach deutlich schneller als SMB2 sein, muss es aber nicht, hängt am Ende von den beteiligten Komponenten ab.
Die Joker-Frage ist netzwerkspezifisch und wer weiß, möglicherweise sogar speziell in eurer Umgebung begründet und damit sicher in einem Netzwerkforum deutlich besser aufgehoben. :)
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Neu: Powershell Code Manager v5 ! Link
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.
- Bearbeitet Denniver ReiningMVP, Moderator Freitag, 20. Januar 2017 13:56
- Als Antwort markiert Panteraa Freitag, 20. Januar 2017 14:47
-
Moin,
1. was brima gesagt hat. Durch die Nutzung von .NET-Klassen statt Out-File beschleunigst Du das Schreiben um den Faktor 2-5, aber mehr auch nicht (s. z.B. auch http://www.it-pro-berlin.de/2016/05/powershell-hack-utf-8-ohne-bom-ausgeben/ ).
2. Deine Erfahrungen bekräftigen noch einmal, warum SMB3 wirklich der neue gelie Sch... ist ;-)
3. Was es sich bei SMB2 aus Performance-Sicht lohnen könnte zu deaktivieren, ist SMB-Signierung. Aus Security-Sicht willst Du es natürlich überhaupt nicht.
4. Wenn Du soviel Einfluss auf den Code hast, dass Du bestimmen kannst, wie die Datei generiert wird, kannst Du es natürlich deutlich beschleunigen, indem Du den Content im RAM einsammelst und dann in einem Vorgang in die Datei schreibst.
5. Was sagen TCP-Retransmissions, wenn Du von Windows 7 übers Netzwerk schreibst?
Evgenij Smirnov
I work @ msg services ag, Berlin -> http://www.msg-services.de
I blog (in German) @ http://it-pro-berlin.de
my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
Exchange User Group, Berlin -> http://exusg.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com- Als Antwort markiert Denniver ReiningMVP, Moderator Freitag, 20. Januar 2017 23:28
Alle Antworten
-
Hallo,
also rein von der programmtechnischen Seite kann über die PowerShell im IO Breich Performance herauskitzelen, wenn man Lese - / Schreib Vorgänge direkt über die Klasse [System.IO.File] abhandelt, das wird dann aber aufwendiger weil du dich dann jenachdem um Dinge selbst kümmern musst, die in den CMDLets für IO (wie out-file, set-content, get-content usw.) schon eingebaut sind.
KlickOb sich dass aber grundsätzlich auf deine unterschiedlichen Destinattion auswirkt wage ich zu bezweifeln, d.h. die dürften jeweils schneller sein, aber am Verhaältnis ändert sich eher wenig.
Zudem wäre es auch natürlcih sehr interessant für uns den Code zu zeigen mit dem du deine Testdatai erzeugst.
Beste Gruesse
brima -
Moin,
1. was brima gesagt hat. Durch die Nutzung von .NET-Klassen statt Out-File beschleunigst Du das Schreiben um den Faktor 2-5, aber mehr auch nicht (s. z.B. auch http://www.it-pro-berlin.de/2016/05/powershell-hack-utf-8-ohne-bom-ausgeben/ ).
2. Deine Erfahrungen bekräftigen noch einmal, warum SMB3 wirklich der neue gelie Sch... ist ;-)
3. Was es sich bei SMB2 aus Performance-Sicht lohnen könnte zu deaktivieren, ist SMB-Signierung. Aus Security-Sicht willst Du es natürlich überhaupt nicht.
4. Wenn Du soviel Einfluss auf den Code hast, dass Du bestimmen kannst, wie die Datei generiert wird, kannst Du es natürlich deutlich beschleunigen, indem Du den Content im RAM einsammelst und dann in einem Vorgang in die Datei schreibst.
5. Was sagen TCP-Retransmissions, wenn Du von Windows 7 übers Netzwerk schreibst?
Evgenij Smirnov
I work @ msg services ag, Berlin -> http://www.msg-services.de
I blog (in German) @ http://it-pro-berlin.de
my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
Exchange User Group, Berlin -> http://exusg.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com- Als Antwort markiert Denniver ReiningMVP, Moderator Freitag, 20. Januar 2017 23:28
-
Hallo,
grundsätzlich brauche ich kein Tuning für das Powershell-Script. Ich kenne diese StreamWrite-Geschichte.
Ich versuche ein Szenario zu finden, dass ich unserem Storage-Team, den Storage-Hersteller oder vielleicht dem Netzwerk-Team zeigen kann - so ala: Schau her auf einem Microsoft-Share braucht das 1 Sekunde und auf die Storage braucht das 20 Sekunden.
Ich war mit meinem Script anfangs zuversichtlich, die schlechte Performance reproduzieren zu können, jedoch verwundert es mich, dass das Schreiben auf einem Microsoft-Share via SMB1 und SMB2 ebenso lange dauert.
Via SMB3-Client geht's schnell ... Ich versuche jetzt auch dahinterzukommen warum.Mein Script ist sehr einfach gestrickt:
Ich lese eine originale Config-Datei ein:
$Content = Get-Content -Path $OriginaleUserConfigINI
Ich vervielfältige den Content um mehr Zeilen zu erhalten:
for ($i=1; $i -le $LoopCount; $i++) { $Content += $Content }
Ich schreibe den Inhalt von $Content in eine Datei auf der Storage und messe die Zeit:
$WriteTimeStorage = Measure-Command -Expression { $Content | Out-File -FilePath $StorageDestination -Encoding default }
- Bearbeitet Panteraa Dienstag, 17. Januar 2017 10:13
-
>>> 5. Was sagen TCP-Retransmissions, wenn Du von Windows 7 übers Netzwerk schreibst?
Ich bin kein Netzwerker und kann dir keine direkte Antwort darauf geben.
Es passt hier auf keinen Fall ins Powershell-Forum, aber hier ein Vergleich des Wireshark-Traces zwischen Schreiben auf die Storage (links) und schreiben auf einen Microsoft Windows Share (rechts).
Da sehe sogar ich als Nicht-Netzwerker, dass da was nicht stimmt ...EDIT: ich darf keine Bilder posten. Nachfolgend ein Link zum Bild:
http://img5.fotos-hochladen.net/uploads/wiresharkep41vjq3ah.png -
>>> 5. Was sagen TCP-Retransmissions, wenn Du von Windows 7 übers Netzwerk schreibst?
Ich bin kein Netzwerker und kann dir keine direkte Antwort darauf geben.
Evgenij Smirnov
I work @ msg services ag, Berlin -> http://www.msg-services.de
I blog (in German) @ http://it-pro-berlin.de
my stuff in PSGallery --> https://www.powershellgallery.com/profiles/it-pro-berlin.de/
Exchange User Group, Berlin -> http://exusg.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.com -
So jetzt noch etwas seltsames ...
Nutzung der .NET Klasse [System.IO.File]:
$Content = Get-Content -Path $OriginaleUserConfigINI for ($i=1; $i -le $LoopCount; $i++) { $Content += $Content } $WriteTimeStorage = Measure-Command -Expression { [System.IO.File]::WriteAllLines($StorageDestination, $Content) }
Ergebnis:
Es wurde eine Text-Datei mit den folgenden Eigenschaften geschrieben: Dateigröße: 0,30 MB Zeilenzahl: 13248 Die folgenden Zeiten wurden gemessen ... Write-Time Lokal: 0,0243907 Sekunden (C:\...) Write-Time Storage: 0,1287163 Sekunden (\\Domain.local\...) Das Schreiben auf die Storage ist im Vergleich um ca. 428 Prozent langsamer!
Gibt es irgendeine logische Erklärung hinsichtlich Storage-Performance, warum das jetzt über die Klasse von vorher 18 Sekunden auf 0,12 Sekunden runter ist? Erwartet war ja ein Verbesserung um Faktor von 2-5.
- Bearbeitet Panteraa Dienstag, 17. Januar 2017 11:40
-
> Erwartet war ja ein Verbesserung um Faktor von 2-5.
Vielleicht lags an der Erwartung. ;-)
Meiner Erfahrung nach beschleunigt das lokal um einen Faktor 10 - 20.
Lokal, wohlgemerkt. Der Faktor hängt nach oben aber auch schlicht davon ab, wie schnell die Platte die Daten liefern kann.
Übers Netzwerk kommen immer aber noch zusätzliche Faktoren hinzu, die das Ergebnis verfälschen können, insbesondere bei so kurzen Aktionen im Millisekundenbereich.
Schau doch mal wie sich der Unterschied darstellt, wenn du 50 MB schreibst.Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Neu: Powershell Code Manager v5 ! Link
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.- Bearbeitet Denniver ReiningMVP, Moderator Dienstag, 17. Januar 2017 12:31
-
>>> Schau doch mal wie sich der Unterschied darstellt, wenn du 50 MB schreibst.
Das ist kein Problem:
Es wurde eine Text-Datei mit den folgenden Eigenschaften geschrieben: Dateigröße: 77,94 MB Zeilenzahl: 3391488 Die folgenden Zeiten wurden gemessen ... Write-Time Lokal: 2,1599077 Sekunden (C:\...) Write-Time Storage: 28,0579477 Sekunden (\\Domain.local\...) Das Schreiben auf die Storage ist im Vergleich um ca. 1199 Prozent langsamer!
-
Das war offenbar ein Missverständnis.
Die Bemerkung bez. des Faktors sowohl von Evgenij als auch von mir, bezog sich auf den Vergleich zwischen Powershell-Cmdlet und [System.IO.File]-Methode, nicht auf lokal vs. Netz.
Blog: http://bytecookie.wordpress.com
Neu: Powershell Code Manager v5 ! Link
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.
-
Gut. :) Ok, gehts hier jetzt noch um Powershell oder eigentlich nur um die Schreibperformance -unabhängig von der Methode- übers Netz auf verschiedene Ziele?
Falls Powershell, konkretisiere bitte die eigentlich Frage mal.Blog: http://bytecookie.wordpress.com
Neu: Powershell Code Manager v5 ! Link
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.
-
Hallo,
grundsätzlich habe ich die Analyse meiner WireShark-Traces bei einem Consultant in Auftrag gegeben.
Die Hoffnung lebt, dass ich hier mehr über den Hintergrund der Performance-Probleme erfahren werde.
Aus Powershell-Sicht wollte ich wenn möglich noch die Dinge aus dem Eingangspost wissen.Die Performance-Daten aus den vorangegangenen Posts kurz zusammengefasst:
Schreiben einer Text-Datei via Out-File (Dateigröße 0,3 MB | Zeilenzahl 13.500 | SMB2):
Lokale Disk: 0,8 Sekunden
Storage via LAN: 18 Sekunden
Schreiben einer Text-Datei via [System.IO.File] (Dateigröße 78 MB | Zeilenzahl 3.391.488 | SMB2):
Lokale Disk: 2 Sekunden
Storage via LAN: 28 Sekunden- Gibt es eine Erklärung dafür, dass das Schreiben einer Textdatei auf eine Netzwerkfreigabe vergleichsweise langsam ist bzw. liegt der Unterschied eurer Meinung nach im Rahmen?
- Habt Ihr auch via SMB2 beim Schreiben auf einen Netzwerkshare via Out-File ähnlich schlechte Performance bzw. hat jemand von euch ev. Vergleichswerte?
- Kann der Inhalt der Text-Datei in irgendeiner Form einen Einfluss haben? (Encoding, ...)
- Joker-Frage:
Nachfolgend ein Screenshot der Netzwerkstatistik. Die Aufzeichnung zeigt nicht den Kopiervorgang via Powershell sondern das Starten der Applikation.
links -> Konfigurationsdatei (20 KB) liegt auf einem Windows-Share -> 900 Pakete werden ausgetauscht. Insg. 2 MB
rechts -> Konfigurationsdatei (20 KB) liegt auf der Storage -> 10.000 Pakete werden ausgetauscht. Insg. 26 MB
http://img5.fotos-hochladen.net/uploads/wiresharkep41vjq3ah.png
Gibt es eine Erklärung/Idee dazu?
Danke
- Bearbeitet Panteraa Freitag, 20. Januar 2017 09:22
- Gibt es eine Erklärung dafür, dass das Schreiben einer Textdatei auf eine Netzwerkfreigabe vergleichsweise langsam ist bzw. liegt der Unterschied eurer Meinung nach im Rahmen?
-
Also was Powershell betrifft, ist "out-file" wahrscheinlich die langsamste Art eine Datei zu schreiben.
Das liegt unter anderem daran, das hier vor jeder geschriebenen Zeile die Datei gesperrt und nach jeder Zeile freigegeben wird, was den gleichzeitigen Zugriff von anderen Prozessen auf das File erlaubt, aber massiv Performance kostet. Diverse .NET-Methoden, aber auch z.B. Set-Content ist deutlich schneller, u.a. weil es die Datei über die komplette Zeit sperrt. (hier sind noch mehr Unterschiede LINK)
Übers Netzwerk verschärft sich das Problem nochmals. In meinem Test war kein Unterschied bei Set-Content zwischen lokal und SMB2, allerdings auch unter LAB-Bedingungen mit sehr flotter Netzanbindung und quasi keinem anderen Traffic.
1MB Textfile ASCII Out-File Lokal 1,3101044 Set-Content Lokal 0,4239831 Out-File SMB2 11,7188623 Set-Content SMB2 0,4118863
Damit hast du dann auch deine Vergleichswerte. Das Encoding sollte sich hier nur insofern auswirken, als das z.B eine (ungewollte) Konvertierung in ein anderes Encoding, bei gleichem Text eine deutlich größere Datei erzeugen kann und damit die Performance sinkt.
SMB3 kann meiner Erfahrung nach deutlich schneller als SMB2 sein, muss es aber nicht, hängt am Ende von den beteiligten Komponenten ab.
Die Joker-Frage ist netzwerkspezifisch und wer weiß, möglicherweise sogar speziell in eurer Umgebung begründet und damit sicher in einem Netzwerkforum deutlich besser aufgehoben. :)
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Neu: Powershell Code Manager v5 ! Link
(Schneller, besser + komfortabler scripten.)
Hilf mit und markiere hilfreiche Beiträge mit dem "Abstimmen"-Button (links) und Beiträge die eine Frage von dir beantwortet haben, als "Antwort" (unten).
Warum das Ganze? Hier gibts die Antwort.
- Bearbeitet Denniver ReiningMVP, Moderator Freitag, 20. Januar 2017 13:56
- Als Antwort markiert Panteraa Freitag, 20. Januar 2017 14:47
-
Vielen Dank - Dein Beitrag war sehr hilfreich.
Anhand deiner eruierten Werte/Zeiten zum Schreiben der Datei sehe ich, dass der Unterschied zw. Schreiben auf eine lokale Disk und Schreiben auf einen Netzwerkshare in der Tat so gewaltig sein kann.
Das zeigt mir, dass ich mit der gewollten Methode die schlechte Anwendungsperformance leider so nicht nachstellen kann.
Ich habe auch ein erstes Feedback von meinem Consultant bekommen. Meine WireShark-Traces, die die Anwendungsperformance zeigen, wurden begutachtet. Wie erwartet wurde die Ursache selbst noch lange nicht ausgemacht.
Ich habe mehrere Graphen bekommen, die massive Unterschiede zw. der 3rd-Party Storage und einem Standard Windows-Share zeigen. Der Graph sieht zum Schluss hin beim eigentlichen Zugriff bei beiden Szenarien gleich aus. Bevor die Storage aber dorthin kommt werden für 6 Sekunden lang massiv Pakete ausgetauscht. Man sieht auch ein andauerndes Open/Close auf die Datei und noch viel mehr unerklärliche Phänomene für die X-Akten.
Die Folder-Redirection (Desktop) sieht man auch dauernd im Traffic. Ich muss jetzt noch weitere Traces liefern, wo die Konfig-Datei alleine auf einem Share auf einem anderen Knoten der Storage liegt.
Schöne Grüße