Disclaimer: won't go into details about different ways to chunk and move through datasets. I'll rather stick to what could you do with MongoDB. For other DB engines, you have to figure out a way to do the same with a different set of features.
How would you typically go about scenarios that may result in a huge entity selection from a DB?
It depends on the DB engine and the available features. Given you are working with MongoDB, you might find cursors and cursor.batchSize to be more interesting than pagination (limit().skip()
) because it implies less overhead (handling the pointer) and can reduce the network round trips significantly.
const query = {...};
const projection = {...};
const cursor = db.users.find(query, projection).batchSize(B);
for (let user = await cursor.next(); user != null; user = await cursor.next()) {
... //do something
}
I'm just afraid that with my current implementation, I'll run out of memory by simply trying to load the result set into memory.
Then, you have to set limits. How much RAM is acceptable depends on the context, you will have to figure it out.
Once you have a number, tune the service by testing different configurations. For example
- Set
projection
to fetch the minimum information required
- Estimate the size
S
(in bytes
) of 1 record based on the previous projection
- Set a
batchSize
(B
) for which product with S
is lesser than L
(RAM max size in bytes). But don't go all in with L
, the service does more things and you want it to handle some concurrency, so make B
to be proportional to L
(1/2, 1/3, 1/4, ...)
- Perform load tests1
- Get metrics
- Repeat steps [3-5]
- Compare
This is for a single instance of the service!
Given you are deploying on K8S, you could make B
to be close to L
(say 90%) and bound Kubernetes horizontal autoscale to memory. The new POD is likely to handle all the incoming requests while the old one is processing notifications at full capacity.
1: Try setting up a fake SMTP server so you can test the load and the behaviour of the service under different conditions. For example, when the SMTP server is not accessible