Reputation: 543
Background:
We're trying to migrate our API Gateway from REST to gRPC. The API Gateway will consume by Backend Team with REST, and the communication from API Gateway to microservice will be using gRPC. Our API Gateway build with Tornado Python Framework, Gunicorn, and using tornado.curl_httpclient.CurlAsyncHTTPClient
to enable Async / Future for each endpoint. Each endpoint will call to Microservices using Unary RPC and the gRPC stub will return Future.
So before fully migrate to gRPC, we're trying to compare gRPC vs REST performance. Here is the detail u might need to know:
/0
, /1
, and /2
with a single string payload. The payload size are 100KB, 1MB, and 4MB. These message already created when the instance just started, so the endpoint only need to retrieve it.The Conclusion is The higher Concurrency and payload size, the slower gRPC become and eventually slower than REST.
Question:
Here's a few way that i have tried:
GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS
and GRPC_ARG_KEEPALIVE_TIMEOUT_MS
options on the stub and server config. There's no changes in performance.10000
. Result: No Changes in performance.1
. Result: No Changes in Performance.The way I haven't tried:
Any Help is appareciated. Thank you.
Upvotes: 5
Views: 2689
Reputation: 1620
Is gRPC incapable of handling large payload size and large concurrency by using Unary Call compare to REST ?
Yes, the gRPC Python bindings are used in production to serve requests as large as several gigabytes at speed.
Are there anyway to enable gRPC to become faster than REST ?
I believe your issue is likely this:
Each endpoint will call to Microservices using Unary RPC and the gRPC stub will return Future.
Each time you use the future API in the Python bindings, a new thread is created to service that request. As you know, Python has a global interpreter lock, so while a process may have many threads, only one of them may access Python objects at any one time. Further, the more threads contending on the GIL, the more slowdowns will happen due to synchronization.
To avoid this, you can either use only the synchronous parts of the gRPC Python API, or you can switch over to the AsyncIO bindings, which were designed to solve exactly this problem.
Upvotes: 0