2020-11-20 18:24:01
We continue to look at hacks from interesting projects. This time we have a whole subsystem for monitoring memory consumption in TiDB. It works globally for the entire database and for each request separately.
But the authors themselves mention that this control method was taken from Apache Impala.
Here is the component itself in which large allocations are registered when a request is made https://github.com/pingcap/tidb/blob/abc8f1665f2b94d6d030977f0e1f0f970e6538d6/util/memory/tracker.go
Tracker itself is thread-safe and allows you to make branches and child Trackers with a separate memory limit if you need to start several threads to execute a request.
Tracker contains a registry of various actions that must be triggered if the limit was exceeded, and then, throughout the code, such actions are registered in different components that execute the request.
The most commonplace examples are to log something on limit reach and/or panic in a goroutine that has exceeded the limit, but there are smarter strategies, for example:
- merge intermediate query results to disk https://github.com/pingcap/tidb/blob/0c822d13a151d80ddc1906fb18e8262e097f9155/util/chunk/row_container.go
- lower the rate limits of asynchronously running processes https://github.com/pingcap/tidb/blob/611d24911ec1653c456a196bd986ac1b263b3b1f/store/tikv/coprocessor.go#L1354
Cleaning of all sorts of caches also sounds like a viable option, but I didn't find such an example in the codebase.
#hacks
914 viewsedited 15:24