1 // Copyright (c) 2015, Facebook, Inc. All rights reserved. 2 // This source code is licensed under both the GPLv2 (found in the 3 // COPYING file in the root directory) and Apache 2.0 License 4 // (found in the LICENSE.Apache file in the root directory). 5 6 package org.rocksdb; 7 8 /** 9 * RateLimiter, which is used to control write rate of flush and 10 * compaction. 11 * 12 * @since 3.10.0 13 */ 14 public class RateLimiter extends RocksObject { 15 public static final long DEFAULT_REFILL_PERIOD_MICROS = 100 * 1000; 16 public static final int DEFAULT_FAIRNESS = 10; 17 public static final RateLimiterMode DEFAULT_MODE = 18 RateLimiterMode.WRITES_ONLY; 19 public static final boolean DEFAULT_AUTOTUNE = false; 20 21 /** 22 * RateLimiter constructor 23 * 24 * @param rateBytesPerSecond this is the only parameter you want to set 25 * most of the time. It controls the total write rate of compaction 26 * and flush in bytes per second. Currently, RocksDB does not enforce 27 * rate limit for anything other than flush and compaction, e.g. write to 28 * WAL. 29 */ RateLimiter(final long rateBytesPerSecond)30 public RateLimiter(final long rateBytesPerSecond) { 31 this(rateBytesPerSecond, DEFAULT_REFILL_PERIOD_MICROS, DEFAULT_FAIRNESS, 32 DEFAULT_MODE, DEFAULT_AUTOTUNE); 33 } 34 35 /** 36 * RateLimiter constructor 37 * 38 * @param rateBytesPerSecond this is the only parameter you want to set 39 * most of the time. It controls the total write rate of compaction 40 * and flush in bytes per second. Currently, RocksDB does not enforce 41 * rate limit for anything other than flush and compaction, e.g. write to 42 * WAL. 43 * @param refillPeriodMicros this controls how often tokens are refilled. For 44 * example, 45 * when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to 46 * 100ms, then 1MB is refilled every 100ms internally. Larger value can 47 * lead to burstier writes while smaller value introduces more CPU 48 * overhead. The default of 100,000ms should work for most cases. 49 */ RateLimiter(final long rateBytesPerSecond, final long refillPeriodMicros)50 public RateLimiter(final long rateBytesPerSecond, 51 final long refillPeriodMicros) { 52 this(rateBytesPerSecond, refillPeriodMicros, DEFAULT_FAIRNESS, DEFAULT_MODE, 53 DEFAULT_AUTOTUNE); 54 } 55 56 /** 57 * RateLimiter constructor 58 * 59 * @param rateBytesPerSecond this is the only parameter you want to set 60 * most of the time. It controls the total write rate of compaction 61 * and flush in bytes per second. Currently, RocksDB does not enforce 62 * rate limit for anything other than flush and compaction, e.g. write to 63 * WAL. 64 * @param refillPeriodMicros this controls how often tokens are refilled. For 65 * example, 66 * when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to 67 * 100ms, then 1MB is refilled every 100ms internally. Larger value can 68 * lead to burstier writes while smaller value introduces more CPU 69 * overhead. The default of 100,000ms should work for most cases. 70 * @param fairness RateLimiter accepts high-pri requests and low-pri requests. 71 * A low-pri request is usually blocked in favor of hi-pri request. 72 * Currently, RocksDB assigns low-pri to request from compaction and 73 * high-pri to request from flush. Low-pri requests can get blocked if 74 * flush requests come in continuously. This fairness parameter grants 75 * low-pri requests permission by fairness chance even though high-pri 76 * requests exist to avoid starvation. 77 * You should be good by leaving it at default 10. 78 */ RateLimiter(final long rateBytesPerSecond, final long refillPeriodMicros, final int fairness)79 public RateLimiter(final long rateBytesPerSecond, 80 final long refillPeriodMicros, final int fairness) { 81 this(rateBytesPerSecond, refillPeriodMicros, fairness, DEFAULT_MODE, 82 DEFAULT_AUTOTUNE); 83 } 84 85 /** 86 * RateLimiter constructor 87 * 88 * @param rateBytesPerSecond this is the only parameter you want to set 89 * most of the time. It controls the total write rate of compaction 90 * and flush in bytes per second. Currently, RocksDB does not enforce 91 * rate limit for anything other than flush and compaction, e.g. write to 92 * WAL. 93 * @param refillPeriodMicros this controls how often tokens are refilled. For 94 * example, 95 * when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to 96 * 100ms, then 1MB is refilled every 100ms internally. Larger value can 97 * lead to burstier writes while smaller value introduces more CPU 98 * overhead. The default of 100,000ms should work for most cases. 99 * @param fairness RateLimiter accepts high-pri requests and low-pri requests. 100 * A low-pri request is usually blocked in favor of hi-pri request. 101 * Currently, RocksDB assigns low-pri to request from compaction and 102 * high-pri to request from flush. Low-pri requests can get blocked if 103 * flush requests come in continuously. This fairness parameter grants 104 * low-pri requests permission by fairness chance even though high-pri 105 * requests exist to avoid starvation. 106 * You should be good by leaving it at default 10. 107 * @param rateLimiterMode indicates which types of operations count against 108 * the limit. 109 */ RateLimiter(final long rateBytesPerSecond, final long refillPeriodMicros, final int fairness, final RateLimiterMode rateLimiterMode)110 public RateLimiter(final long rateBytesPerSecond, 111 final long refillPeriodMicros, final int fairness, 112 final RateLimiterMode rateLimiterMode) { 113 this(rateBytesPerSecond, refillPeriodMicros, fairness, rateLimiterMode, 114 DEFAULT_AUTOTUNE); 115 } 116 117 /** 118 * RateLimiter constructor 119 * 120 * @param rateBytesPerSecond this is the only parameter you want to set 121 * most of the time. It controls the total write rate of compaction 122 * and flush in bytes per second. Currently, RocksDB does not enforce 123 * rate limit for anything other than flush and compaction, e.g. write to 124 * WAL. 125 * @param refillPeriodMicros this controls how often tokens are refilled. For 126 * example, 127 * when rate_bytes_per_sec is set to 10MB/s and refill_period_us is set to 128 * 100ms, then 1MB is refilled every 100ms internally. Larger value can 129 * lead to burstier writes while smaller value introduces more CPU 130 * overhead. The default of 100,000ms should work for most cases. 131 * @param fairness RateLimiter accepts high-pri requests and low-pri requests. 132 * A low-pri request is usually blocked in favor of hi-pri request. 133 * Currently, RocksDB assigns low-pri to request from compaction and 134 * high-pri to request from flush. Low-pri requests can get blocked if 135 * flush requests come in continuously. This fairness parameter grants 136 * low-pri requests permission by fairness chance even though high-pri 137 * requests exist to avoid starvation. 138 * You should be good by leaving it at default 10. 139 * @param rateLimiterMode indicates which types of operations count against 140 * the limit. 141 * @param autoTune Enables dynamic adjustment of rate limit within the range 142 * {@code [rate_bytes_per_sec / 20, rate_bytes_per_sec]}, according to 143 * the recent demand for background I/O. 144 */ RateLimiter(final long rateBytesPerSecond, final long refillPeriodMicros, final int fairness, final RateLimiterMode rateLimiterMode, final boolean autoTune)145 public RateLimiter(final long rateBytesPerSecond, 146 final long refillPeriodMicros, final int fairness, 147 final RateLimiterMode rateLimiterMode, final boolean autoTune) { 148 super(newRateLimiterHandle(rateBytesPerSecond, 149 refillPeriodMicros, fairness, rateLimiterMode.getValue(), autoTune)); 150 } 151 152 /** 153 * <p>This API allows user to dynamically change rate limiter's bytes per second. 154 * REQUIRED: bytes_per_second > 0</p> 155 * 156 * @param bytesPerSecond bytes per second. 157 */ setBytesPerSecond(final long bytesPerSecond)158 public void setBytesPerSecond(final long bytesPerSecond) { 159 assert(isOwningHandle()); 160 setBytesPerSecond(nativeHandle_, bytesPerSecond); 161 } 162 163 /** 164 * Returns the bytes per second. 165 * 166 * @return bytes per second. 167 */ getBytesPerSecond()168 public long getBytesPerSecond() { 169 assert(isOwningHandle()); 170 return getBytesPerSecond(nativeHandle_); 171 } 172 173 /** 174 * <p>Request for token to write bytes. If this request can not be satisfied, 175 * the call is blocked. Caller is responsible to make sure 176 * {@code bytes < GetSingleBurstBytes()}.</p> 177 * 178 * @param bytes requested bytes. 179 */ request(final long bytes)180 public void request(final long bytes) { 181 assert(isOwningHandle()); 182 request(nativeHandle_, bytes); 183 } 184 185 /** 186 * <p>Max bytes can be granted in a single burst.</p> 187 * 188 * @return max bytes can be granted in a single burst. 189 */ getSingleBurstBytes()190 public long getSingleBurstBytes() { 191 assert(isOwningHandle()); 192 return getSingleBurstBytes(nativeHandle_); 193 } 194 195 /** 196 * <p>Total bytes that go through rate limiter.</p> 197 * 198 * @return total bytes that go through rate limiter. 199 */ getTotalBytesThrough()200 public long getTotalBytesThrough() { 201 assert(isOwningHandle()); 202 return getTotalBytesThrough(nativeHandle_); 203 } 204 205 /** 206 * <p>Total # of requests that go through rate limiter.</p> 207 * 208 * @return total # of requests that go through rate limiter. 209 */ getTotalRequests()210 public long getTotalRequests() { 211 assert(isOwningHandle()); 212 return getTotalRequests(nativeHandle_); 213 } 214 newRateLimiterHandle(final long rateBytesPerSecond, final long refillPeriodMicros, final int fairness, final byte rateLimiterMode, final boolean autoTune)215 private static native long newRateLimiterHandle(final long rateBytesPerSecond, 216 final long refillPeriodMicros, final int fairness, 217 final byte rateLimiterMode, final boolean autoTune); disposeInternal(final long handle)218 @Override protected final native void disposeInternal(final long handle); 219 setBytesPerSecond(final long handle, final long bytesPerSecond)220 private native void setBytesPerSecond(final long handle, 221 final long bytesPerSecond); getBytesPerSecond(final long handle)222 private native long getBytesPerSecond(final long handle); request(final long handle, final long bytes)223 private native void request(final long handle, final long bytes); getSingleBurstBytes(final long handle)224 private native long getSingleBurstBytes(final long handle); getTotalBytesThrough(final long handle)225 private native long getTotalBytesThrough(final long handle); getTotalRequests(final long handle)226 private native long getTotalRequests(final long handle); 227 } 228