-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parallelise upload to get better upload speeds #6
base: master
Are you sure you want to change the base?
Conversation
I'm glad to see that you're taking this on. Trying to get large files through WinRM quickly is a difficult problem. Sending files using XML SOAP is never going to be pretty, breaking files up into individual tasks should help save some time with parallelization and also make it much easier to insert fail/retry logic. As for a parallelization flag, in the long run you might consider only supporting 1. not-parallel and 2. fast-as-we-can-parallel. Between the different flavors of Windows and the wildly different WinRM configurations (max ops per shell, max concurrent operations etc.) out there, it's going to be hard to find sweet spot without building a feedback mechanism in this code. |
Just FYI ill rebase/merge/squash many of this commits and put proper comments but im still working trough it and i needed to push so i can work on the different locations, forgot to just do it to another branch. |
2608e12
to
d0faeb8
Compare
Did some rework and cleanup. When you have time please give this a look. |
As a note, more than 6 shells seem to be throttled by the CPU, as the amount of connections/logins ramps that up. |
I think there is also something missing here, Invoke-Command from powershell is able to send much larger files. EG: i found that we could be directly using powershell trough wsman instead of calling it on a cmd shell, by calling to this other URI on the winrm library:
There is also this Maybe we can re use some of that as well. Honestly im surprised how hard is to find good info on this compared to other MS products. @masterzen i could use your input here as well. |
re: "Invoke-Command": I assume you're talking about running |
Im not saying to call the Invoke-Command directly, im saying lets reflect the dotNet library and copy the general idea of how it works. |
@dylanmei any thoughts about merging this as is and if i ever get progress on reflecting the .net part ill do a new PR? |
… doesnt break the rest of the systems.
5b34f14
to
7c875e5
Compare
This is what i wanted from refelecting the System.Management.Automation.dll thanks to @StefanScherer, altough this will need to be implemented on the winrm project ( @masterzen ) http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-PSRP%5D.pdf |
@pecigonzalo I'm just connecting the dots 😀 |
@pecigonzalo looks very interesting. I didn't read the full paper, but it looks like a project in itself. I don't think I'll have the time and energy to implement this new protocol :( but as usual I'm willing to accept PRs :) |
When we were first looking at transferring files for Test-Kitchen windows compatibility, we took a similar approach of paralleling the uploads via multiple shells. This does provide some gains in perf, but we found that compressing the entire payload into a single compressed file and transferring that over a single shell was significantly faster given a variety of varying payload compositions. This is the strategy currently used in winrm-fs. You could get very clever and certainly optimize by adding parallelization on top of that and possibly implementing a torrent-like pattern, but in the end you are always going to be crippled by the 8k command line limit and a limit of shells you can open. In line with the findings of @pecigonzalo I too discovered the PSRP protocol eliminated this 8k limit by looking at wireshark traces of remote I finally got around to investigating that further last week and came up with a very rough but working prototype here. There is a considerable amount of work left to "productionize" that. Honestly its an ugly protocol. If you hated winrm(I did) you might like it after working with PSRP. Rather than plain text, payloads are in binary format and the powershell itself has to be serialized into CliXML, embedded into a binary blob and then that is base64 encoded into the wsman SOAP envelope. Good times. However as I explain here, I think a "partial" implementation can provide alot of benefit. I have played with sending large payloads over that protocol. 100k worked great in one round trip but I think at some point you do have to fragment the packets. 200k hung but I have not spent time investigating further. The first step is going to be working it into basic powershell commands in the winrm gem and then optimizing it specifically for file uploading in winrm-fs. Jut thought I'd share that experience and perhaps we can all learn from each others efforts in the this process. Maybe we'll all meet one day in a winrm/psrp support group for those who cant stop adding XML namespaces to their SOAP messages. |
Is there any plans for further work on this? We have a lot of cookbooks and the WinRM uploads are really slow that it hinders development, would be happy to contribute. |
I took a quick look at how winrmcp is writing files into the filesystem, and it looks like for every chunk that gets transffered, it's executing this command:
Maybe this should use It'll probably be more effective to look at improving the chunk transfer before making the code more complex by parallellizing it. It looks like (edited to add last paragraph mentioning |
Is this ever going to be merged? |
Another year gone by |
one more year |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
have any of you guys tried my PR? when I dev'd it, it worked significantly faster for me. try it out, even...heh. |
@arizvisa i did not try it, solved it by using the cd feature of the cloud im using. until its merged, i cant use it |
welp, it's worth a compile because it optimizes the innermost loop of the copy which is using i/o redirection. this involves repeatedly doing: open file, seek to end of file, write data, close file. this is being done on top of powershell's already-existent cost of evaluation and base64 decoding. by parallelizing it, you multiply all of those costs by the number of processes that you're parallelizing it with, which works..sorta. but as every one of these calls can block your i/o, and my PR fixes that by opening the file once, keeping the handle open, and then just repeatedly appending to the file, closing it when it's complete, so that powershell isn't repeatedly evaluating script and converting it for every single line of input. this divides the cost to just one decode and one i/o call. |
👋🏼 Is there intent to merge this? If there is, ill try and resolve conflicts so we can merge. |
There us no support for tis in the past 8 years. No it isn’t getting merged, at best it gets sunsetted so plugin makes adopt a new method of uploading files.
That being said, there is no need for all of this complexity. Tar your files into one upload and this will work.
|
Im trying to get a working parallelised upload mechanism to get better upload speeds.
You get about 5Mbps per worker.
This will be exposed as an parameter like max chunks, allowing to set according to the destination but 4/10 workers is a safe config and maybe 4 should be the default.
This is still work in progress im putting the PR here to get visibility over the work and maybe some help.
Todo:
This should be easy by appending the chunk number to the end of the file name chunk that we write on the destination.
It would be even easier if we change this code to be more OO instead of plain functions.