parse-community / parse-server

Parse Server for Node.js / Express
https://parseplatform.org
Apache License 2.0
20.7k stars 4.76k forks source link

Parse Server compatibility with Serverless environment #7938

Open Moumouls opened 2 years ago

Moumouls commented 2 years ago

New Feature / Enhancement Checklist

Current Limitation

I'm currently investigating the usage of Parse Server in a serverless env. The current tested setup is:

Refactors/workarounds:

Errors:

Limitations:

Stats:

Feature / Enhancement Description

The cold start is mainly related to dependency size. To reduce cold start we need to start some code splitting. All adapters should be moved out of parse-server. Developers should be able to only import wanted adapters/servers, like LiveQuery, GraphQL server, PostgresAdapter, etc...

Then some tiny cache optimization could help to make the parse-server start under maybe 1-2sec.

Example Use Case

Fully serverless usage (with mongo serverless) to allow Parse developers to leverage Serverless computing like:

Alternatives / Workarounds

None

3rd Party References

Cloud providers that support scale to zero container instances

https://cloud.google.com/run https://www.scaleway.com/en/serverless-containers/ https://docs.microsoft.com/en-us/azure/container-apps/ https://aws.amazon.com/ecs/

Database provider with serverless (pay as you go) pricing https://www.mongodb.com/cloud/atlas/serverless

parse-github-assistant[bot] commented 2 years ago

Thanks for opening this issue!

mtrezza commented 2 years ago

See https://github.com/parse-community/parse-server/issues/483

Moumouls commented 2 years ago

Note: I'm currently not investigating proprietary serverless environments like AWS Lambda/Cloudflare Workers/Vercel serverless. Since it needs specific adaptations/bundling, it's not easily testable in a local env. From my point of view, it's a less standard approach.

Docker helps to get some execution abstraction.

I'm currently focusing on making a parse-server at least compatible to run in a container on a serverless orchestrator: like GCP Cloud Run, Knative.

I'm also focusing on containers since Knative is now part of CNCF, and could be the next cloud standard (like Kubernetes ) to deploy serverless containers across cloud providers: https://www.forbes.com/sites/janakirammsv/2022/03/06/cncf-accepts-knative-projectwhat-does-it-mean-to-the-cloud-native-ecosystem/?sh=72413dfe174b

mtrezza commented 2 years ago

So is this still a general discussion? In that case it should continue in our community forum. We use GitHub to track concrete issues and feature suggestions.

Moumouls commented 2 years ago

It's not a general discussion, it's an issue, and I will work on a PR to fix the app. listen to the issue. I'll also work on a distinct pr to fix the collation issue for Mongo Serverless.

mtrezza commented 2 years ago

What you are describing seems to be a refactoring of Parse Server that won't be done with a few small PRs. These seems to be several individual issues (adapters, cache, collation), each of which will likely require its own GH issue and discussion. Could you make a roadmap for this with a TODO list to see for which points we need to discuss in more depth?

Moumouls commented 2 years ago

@mtrezza

Roadmap:

Minimum compatibility requirements

  1. Fix errors (developers do not have workarounds):

    • feat: allow to disable collation (case-insensitivity) on User queries/indexes (email/username)
  2. Parse Server listens too early

    • feat: add a new "startCompletePort" option to be handle correctly public requests (from a internet/balancer) once parse server startComplete resolve. We need an additional port since internal parse-server code, developers' code inside before/afterMigration, and startServerComplete could use Parse Node JS SDK that internally uses a serverUrl.

At this point Parse Server (without livequery and Parse Jobs) should be able to run in a containerized serverless env out of the box (for example on Cloud Run GCP)

Performance improvement (road to 1-2 sec cold start)

  1. Code splitting

    • feat: move out adapters of the parse-server package, and allow developers to only install and provide needed adapters, to reduce nodeJS require time currently approximatively 2sec
  2. Init speed up

    • feat: use the hash (SHA1) mechanism on schema and some configs to easily detect changes, I think parse-server could be optimized and can reduce init time.
  3. Dynamic module loading investigation

    • feat: some modules of parse could be required dynamically once needed, for example, an auth provider, should be loaded only if a request uses it. The server should not load/require all the code by default at startup time.

Support feature not "Serverless Friendly" like LiveQuery, Parse Jobs

Moumouls commented 2 years ago

@mtrezza we can split this one into many issues. I think we should also keep this issue open to tracking the work progress.

I'll work on point 1 and 2 may be the next week?

mtrezza commented 2 years ago

Yes, this should be split into smaller PRs as much as possible because large, monolithic PRs are more difficult to manage and take more time to get merged. We can keep this issue open to track the progress; maybe you want to move a compact TODO list of your roadmap to the post at the very top and add checkboxes and PR references to each one so everyone can easily see the status of this.

Moumouls commented 2 years ago

Just for reference, the readiness probe, exposing the server to public traffic needs to be handled by the developer.

Linked comment : https://github.com/parse-community/parse-server/pull/7914#issuecomment-1115902685

The https://github.com/parse-community/parse-server/pull/7914 will allow developers to design graceful start easily using startAsync or serverStartComplete thanks to @dblythy

Moumouls commented 2 years ago

@mtrezza what do you think about adding a section on the docs about some tips for a graceful start in environments like PM2, GCP Could Run, Kubernetes, etc...

mtrezza commented 2 years ago

Sure, please feel free to open a PR.

stewones commented 1 year ago

👀 I'm also interested in serverless hosting, specifically Atlas Serverless... I'm curious to know what the status of this project is.

Moumouls commented 1 year ago

Hi @stewones, I'm running successfully many parse servers with MongoDB Atlas Serverless (6.1). Once correct indexes are added it works like a charm with excellent cost efficiency.

To work with MongoDB serverless some PRs are needed like this one: https://github.com/parse-community/parse-server/pull/8042

The best and easiest option to run parse-server in serverless env is Google Cloud Run using a Docker container.

@mtrezza once needed PR to are merged I can push a repo example (with terraform file example) to deploy Parse Server fully serverless on Google Cloud Run and Mongo Atlas Serverless for developers interested in running parse-server as Serverless.

The repo example could be coupled to a documentation page/blog post maybe

Moumouls commented 1 year ago

it could be a good blog post for Parse V6: "Parse Server goes fully serverless with Mongo Atlas Serverless and Google Cloud Run"

@dblythy do you have some suggestions here ?

dblythy commented 1 year ago

It sounds like a good idea. Mongo Atlas Serverless sounds exciting and I'm keen to see how it compares in price vs my current solution which is AWS EB.

Moumouls commented 1 year ago

I'm keen to see how it compares in price

On MongoDB Serverless it depends a lot of indexes, a poorly indexed query will produce a lot RPU, my current strategy is to "over-index" (creating many indexes on possible queries) since storage is so much cheaper than RPU/WPU.

But I can easily say that once indexes are correctly configured, scaling, performance, and cost of MongoDB Serverless are really impressive.

And Parse Server on Cloud Run with a Google Cloud task that keeps at least 1 server idle, it's also really cost-efficient.

@dblythy

For an app with invariant traffic and 10k of users you can easily run Parse Server on Cloud Run + Mongo Atlas Serverless for like 10$/month (or less) (but it really depends of the app, and optimization, caches etc...). Serverless is not magic, just super efficient when it's correctly used.

matheusfrozzi commented 2 months ago

@Moumouls did you publish the tutorial to run the parse server with google cloud run? Didn't find it anywhere!

Thanks

Moumouls commented 1 month ago

Hi @matheusfrozzi , it's quite easy to run Parse Server in Google Cloud Run, Google Cloud Run is standard and you just need to start your parse server and makes sure that it listen on port 80.

Parse Server have a little bit of cold start, if you want to prevent a cold start you can use common tricks like using a Google Cloud Scheduler to ping each min your Google Cloud Service.

Be aware that on Google Cloud Run by default it's not easy to use Live Query, it needs way more setup.

About the cache, since i've many small parse server instances, i don't care about a centralized cache, the in memory cache ( default of parse server) do the job.

Again a big warning on background tasks in Google Cloud Run when you use the pricing with CPU only active on the request. Parse Cloud Jobs will not work correctly by default.

To run background task correctly on Google Cloud Run ( it's not related to Parse or NodeJS).

You need this kind of flow: