3 ms·
For me, the issue with GC never has been about how long it runs for. It's been about the unpredictability of when it can kick in. Granted a malloc can be unpred
by aloknnikhil 7y ago
For me, the issue with GC never has been about how long it runs for. It's been about the unpredictability of when it can kick in. Granted a malloc can be unpredictable too (albeit very very rarely), but at least you know a malloc is the only time your process could stall waiting for memory.
Databases make extensive use of scratch space for undo logs and redo logs and especially while processing JOINs. It's tremendous pressure on the GC that results in frequent performance dips. With C/C++/Rust, you'd pipeline the query stages to malloc/free that space outside the hot path to minimize query response times.
- irfansharif 7y agoI'll repeat what was mentioned elsewhere. The GC pauses in Go are in the order of microseconds. We've done a ton of work keeping our memory usage under tight bounds and keeping a close eye on exactly how the go GC processes interplay with query execution threads (what processors are consumed, GC pressure buildup, where/when the stalls are introduced, etc.) Consistently we've found that given you're invariably dealing with network latencies (it's a distributed db after all), the microsecond GC pauses are almost entirely dwarfed to matter (I'm not excluding p99s here).
- tom_mellior 7y ago> With C/C++/Rust, you'd pipeline the query stages to malloc/free that space outside the hot path to minimize query response times. I don't understand why you seem to assert that GC'd languages would force you to put allocations on the hot path. Surely in Go you can also allocate that space elsewhere?
- aloknnikhil 7y agoI was primarily referring to the free on the hot path. GCd languages don't force any allocation paradigms. But due to the unpredictability of the GC, you could be in the middle of a query execution and the GC can kick in. With C/C++/Rust, you're free to maintain your own a allocator that could have a buffer pool of pages that can be recycled and freed when the database is idle. Under a large load, the micro spikes in latency can have an avalanche effect that leads to a build up of queries. I've dealt with customer cases where the MySQL/InnoDB lock manager caused connection spikes due to a brief (< 10 us) global write lock taken while the system was under load.
- tom_mellior 7y ago> But due to the unpredictability of the GC, you could be in the middle of a query execution and the GC can kick in. Yes, that is a possibility. Typically there are two ways to deal with this in a GC'd language: (a) You know that GC is only triggered by certain operations that might allocate, and you avoid those operations in your critical hot section, or (b) you know how to disable the GC temporarily, while you are in that critical hot section. For Go the latter is apparently done by calling this function: https://golang.org/pkg/runtime/debug/#SetGCPercent https://golang.org/pkg/runtime/debug/#SetGCPercent I'm not a Go developer myself, but I imagine people developing such low-latency software in Go know about this.