blob: 5237a69c71494966cb6fac6b3349020c8b0b9d15 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc -->
<title>PartitionReconciler (Apache Beam 2.47.0)</title>
<link rel="stylesheet" type="text/css" href="../../../../../../../../../stylesheet.css" title="Style">
<script type="text/javascript" src="../../../../../../../../../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="PartitionReconciler (Apache Beam 2.47.0)";
}
}
catch(err) {
}
//-->
var methods = {"i0":10,"i1":10,"i2":10};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],8:["t4","Concrete Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">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">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev&nbsp;Class</li>
<li>Next&nbsp;Class</li>
</ul>
<ul class="navList">
<li><a href="../../../../../../../../../index.html?org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html" target="_top">Frames</a></li>
<li><a href="PartitionReconciler.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<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="subNavList">
<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>
<a name="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<!-- ======== START OF CLASS DATA ======== -->
<div class="header">
<div class="subTitle">org.apache.beam.sdk.io.gcp.bigtable.changestreams.reconciler</div>
<h2 title="Class PartitionReconciler" class="title">Class PartitionReconciler</h2>
</div>
<div class="contentContainer">
<ul class="inheritance">
<li>java.lang.Object</li>
<li>
<ul class="inheritance">
<li>org.apache.beam.sdk.io.gcp.bigtable.changestreams.reconciler.PartitionReconciler</li>
</ul>
</li>
</ul>
<div class="description">
<ul class="blockList">
<li class="blockList">
<hr>
<br>
<pre><a href="../../../../../../../../../org/apache/beam/sdk/annotations/Internal.html" title="annotation in org.apache.beam.sdk.annotations">@Internal</a>
public class <span class="typeNameLabel">PartitionReconciler</span>
extends java.lang.Object</pre>
<div class="block">There can be a race when many splits and merges happen to a single partition in quick succession.
It's possible that some CloseStream merge messages may be missed. This can lead to an
inconsistent state in the metadata table causing some partitions to not be streamed at all. This
class tries to reconcile the problem by ensuring that all partitions are streamed. If any
partitions are missing for an extended period of time, we fix it by creating a new
partitionRecord to stream the partition.
<p>Example of race condition:
<ol>
<li>Bigtable: decides to merge A-B and B-C to A-C
<li>Beam A-B: receives CloseStream to merge into Partition A-C . Creates entry in metadata and
terminates the stream.
<li>Beam B-C: is not currently streaming because it just check pointed and hasn't restarted
yet.
<li>Bigtable: decides maybe merge wasn't good, splits A-C back into A-B and B-C
<li>Beam B-C: restarts now, but it never receives the 1st CloseStream merge message and it
never will because CloseStream messages are not queued and because when requesting Change
Stream for B-C, Bigtable recognizes that B-C does exist, so it's happy to start the stream.
<li>Beam A-B: doesn't exist... it's in the metadata table waiting for B-C to merge into A-C.
</ol>
<p>To reconcile this, we identify partitions that haven't been streamed for at least 5 minutes.
This is probably an indication that there were some races of CloseStream merge messages.</div>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ======== CONSTRUCTOR SUMMARY ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor.summary">
<!-- -->
</a>
<h3>Constructor Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Constructor Summary table, listing constructors, and an explanation">
<caption><span>Constructors</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colOne" scope="col">Constructor and Description</th>
</tr>
<tr class="altColor">
<td class="colOne"><code><span class="memberNameLink"><a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html#PartitionReconciler-org.apache.beam.sdk.io.gcp.bigtable.changestreams.dao.MetadataTableDao-">PartitionReconciler</a></span>(<a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/dao/MetadataTableDao.html" title="class in org.apache.beam.sdk.io.gcp.bigtable.changestreams.dao">MetadataTableDao</a>&nbsp;metadataTableDao)</code>&nbsp;</td>
</tr>
</table>
</li>
</ul>
<!-- ========== METHOD SUMMARY =========== -->
<ul class="blockList">
<li class="blockList"><a name="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="memberSummary" border="0" cellpadding="3" cellspacing="0" summary="Method Summary table, listing methods, and an explanation">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t4" class="tableTab"><span><a href="javascript:show(8);">Concrete Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colLast" scope="col">Method and Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code>void</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html#addMissingPartitions-java.util.List-">addMissingPartitions</a></span>(java.util.List&lt;com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange&gt;&nbsp;missingPartitions)</code>
<div class="block">Capture partitions that are not currently being streamed.</div>
</td>
</tr>
<tr id="i1" class="rowColor">
<td class="colFirst"><code>void</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html#addNewPartition-com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange-com.google.protobuf.ByteString-">addNewPartition</a></span>(com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange&nbsp;partition,
com.google.protobuf.ByteString&nbsp;rowKey)</code>
<div class="block">Capture NewPartition row that's waiting to be created.</div>
</td>
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>java.util.HashMap&lt;com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange,java.util.Set&lt;com.google.protobuf.ByteString&gt;&gt;</code></td>
<td class="colLast"><code><span class="memberNameLink"><a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html#getPartitionsToReconcile--">getPartitionsToReconcile</a></span>()</code>
<div class="block">Match partitions that have been missing for a while and need to be reconciled with NewPartition
row key.</div>
</td>
</tr>
</table>
<ul class="blockList">
<li class="blockList"><a name="methods.inherited.from.class.java.lang.Object">
<!-- -->
</a>
<h3>Methods inherited from class&nbsp;java.lang.Object</h3>
<code>clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ========= CONSTRUCTOR DETAIL ======== -->
<ul class="blockList">
<li class="blockList"><a name="constructor.detail">
<!-- -->
</a>
<h3>Constructor Detail</h3>
<a name="PartitionReconciler-org.apache.beam.sdk.io.gcp.bigtable.changestreams.dao.MetadataTableDao-">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>PartitionReconciler</h4>
<pre>public&nbsp;PartitionReconciler(<a href="../../../../../../../../../org/apache/beam/sdk/io/gcp/bigtable/changestreams/dao/MetadataTableDao.html" title="class in org.apache.beam.sdk.io.gcp.bigtable.changestreams.dao">MetadataTableDao</a>&nbsp;metadataTableDao)</pre>
</li>
</ul>
</li>
</ul>
<!-- ============ METHOD DETAIL ========== -->
<ul class="blockList">
<li class="blockList"><a name="method.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a name="addMissingPartitions-java.util.List-">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>addMissingPartitions</h4>
<pre>public&nbsp;void&nbsp;addMissingPartitions(java.util.List&lt;com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange&gt;&nbsp;missingPartitions)</pre>
<div class="block">Capture partitions that are not currently being streamed. This should be the result of
observing the metadata table to identify missing StreamPartition rows. All the StreamPartitions
rows combined should form continuous, non-overlapping partitions covering all row keys.
<p>Combine existing missing partitions and current (newly added) missing partitions. If missing
partitions have been missing for more than allotted time, it will be reconciled.
<p>It is possible that a missing partition's boundary can change frequently, such that it can
take a long time to realize a partition is truly missing. For example, if [C, D) is missing,
but there are a lot of splits and merges around [C, D), we may see that sometimes [B,D) is
missing, or at other times [C-E) is missing due to split and merge activities of [B-C) and
[D-E), while [C-D) is truly missing. The moving boundaries would reset the timer leading to
slower reconciliation of the missing partition.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>missingPartitions</code> - partitions not being streamed.</dd>
</dl>
</li>
</ul>
<a name="addNewPartition-com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange-com.google.protobuf.ByteString-">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>addNewPartition</h4>
<pre>public&nbsp;void&nbsp;addNewPartition(com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange&nbsp;partition,
com.google.protobuf.ByteString&nbsp;rowKey)</pre>
<div class="block">Capture NewPartition row that's waiting to be created. If any of these NewPartition row
overlaps with partition we notice are missing and needs to be reconciled, we will need to clean
up these NewPartition to avoid future conflicts and inconsistencies.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>partition</code> - new partitions waiting to be created.</dd>
<dd><code>rowKey</code> - the full row key of the new partition.</dd>
</dl>
</li>
</ul>
<a name="getPartitionsToReconcile--">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>getPartitionsToReconcile</h4>
<pre>public&nbsp;java.util.HashMap&lt;com.google.cloud.bigtable.data.v2.models.Range.ByteStringRange,java.util.Set&lt;com.google.protobuf.ByteString&gt;&gt;&nbsp;getPartitionsToReconcile()</pre>
<div class="block">Match partitions that have been missing for a while and need to be reconciled with NewPartition
row key. Find NewPartition row key that overlaps with the reconciled partitions to clean them
up.</div>
<dl>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>missing partitions and related NewPartition rows keys to delete.</dd>
</dl>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- ========= END OF CLASS DATA ========= -->
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../../../../../overview-summary.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">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">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li>Prev&nbsp;Class</li>
<li>Next&nbsp;Class</li>
</ul>
<ul class="navList">
<li><a href="../../../../../../../../../index.html?org/apache/beam/sdk/io/gcp/bigtable/changestreams/reconciler/PartitionReconciler.html" target="_top">Frames</a></li>
<li><a href="PartitionReconciler.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../../../../../../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
</div>
<div>
<ul class="subNavList">
<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="subNavList">
<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>
<a name="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>