blob: 598717820284e93e12aa5aa3aafebb490bd98bb2 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en">
<head>
<!-- Generated by javadoc (17) -->
<title>TokenBucket (kafka 3.6.1 API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="declaration: package: org.apache.kafka.common.metrics.stats, class: TokenBucket">
<meta name="generator" content="javadoc/ClassWriterImpl">
<link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../script-dir/jquery-ui.min.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../../jquery-ui.overrides.css" title="Style">
<script type="text/javascript" src="../../../../../../script.js"></script>
<script type="text/javascript" src="../../../../../../script-dir/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="../../../../../../script-dir/jquery-ui.min.js"></script>
</head>
<body class="class-declaration-page">
<script type="text/javascript">var evenRowColor = "even-row-color";
var oddRowColor = "odd-row-color";
var tableTab = "table-tab";
var activeTableTab = "active-table-tab";
var pathtoroot = "../../../../../../";
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<div class="flex-box">
<header role="banner" class="flex-header">
<nav role="navigation">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="top-nav" id="navbar-top">
<div class="skip-nav"><a href="#skip-navbar-top" title="Skip navigation links">Skip navigation links</a></div>
<ul id="navbar-top-firstrow" class="nav-list" title="Navigation">
<li><a href="../../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="nav-bar-cell1-rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../../help-doc.html#class">Help</a></li>
</ul>
</div>
<div class="sub-nav">
<div>
<ul class="sub-nav-list">
<li>Summary:&nbsp;</li>
<li>Nested&nbsp;|&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-summary">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-summary">Method</a></li>
</ul>
<ul class="sub-nav-list">
<li>Detail:&nbsp;</li>
<li>Field&nbsp;|&nbsp;</li>
<li><a href="#constructor-detail">Constr</a>&nbsp;|&nbsp;</li>
<li><a href="#method-detail">Method</a></li>
</ul>
</div>
<div class="nav-list-search"><label for="search-input">SEARCH:</label>
<input type="text" id="search-input" value="search" disabled="disabled">
<input type="reset" id="reset-button" value="reset" disabled="disabled">
</div>
</div>
<!-- ========= END OF TOP NAVBAR ========= -->
<span class="skip-nav" id="skip-navbar-top"></span></nav>
</header>
<div class="flex-content">
<main role="main">
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="sub-title"><span class="package-label-in-type">Package</span>&nbsp;<a href="package-summary.html">org.apache.kafka.common.metrics.stats</a></div>
<h1 title="Class TokenBucket" class="title">Class TokenBucket</h1>
</div>
<div class="inheritance" title="Inheritance Tree"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">java.lang.Object</a>
<div class="inheritance">org.apache.kafka.common.metrics.stats.TokenBucket</div>
</div>
<section class="class-description" id="class-description">
<dl class="notes">
<dt>All Implemented Interfaces:</dt>
<dd><code><a href="../Measurable.html" title="interface in org.apache.kafka.common.metrics">Measurable</a></code>, <code><a href="../MeasurableStat.html" title="interface in org.apache.kafka.common.metrics">MeasurableStat</a></code>, <code><a href="../MetricValueProvider.html" title="interface in org.apache.kafka.common.metrics">MetricValueProvider</a>&lt;<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Double.html" title="class or interface in java.lang" class="external-link">Double</a>&gt;</code>, <code><a href="../Stat.html" title="interface in org.apache.kafka.common.metrics">Stat</a></code></dd>
</dl>
<hr>
<div class="type-signature"><span class="modifiers">public class </span><span class="element-name type-name-label">TokenBucket</span>
<span class="extends-implements">extends <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a>
implements <a href="../MeasurableStat.html" title="interface in org.apache.kafka.common.metrics">MeasurableStat</a></span></div>
<div class="block">The <a href="TokenBucket.html" title="class in org.apache.kafka.common.metrics.stats"><code>TokenBucket</code></a> is a <a href="../MeasurableStat.html" title="interface in org.apache.kafka.common.metrics"><code>MeasurableStat</code></a> implementing a token bucket algorithm
that is usable within a <a href="../Sensor.html" title="class in org.apache.kafka.common.metrics"><code>Sensor</code></a>.
The <a href="../Quota.html#bound()"><code>Quota.bound()</code></a> defined the refill rate of the bucket while the maximum burst or
the maximum number of credits of the bucket is defined by
<a href="../MetricConfig.html#samples()"><code>* MetricConfig#timeWindowMs() * Quota#bound()</code></a>.
The quota is considered as exhausted when the amount of remaining credits in the bucket
is below zero. The enforcement is done by the <a href="../Sensor.html" title="class in org.apache.kafka.common.metrics"><code>Sensor</code></a>.
Token Bucket vs Rate based Quota:
The current sampled rate based quota does not cope well with bursty workloads. The issue is
that a unique and large sample can hold the average above the quota until it is discarded.
Practically, when this happens, one must wait until the sample is expired to bring the rate
below the quota even though less time would be theoretically required. As an example, let's
imagine that we have:
- Quota (Q) = 5
- Samples (S) = 100
- Window (W) = 1s
A burst of 560 brings the average rate (R) to 5.6 (560 / 100). The expected throttle time is
computed as follow: ((R - Q / Q * S * W)) = ((5.6 - 5) / 5 * 100 * 1) = 12 secs. In practice,
the average rate won't go below the quota before the burst is dropped from the samples so one
must wait 100s (S * W).
The token bucket relies on continuously updated amount of credits. Therefore, it does not
suffers from the above issue. The same example would work as follow:
- Quota (Q) = 5
- Burst (B) = 5 * 1 * 100 = 500 (Q * S * W)
A burst of 560 brings the amount of credits to -60. One must wait 12s (-(-60)/5) to refill the
bucket to zero.</div>
</section>
<section class="summary">
<ul class="summary-list">
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<li>
<section class="constructor-summary" id="constructor-summary">
<h2>Constructor Summary</h2>
<div class="caption"><span>Constructors</span></div>
<div class="summary-table two-column-summary">
<div class="table-header col-first">Constructor</div>
<div class="table-header col-last">Description</div>
<div class="col-constructor-name even-row-color"><code><a href="#%3Cinit%3E()" class="member-name-link">TokenBucket</a>()</code></div>
<div class="col-last even-row-color">&nbsp;</div>
<div class="col-constructor-name odd-row-color"><code><a href="#%3Cinit%3E(java.util.concurrent.TimeUnit)" class="member-name-link">TokenBucket</a><wbr>(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/TimeUnit.html" title="class or interface in java.util.concurrent" class="external-link">TimeUnit</a>&nbsp;unit)</code></div>
<div class="col-last odd-row-color">&nbsp;</div>
</div>
</section>
</li>
<!-- ========== METHOD SUMMARY =========== -->
<li>
<section class="method-summary" id="method-summary">
<h2>Method Summary</h2>
<div id="method-summary-table">
<div class="table-tabs" role="tablist" aria-orientation="horizontal"><button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab2" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab2', 3)" class="table-tab">Instance Methods</button><button id="method-summary-table-tab4" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab4', 3)" class="table-tab">Concrete Methods</button></div>
<div id="method-summary-table.tabpanel" role="tabpanel">
<div class="summary-table three-column-summary" aria-labelledby="method-summary-table-tab0">
<div class="table-header col-first">Modifier and Type</div>
<div class="table-header col-second">Method</div>
<div class="table-header col-last">Description</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>double</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#measure(org.apache.kafka.common.metrics.MetricConfig,long)" class="member-name-link">measure</a><wbr>(<a href="../MetricConfig.html" title="class in org.apache.kafka.common.metrics">MetricConfig</a>&nbsp;config,
long&nbsp;timeMs)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Measure this quantity and return the result as a double</div>
</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#record(org.apache.kafka.common.metrics.MetricConfig,double,long)" class="member-name-link">record</a><wbr>(<a href="../MetricConfig.html" title="class in org.apache.kafka.common.metrics">MetricConfig</a>&nbsp;config,
double&nbsp;value,
long&nbsp;timeMs)</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Record the given value</div>
</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#toString()" class="member-name-link">toString</a>()</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
</div>
</div>
</div>
<div class="inherited-list">
<h3 id="methods-inherited-from-class-java.lang.Object">Methods inherited from class&nbsp;java.lang.<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></h3>
<code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#clone()" title="class or interface in java.lang" class="external-link">clone</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)" title="class or interface in java.lang" class="external-link">equals</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#finalize()" title="class or interface in java.lang" class="external-link">finalize</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#getClass()" title="class or interface in java.lang" class="external-link">getClass</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#hashCode()" title="class or interface in java.lang" class="external-link">hashCode</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#notify()" title="class or interface in java.lang" class="external-link">notify</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#notifyAll()" title="class or interface in java.lang" class="external-link">notifyAll</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#wait()" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#wait(long)" title="class or interface in java.lang" class="external-link">wait</a>, <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#wait(long,int)" title="class or interface in java.lang" class="external-link">wait</a></code></div>
</section>
</li>
</ul>
</section>
<section class="details">
<ul class="details-list">
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<li>
<section class="constructor-details" id="constructor-detail">
<h2>Constructor Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="&lt;init&gt;()">
<h3>TokenBucket</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name">TokenBucket</span>()</div>
</section>
</li>
<li>
<section class="detail" id="&lt;init&gt;(java.util.concurrent.TimeUnit)">
<h3>TokenBucket</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name">TokenBucket</span><wbr><span class="parameters">(<a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/TimeUnit.html" title="class or interface in java.util.concurrent" class="external-link">TimeUnit</a>&nbsp;unit)</span></div>
</section>
</li>
</ul>
</section>
</li>
<!-- ============ METHOD DETAIL ========== -->
<li>
<section class="method-details" id="method-detail">
<h2>Method Details</h2>
<ul class="member-list">
<li>
<section class="detail" id="measure(org.apache.kafka.common.metrics.MetricConfig,long)">
<h3>measure</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">double</span>&nbsp;<span class="element-name">measure</span><wbr><span class="parameters">(<a href="../MetricConfig.html" title="class in org.apache.kafka.common.metrics">MetricConfig</a>&nbsp;config,
long&nbsp;timeMs)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="../Measurable.html#measure(org.apache.kafka.common.metrics.MetricConfig,long)">Measurable</a></code></span></div>
<div class="block">Measure this quantity and return the result as a double</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="../Measurable.html#measure(org.apache.kafka.common.metrics.MetricConfig,long)">measure</a></code>&nbsp;in interface&nbsp;<code><a href="../Measurable.html" title="interface in org.apache.kafka.common.metrics">Measurable</a></code></dd>
<dt>Parameters:</dt>
<dd><code>config</code> - The configuration for this metric</dd>
<dd><code>timeMs</code> - The POSIX time in milliseconds the measurement is being taken</dd>
<dt>Returns:</dt>
<dd>The measured value</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="record(org.apache.kafka.common.metrics.MetricConfig,double,long)">
<h3>record</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name">record</span><wbr><span class="parameters">(<a href="../MetricConfig.html" title="class in org.apache.kafka.common.metrics">MetricConfig</a>&nbsp;config,
double&nbsp;value,
long&nbsp;timeMs)</span></div>
<div class="block"><span class="descfrm-type-label">Description copied from interface:&nbsp;<code><a href="../Stat.html#record(org.apache.kafka.common.metrics.MetricConfig,double,long)">Stat</a></code></span></div>
<div class="block">Record the given value</div>
<dl class="notes">
<dt>Specified by:</dt>
<dd><code><a href="../Stat.html#record(org.apache.kafka.common.metrics.MetricConfig,double,long)">record</a></code>&nbsp;in interface&nbsp;<code><a href="../Stat.html" title="interface in org.apache.kafka.common.metrics">Stat</a></code></dd>
<dt>Parameters:</dt>
<dd><code>config</code> - The configuration to use for this metric</dd>
<dd><code>value</code> - The value to record</dd>
<dd><code>timeMs</code> - The POSIX time in milliseconds this value occurred</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="toString()">
<h3>toString</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span>&nbsp;<span class="element-name">toString</span>()</div>
<dl class="notes">
<dt>Overrides:</dt>
<dd><code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#toString()" title="class or interface in java.lang" class="external-link">toString</a></code>&nbsp;in class&nbsp;<code><a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html" title="class or interface in java.lang" class="external-link">Object</a></code></dd>
</dl>
</section>
</li>
</ul>
</section>
</li>
</ul>
</section>
<!-- ========= END OF CLASS DATA ========= -->
</main>
</div>
</div>
</body>
</html>