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    */
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    */
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    */
79   public RateLimiter(final long rateBytesPerSecond,
80       final long refillPeriodMicros, final int fairness) {
81     this(rateBytesPerSecond, refillPeriodMicros, fairness, DEFAULT_MODE,
getType()82         DEFAULT_AUTOTUNE);
83   }
84 
85   /**
86    * RateLimiter constructor
RewriteDescriptor(Type T)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    */
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
RewriteSymbolPass()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    */
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 &gt; 0</p>
155    *
156    * @param bytesPerSecond bytes per second.
157    */
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    */
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 &lt; GetSingleBurstBytes()}.</p>
177    *
178    * @param bytes requested bytes.
179    */
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    */
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    */
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    */
210   public long getTotalRequests() {
211     assert(isOwningHandle());
212     return getTotalRequests(nativeHandle_);
213   }
214 
215   private static native long newRateLimiterHandle(final long rateBytesPerSecond,
216       final long refillPeriodMicros, final int fairness,
217       final byte rateLimiterMode, final boolean autoTune);
218   @Override protected final native void disposeInternal(final long handle);
219 
220   private native void setBytesPerSecond(final long handle,
221       final long bytesPerSecond);
222   private native long getBytesPerSecond(final long handle);
223   private native void request(final long handle, final long bytes);
224   private native long getSingleBurstBytes(final long handle);
225   private native long getTotalBytesThrough(final long handle);
226   private native long getTotalRequests(final long handle);
227 }
228