04-26-2016, 05:54 PM
(This post was last modified: 04-26-2016, 06:30 PM by LogicParrot.)
Currently, our chunk management is bad. See #3142 for reference.
I have started fiddling around with various ways to manage this better (see #3151). I think we should discuss the optimal way to manage this. I explain the problem below. I also list the various proposals. The list may grow as we propose more ideas. Please discuss the various approaches. I need opinions on this.
Brief Background and Terminology
Minecraft is divided into chunks, they are saved in files. These chunks can either be loaded or unloaded. Loaded chunks reside RAM. When a player leaves a chunk, it should be unloaded at some point to free that RAM.
Dirty / clean chunks - Some chunks are dirty, meaning they changed since last saved to disk. These chunks must be saved to disk before being unloaded. Clean chunks have not changed since last saved and can simply be unloaded straight away.
Used / Unused chunks - Unused chunks are not being used by the game and have no players nearby, Assuming they are clean, we can unload them. Used chunks are being used by the game and must never be unloaded, whether dirty or clean. However, they should be periodically saved if dirty, to avoid data loss if the game crashes.
The problem
When a chunk becomes unused, we should unload it at some point. If we unload it too fast and a player gets back to it, we have wasted resources; the chunk must be re-loaded from disk into RAM. On the other hand, if we keep chunks too long, then server consumes too much RAM.
Solutions
The current approach (master branch)
Currently, Cuberite has a 10 second unload cycle and a 300 second save cycle.
The "Stable Ram" approach
This is the current approach in #3151.
Unload ASAP
Save and/or unload a chunk as soon as it becomes unused.
Pros:
I have started fiddling around with various ways to manage this better (see #3151). I think we should discuss the optimal way to manage this. I explain the problem below. I also list the various proposals. The list may grow as we propose more ideas. Please discuss the various approaches. I need opinions on this.
Brief Background and Terminology
Minecraft is divided into chunks, they are saved in files. These chunks can either be loaded or unloaded. Loaded chunks reside RAM. When a player leaves a chunk, it should be unloaded at some point to free that RAM.
Dirty / clean chunks - Some chunks are dirty, meaning they changed since last saved to disk. These chunks must be saved to disk before being unloaded. Clean chunks have not changed since last saved and can simply be unloaded straight away.
Used / Unused chunks - Unused chunks are not being used by the game and have no players nearby, Assuming they are clean, we can unload them. Used chunks are being used by the game and must never be unloaded, whether dirty or clean. However, they should be periodically saved if dirty, to avoid data loss if the game crashes.
The problem
When a chunk becomes unused, we should unload it at some point. If we unload it too fast and a player gets back to it, we have wasted resources; the chunk must be re-loaded from disk into RAM. On the other hand, if we keep chunks too long, then server consumes too much RAM.
Solutions
The current approach (master branch)
Currently, Cuberite has a 10 second unload cycle and a 300 second save cycle.
- Save cycle: All dirty chunks are saved, whether unused or used.
- Unload cycle: All unused, clean chunks are unloaded.
- Simple code
- clean chunks are unloaded as soon as they're left. (This may be the way Vanilla does this, too)
- Dirty chunks can persist in RAM for up to 5 minutes, until the save cycle arrives. Because dirty chunks cannot be unloaded before being saved. This can often overwhelm the ram of small devices. On Raspberry Pis, if you fly in a straight line too fast, you can choke the RAM.
The "Stable Ram" approach
This is the current approach in #3151.
- A server has RAM dedicated for chunks, this is configurable in settings.ini
- Unused, clean chunks are unloaded only when that RAM limit is exceeded.
- If the RAM limit is exceeded but there are not enough unused clean chunks to unload, we resort to saving unused dirty chunks and then unloading them.
- Additionally, there is a 300 second save cycle, so that chunks are never dirty for too long.
- Full RAM utilization, chunks are freed only when we have to.
- Never overwhelms the server, the used RAM is static. Except in extreme cases where the amount of *used* chunks exceeds the configured RAM.
- The used RAM is static. This means that even when there are few players online, the server would be consuming the same amount of RAM as always.
- The current chunk save scheme is random - we pick random unused chunks and free them. This can be improved in various ways.
Unload ASAP
Save and/or unload a chunk as soon as it becomes unused.
Pros:
- Minimum RAM utilization, chunks are freed ASAP
- Code already exists. Setting the RAM setting ridiculously low in the above solution does exactly this.
- Minimum RAM utilization and high disk usage. The RAM could have been better used.