当前位置:Gxlcms > 数据库问题 > RocksDB Rate Limiter源码解析

RocksDB Rate Limiter源码解析

时间:2021-07-01 10:21:17 帮助过:14人阅读

// Create a RateLimiter object, which can be shared among RocksDB instances to control write rate of flush and compaction. 2 // @rate_bytes_per_sec: this is the only parameter you want to set most of the time. It controls the total write rate of compaction and flush in bytes per second. Currently, RocksDB does not enforce rate limit for anything other than flush and compaction, e.g. write to WAL. 3 // @refill_period_us: this controls how often tokens are refilled. For example, when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to 100ms, then 1MB is refilled every 100ms internally. Larger value can lead to burstier writes while smaller value introduces more CPU overhead. The default should work for most cases. 4 // @fairness: RateLimiter accepts high-pri requests and low-pri requests. A low-pri request is usually blocked in favor of hi-pri request. Currently, RocksDB assigns low-pri to request from compaction and high-pri to request from flush. Low-pri requests can get blocked if flush requests come in continuously. This fairness parameter grants low-pri requests permission by 1/fairness chance even though high-pri requests exist to avoid starvation. You should be good by leaving it at default 10. 5 // @mode: Mode indicates which types of operations count against the limit. 6 // @auto_tuned: Enables dynamic adjustment of rate limit within the range `[rate_bytes_per_sec / 20, rate_bytes_per_sec]`, according to the recent demand for background I/O. 7 extern RateLimiter* NewGenericRateLimiter( 8 int64_t rate_bytes_per_sec, int64_t refill_period_us = 100 * 1000, 9 int32_t fairness = 10, 10 RateLimiter::Mode mode = RateLimiter::Mode::kWritesOnly, 11 bool auto_tuned = false); 12 13 } // namespace rocksdb

这里有个bool auto_tuned,这是RocksDB中带的一个Auto tune Rate Limiter的模块。因为这个rate_bytes_per_sec(写入速度的上限)是很难手动调节的,太大了没效果,太小了又会导致大量写操作无法继续。所以RocksDB提供了这个模块来自动调节。当开启这个模块时,参数rate_bytes_per_sec的含义就变成了定义写入速度上限的上限(In this case rate_bytes_per_sec will indicate the upper-bound of the window within which a rate limit will be picked dynamically.)。之后这个auto tuner会周期性监测I/O写入量,并相应增大/减小写入量上限的值(重新设置rate_bytes_per_sec_和refill_bytes_per_period_)。这里的benchmark显示Auto-tune Rate Limiter可以有效减少write突然增加的程度。

 


 

Rate Limiter的用法

可以通过NewGenericRateLimiter类来新建一个Rate Limiter。可以对每个RocksDB实例单独搞一个,也可以让所有实例共享一个来control the aggregated write rate of flush and compaction。

1 RateLimiter* rate_limiter = NewGenericRateLimiter(
2     rate_bytes_per_sec /* int64_t */, 
3     refill_period_us /* int64_t */,
4     fairness /* int32_t */);

这里面三个参数的含义上面介绍过啦。

Although tokens are refilled with a certain interval set by refill_period_us, the maximum bytes that can be granted in a single burst have to be bounded since we are not happy to see that tokens are accumulated for a long time and then consumed by a single burst request which definitely does not agree with our intention. GetSingleBurstBytes() returns this upper bound of tokens.

使用时,在每次写请求之前,都要申请token。如果当前请求无法满足(也就是被限速了),请求就会被阻塞,直到token被填充到足够完成请求。

1 // block if tokens are not enough
2 rate_limiter->Request(1024 /* bytes */, rocksdb::Env::IO_HIGH); 
3 
4 // perform a write operation
5 Status s = db->Flush();

在运行过程中,也可以通过 SetBytesPerSecond(int64_t bytes_per_second) 动态修改Rate Limiter的流量。

 

RocksDB Rate Limiter源码解析

标签:env   time   this   slides   miss   upper   window   修改   data   

人气教程排行