cockroachdb / cockroachdb/cockroach

kv/rangefeed: catchup scan iterator request limit starvation

Open
#132,438 5 comments 0 reactions 0 assignees View on GitHub
A-kv-rangefeed branch-master C-bug P-3 T-kv
Dominant language
Go
Stars
32.5k
Forks
4.1k
PR merge metrics
PR metrics pending

Description

**Describe the problem**

To prevent overloading the underlying store and to reduce the impact of rangefeeds on the foreground workload, the number of catchup iterators (pebble iterators used for catchup scans) is limited on a per store basis:

https://github.com/cockroachdb/cockroach/blob/d50ca118e4b08725233e941e4e11a0f6bdc18c30/pkg/kv/kvserver/replica_rangefeed.go#L280-L303

In effect, this is a hard limit on the number of catchup scans that can be in flight. If the limit is exhausted, any new rangefeed registrations starting from a timestamp (nearly all rangefeeds), need to wait for the quota.

This limit has been relatively effective, but the current implementation allows a single client to effectively starve all other rangefeed users.

For a large table, it's possible that a single MuxRangefeed call consumes the entire catchup scan budget. If the consumer of that call is slow, it's possible for new MuxRangefeed requests from other clients to be completely blocked for an indefinite amount of time.

Further note that rangefeed replications started by MuxRangefeed are all writing to the same gRPC stream protected by a mutex and all likely being consumed by the same consumer on the other end of that gPRC connection. This may compound the starvation since any individual catchup scan will take longer to complete as it contends with the other catchup scans sharing that stream.

**Potential Approaches**

- Arbitrarily increase the semaphore limit to make this less likely.
- Limit any one MuxRangefeed call's ability to consume more than some percentage of the total catchup scan semaphore.
- Limit any one logical consumer of rangefeeds (LDR, CHANGEFEED, PCR) ability to consume more than some percentage of the total catchup scan semaphore.
- Replace this simple semaphore with something like a priority queue.
- Remove the destination (kv) side catch-up scan semaphore and rely only on the client side rate limiter.

**Additional Notes**

- There is also a client-side catchupScanQuota that is structured as a rate limit, with the original intention of limiting the creation of new goroutines:

https://github.com/cockroachdb/cockroach/blob/d50ca118e4b08725233e941e4e11a0f6bdc18c30/pkg/kv/kvclient/kvcoord/dist_sender_mux_rangefeed.go#L254-L257

This is backed by a `quotapool.RateLImiter`:

https://github.com/cockroachdb/cockroach/blob/d50ca118e4b08725233e941e4e11a0f6bdc18c30/pkg/kv/kvclient/kvcoord/dist_sender_rangefeed.go#L736-L754

Jira issue: CRDB-43066

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.