-
Notifications
You must be signed in to change notification settings - Fork 4k
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
[aws-lambda-nodejs] a single lambda creation takes 30s every time #9120
Comments
Copy @jogold |
@jogold Just updated the repository (https://github.com/vvo/aws-lambda-nodejs-performance), same results, it always takes at least 20s on successive launches of Is there a way to see the output of the docker build to see what's going on? I am not the author of this wonderful package (aws-lambda-nodejs) but it really seems like maybe the yarn/npm cache is not kept in between docker builds maybe? Thanks! |
Had a discussion with @vvo, the issue seems to be linked to Docker performance issues on his machine. Still investigating at this stage. |
Quick tl;dr; on the status of this issue: it's a macos issue. macos filesystem performance through docker containers has been "bad" for some time already (docker/for-mac#1592), but a lot of progress was made. The latest update is coming on the docker for mac edge version https://docs.docker.com/docker-for-mac/edge-release-notes/ where by default they use a new syncing mechanism called "mutagen" (https://mutagen.io/) which makes things faster. Still, on a real-size Node.js project (~ 600MB of node_modules resulting in A LOT of files), mounting the filesystem to docker takes 20s with mutagen (100s without mutagen). The only issue right now is that for mutagen to work well, for now, you have to "flush" data to the host (otherwise asset output is empty when we check it). See docker/for-mac#1592 (comment). Let's wait for the Docker team to reply, but macos filesystem under docker is heading to the right direction. Alternatively, a community-supported nodejs-lambda that would directly use Parcel instead of using Parcel inside docker would make it way way faster, as discussed with @jogold. But I understand this is not the direction the cdk team has headed towards, as @jogold explained to me and that's fine! Thanks all :) |
@eladb Docker performance is really bad on macOS and especially for the what do you suggest here? |
Didn't we configure the volume mapping to use some sort of special mac sauce? |
The volume mount uses |
What I would like to understand is where all the time is "lost": when mounting the volumes? when Parcel runs? when content is written to |
As you know, I did a lot of testing on this, results: On docker stable version: both actions are extremely slow. Mounting is slow (node_modules, lots of files) and parcel is slow (lots of I/O). On my current project, On docker edge/beta version: only the mounting is slow (still 5x faster than stable), afterwards parcel is as fast as native/without docker. On docker edge, :delegated currently uses mutagen by default (may or may not be the end of the story once it reaches docker stable, it might be a different flag)
Docker edge makes the mounting "faster". But as for my testing goes, 20s to mount a real world Node.js project will never be acceptable... By real world I mean my project, approx 600MB node_modules, which is not even big compared to more "enterprise" projects I have seen. We can wait for docker to be faster (but it has been "slow" on macOS filesystems mounting for 3 years already) OR we can make it so it does not use docker on mac. I understand this is not an area you want to go but unfortunately, the road you took will, for now, lead to bad performance on mac for anyone trying to build and deploy Node.js lambdas on AWS using this tool. This will impact A LOT of people. Data I found is from the 2018 Node.js developer survey: MacOS is leading the Node.js developer environment with 41% of users (Windows at 24%), https://nodejs.org/en/user-survey-report/#Primary-OS-Distro. This means that for most people, the experience is not good for now. And those are the people that will try cdk and abandon it if they have the choice. For comparison, I tried https://github.com/pulumi/pulumi and it was instant almost for every command, I still want to use CDK because I do not want/need multi-cloud. And pulumi has some weird defaults as for file organization and how it builds lambdas. Other areas to test:
We tried, I tried, results are worse. Other tests done:
|
Naive question: does the node_modules have to be mounted into the docker container? Could we do the package install inside of the container instead? |
The node modules are bundled so Parcel needs to be able to find them in the container. But we also mount at the project root to be sure to include everything that is referenced in the Lambda code (it could be a util in another package in a monorepo config for example). |
For people having performance issues, could you report timings for
|
(Note: edited July 28th 2020 since I moved from rollup to webpack) Hey there, I finally gave a try at creating an alternative aws-lambda-nodejs. It's here: https://github.com/vvo/aws-lambda-nodejs-webpack. Now Features:
As said in the README:
I hope this will help people having performance issues on macOS or if they're just looking for an alternative lambda builder. I yet have to test it in more details in production, but as of now it just works for simple use cases. And we can always add more (I added a roadmap). Let me know what you think! |
So I tested it with the monorepo and the latest Docker4Mac Edge version. The first run took 4 minutes and then failed with no output as the sync was not done in time. Subsequent runs then took about 20 seconds and succeeded. |
I assume this is because the Dockerfile changed in 1.54.0 and the image had to be rebuilt? Doesn't explain the failure at the end though.
This is still a lot... I'm around 7 seconds on average. If you have a minute (or more 😄), could you try with the other repo where a A temporary solution for macOS users could be to use the |
For the other repo the first run was about 3 minutes and subsequent runs about 40 - 50 seconds. The first-run delay seems to be the sync that Docker does for the folder. It copies the whole folder to the hyperkit vm. The asset-output error did not happen this time. It seems related to what @vvo described earlier. |
First the requested info... This one is the project I'm working on right now: And here's one of my sample projects: https://github.com/elthrasher/cdk-step-functions-example A minute is a long time to wait - especially since I must synth to run unit tests. The numbers above are after running several times, so Docker layers should be cached as well as possible.
I'm at the point where I either have to do a two-step build (build with webpack, then use lambda.Function) or come up with my own construct, but I thought I'd see where you guys were. I can contribute here or go my own way (or maybe there's some sorcery with Thanks for listening :) |
@jogold feels like we may need to support bundling outside of docker in certain environments. Let's kick off a GitHub issue to discuss. Perhaps the direction should be to check it the runtime environment has the required dependencies (e.g parcel in the right version) and only if it doesn't, fall back to docker. This way we can get the docker portability without compromising in environments that support local bundling. Curious how much of this we can/should do in the bundling layer itself and how much is lambda specific. |
@elthrasher, side note, if you want to try a non-docker lambda builder, have a look at the one I created after having performance issues with the default one, see here: https://github.com/vvo/aws-lambda-nodejs-rollup |
@vvo Thanks, I saw that, but I'm using TypeScript. Would be glad to give it a try and give you feedback after you introduce support for TypeScript. |
@elthrasher Just moved from rollup to webpack (rollup could not handle well some npm modules bundling) and added TypeScript + Babel preset-env support. Give it a try and let me know if this works for you: https://github.com/vvo/aws-lambda-nodejs-webpack |
Small status update here: we are going to offer a way out of Docker. I expect this to be available before the end of August. |
tl;dr;
Node.js lambda are slow to build because CDK uses docker and mounting a complete project inside docker is super slow on macos.
There's work being done on Docker side, but it will probably always be very slow for now.
There's work being done on CDK to allow using a local parcel instead of inside docker, see
#9632.
For an alternative solution, I created https://github.com/vvo/aws-lambda-nodejs-webpack which uses webpack locally and is a lot faster
Hi there, when using aws-lambda-nodejs, every cdk synth will take up to 50s, even for a very simple setup. I understand aws-lambda-nodejs uses docker + parcel but even that, with the right cache, performance should not be an issue on successive runs because of Docker / parcel cache. So I guess something is weird here.
As discussed over email with you @jogold, I am creating a new issue that you can reproduce on your side.
Reproduction Steps
I created a repository: https://github.com/vvo/aws-lambda-nodejs-performance
The stack code is:
Reproduction:
Here it's 27 seconds, but I have seen it go up to 50s.
Error Log
No error message
Environment
Other
I'd like to debug further and understand why, maybe, the cache is not used fully but not sure how to do that.
This is 🐛 Bug Report
The text was updated successfully, but these errors were encountered: