Running concurrent backup restores results in OOM killing
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Cinder |
Fix Released
|
Undecided
|
Gorka Eguileor |
Bug Description
When restoring many backups, for example 41, the backup service uses a lot of memory and end up getting killed becase we run out of memory.
The amount of memory required when the volumes are RBD, and the backups are not, is even worse.
Here's the explanation of the peak memory we will need for 1 restore:
- First we use as much as the size of the chunk we have stored, which in our case is compressed, so if we assume a 50% compression ratio, it would be 50% of the original chunk which can be 1999994880 bytes.
So here we use 0.93GB when the ChunkedBackupDriver reads the object [1]
with self._get_
- Then when we decompress the data [2] we will need an additional 1,86GB which is the full original chunk size:
- Then when the ChunkedBackupDriver writes the data [3]:
What happens behind that call, because this is an RBD volume, is that we use the osb-brick connector which uses librbd Image object to do the writing [4]:
def write(self, data):
The write method in librbd calls the rbd_write2 method [5]
ret = rbd_write2(
And the method will call the create_write_raw method with nullptr as the aio_completion parameter [6]:
And because of this the create_write_raw method will copy the data in a different buffer [7]:
if (ictx->
// must copy the buffer if writeback/
// non-AIO)
return buffer::copy(buf, len);
And we end up using another 1.86GB of RAM
So we end up needing 0.93GB + 1.86GB + 1.86GB for a single restore operation. If we now do 41 simultaneous operations, we will end up using 190.65GB, hence the OOM kill.
I see 2 improvements that can be done in the Cinder code:
- Help Python free memory faster by setting to None the body variable as soon as we decompress it, and setting to None the decompressed variable as soon as we've written it.
- Introduce a max concurrent backup & restore operations feature that will queue operations that exceed them.
To mitigate the problem, deployments can do any of:
- Reduce the number of concurrent restore operations
- Disable compression
- Reduce the size of the chunks with the backup_file_size variable
[1]: https:/
[2]: https:/
[3]: https:/
[4]: https:/
[5]: https:/
[6]: https:/
[7]: https:/
Changed in cinder: | |
assignee: | Gorka Eguileor (gorka) → Rajat Dhasmana (whoami-rajat) |
Changed in cinder: | |
assignee: | Rajat Dhasmana (whoami-rajat) → Gorka Eguileor (gorka) |
Related fix proposed to branch: master /review. opendev. org/710250
Review: https:/