You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by "klsince (via GitHub)" <gi...@apache.org> on 2024/04/19 21:27:22 UTC
[PR] [WIP] add locking logic to get consistent table view for upsert tables [pinot]
klsince opened a new pull request, #12976:
URL: https://github.com/apache/pinot/pull/12976
This PR tries to support consistent table view for querying upsert tables. The consistency is at table partition level, which can contain many segments. Today, updates that involve two segments' bitmaps are not atomic, thus causing queries to see inconsistent table view, e.g. to return less than expected PKs.
The high level idea is either to synchronize the query threads and upsert threads (including consuming thread or HelixTaskExecutor threads) for queries to get a consistent set of segments' validDocIds bitmaps; or let upsert threads keep a copy of bitmaps and refresh it regularly. Both modes are added in this PR, as they can be wired up using one R/W lock.
Configs:
1. by default, the feature is disabled.
2. if _enableUpsertView=true, the upsert threads take the WLock when the upsert involves two segments' bitmaps; and the query threads take the RLock when getting bitmaps for all its selected segments. This is the sync mode, for best data freshness, but queries may block data ingestion. Mainly for low qps or low ingestion cases.
3. if _enableUpsertViewBatchRefresh=true, the query threads don't need to take lock when getting bitmaps. The query threads access a copy of bitmaps that are kept updated by upsert thread periodically. In this batch mode, if data freshness is concerned, the query can specify a query option as called upsertViewFreshnessMs (e.g. 3s) to set its tolerance on data freshness, and the query thread can fresh the bitmap copies immediately if they are not fresh enough. For high qps and high ingestion cases.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "Jackie-Jiang (via GitHub)" <gi...@apache.org>.
Jackie-Jiang commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1609034975
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1154,37 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs =
+ Math.min(QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions), _upsertViewRefreshIntervalMs);
+ if (upsertViewFreshnessMs == -1) {
Review Comment:
More robust
```suggestion
if (upsertViewFreshnessMs < 0) {
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] [WIP] add locking logic to get consistent table view for upsert tables [pinot]
Posted by "tibrewalpratik17 (via GitHub)" <gi...@apache.org>.
tibrewalpratik17 commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1575309595
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1103,6 +1210,48 @@ private static MutableRoaringBitmap getQueryableDocIdsSnapshotFromSegment(IndexS
return queryableDocIdsSnapshot;
}
+ private void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ for (SegmentContext segmentContext : segmentContexts) {
+ IndexSegment segment = segmentContext.getIndexSegment();
+ if (_trackedSegments.contains(segment)) {
+ segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ }
+ }
+ }
+
+ private boolean skipUpsertViewRefresh(long upsertViewFreshnessMs) {
+ long nowMs = System.currentTimeMillis();
+ if (upsertViewFreshnessMs >= 0) {
+ return _lastUpsertViewRefreshTimeMs + upsertViewFreshnessMs > nowMs;
+ }
+ return _lastUpsertViewRefreshTimeMs + _upsertViewRefreshIntervalMs > nowMs;
+ }
+
+ private void doBatchRefreshUpsertView(long upsertViewFreshnessMs) {
Review Comment:
Instead of doing this at partition metadata manager level can we move this to table data manager level? We can maintain a map of segment -> segmentContext and do a refresh there. This way we can easily extend the scope of segment context in future as well.
I was trying on something like this -- https://github.com/apache/pinot/compare/master...tibrewalpratik17:pinot:fix_upsert_inconsistency?expand=1
##########
pinot-spi/src/main/java/org/apache/pinot/spi/config/table/UpsertConfig.java:
##########
@@ -75,6 +75,15 @@ public enum Strategy {
@JsonPropertyDescription("Whether to preload segments for fast upsert metadata recovery")
private boolean _enablePreload;
+ @JsonPropertyDescription("Whether to enable consistent view for upsert table")
+ private boolean _enableUpsertView;
+
+ @JsonPropertyDescription("Whether to enable batch refresh mode to keep consistent view for upsert table")
+ private boolean _enableUpsertViewBatchRefresh;
Review Comment:
imo this should be enabled by default. At present, this is more of a bugfix rather than a feature to be kept behind a config. It can be kept behind a config initially to be on the safer side but then we should enable it by default in the long run.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1607358605
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1019,34 +1038,106 @@ public synchronized void close()
_logger.info("Closed the metadata manager");
}
- protected void replaceDocId(ThreadSafeMutableRoaringBitmap validDocIds,
+ /**
+ * Use WLock to make updates on two segments' bitmaps atomically.
+ */
+ protected void replaceDocId(IndexSegment newSegment, ThreadSafeMutableRoaringBitmap validDocIds,
@Nullable ThreadSafeMutableRoaringBitmap queryableDocIds, IndexSegment oldSegment, int oldDocId, int newDocId,
RecordInfo recordInfo) {
- removeDocId(oldSegment, oldDocId);
- addDocId(validDocIds, queryableDocIds, newDocId, recordInfo);
+ // For SNAPSHOT consistency mode, we can use RLock here. But for simplicity and considering there is only one
Review Comment:
kk, separated and commented for more clarity.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1607346400
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
for (SegmentContext segmentContext : segmentContexts) {
IndexSegment segment = segmentContext.getIndexSegment();
- if (_trackedSegments.contains(segment)) {
- segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ if (_segmentQueryableDocIdsMap.containsKey(segment)) {
Review Comment:
good point
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1607359133
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
Review Comment:
correct. the default refresh interval should be checked regardless. updating.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "Jackie-Jiang (via GitHub)" <gi...@apache.org>.
Jackie-Jiang commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1605907484
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
for (SegmentContext segmentContext : segmentContexts) {
IndexSegment segment = segmentContext.getIndexSegment();
- if (_trackedSegments.contains(segment)) {
- segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ if (_segmentQueryableDocIdsMap.containsKey(segment)) {
+ segmentContext.setQueryableDocIdsSnapshot(_segmentQueryableDocIdsMap.get(segment));
Review Comment:
We can use `get()` and `null` check to save one map lookup
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
Review Comment:
I think we always need to do this check even if query doesn't have query option. There is no guarantee there are updates in the past `upsertViewFreshnessMs` and we might miss updates
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1019,34 +1038,106 @@ public synchronized void close()
_logger.info("Closed the metadata manager");
}
- protected void replaceDocId(ThreadSafeMutableRoaringBitmap validDocIds,
+ /**
+ * Use WLock to make updates on two segments' bitmaps atomically.
+ */
+ protected void replaceDocId(IndexSegment newSegment, ThreadSafeMutableRoaringBitmap validDocIds,
@Nullable ThreadSafeMutableRoaringBitmap queryableDocIds, IndexSegment oldSegment, int oldDocId, int newDocId,
RecordInfo recordInfo) {
- removeDocId(oldSegment, oldDocId);
- addDocId(validDocIds, queryableDocIds, newDocId, recordInfo);
+ // For SNAPSHOT consistency mode, we can use RLock here. But for simplicity and considering there is only one
Review Comment:
Suggest keeping it consistent. I found it easier to understand if we always use RL for updates and WL for sync
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
for (SegmentContext segmentContext : segmentContexts) {
IndexSegment segment = segmentContext.getIndexSegment();
- if (_trackedSegments.contains(segment)) {
- segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ if (_segmentQueryableDocIdsMap.containsKey(segment)) {
Review Comment:
We need to read the value into a local variable, or it might be updated in the middle
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1081,6 +1192,52 @@ private static MutableRoaringBitmap getQueryableDocIdsSnapshotFromSegment(IndexS
return queryableDocIdsSnapshot;
}
+ private void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ for (SegmentContext segmentContext : segmentContexts) {
+ IndexSegment segment = segmentContext.getIndexSegment();
+ if (_trackedSegments.contains(segment)) {
+ segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ }
+ }
+ }
+
+ private boolean skipUpsertViewRefresh(long upsertViewFreshnessMs) {
+ long nowMs = System.currentTimeMillis();
Review Comment:
(minor) Check `upsertViewFreshnessMs` before getting the current time. We may also check for `== 0` and directly return `false`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1607011337
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1149,31 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs = QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions);
+ doBatchRefreshUpsertView(upsertViewFreshnessMs);
for (SegmentContext segmentContext : segmentContexts) {
IndexSegment segment = segmentContext.getIndexSegment();
- if (_trackedSegments.contains(segment)) {
- segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ if (_segmentQueryableDocIdsMap.containsKey(segment)) {
+ segmentContext.setQueryableDocIdsSnapshot(_segmentQueryableDocIdsMap.get(segment));
Review Comment:
sharp eye. why not.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1609047588
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1058,11 +1154,37 @@ protected void removeDocId(IndexSegment segment, int docId) {
* Use the segmentContexts to collect the contexts for selected segments. Reuse the segmentContext object if
* present, to avoid overwriting the contexts specified at the others places.
*/
- public void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ public void setSegmentContexts(List<SegmentContext> segmentContexts, Map<String, String> queryOptions) {
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.NONE) {
+ setSegmentContexts(segmentContexts);
+ return;
+ }
+ if (_consistencyMode == UpsertConfig.ConsistencyMode.SYNC) {
+ _upsertViewLock.readLock().lock();
+ try {
+ setSegmentContexts(segmentContexts);
+ return;
+ } finally {
+ _upsertViewLock.readLock().unlock();
+ }
+ }
+ // If batch refresh is enabled, the copy of bitmaps is kept updated and ready to use for a consistent view.
+ // The locking between query threads and upsert threads can be avoided when using batch refresh.
+ // Besides, queries can share the copy of bitmaps, w/o cloning the bitmaps by every single query.
+ // If query has specified a need for certain freshness, check the view and refresh it as needed.
+ // When refreshing the copy of map, we need to take the WLock so only one thread is refreshing view.
+ long upsertViewFreshnessMs =
+ Math.min(QueryOptionsUtils.getUpsertViewFreshnessMs(queryOptions), _upsertViewRefreshIntervalMs);
+ if (upsertViewFreshnessMs == -1) {
Review Comment:
good catch! used < 0 in another check, so better do < 0 here too.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] Add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince merged PR #12976:
URL: https://github.com/apache/pinot/pull/12976
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] [WIP] add locking logic to get consistent table view for upsert tables [pinot]
Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #12976:
URL: https://github.com/apache/pinot/pull/12976#issuecomment-2067349336
## [Codecov](https://app.codecov.io/gh/apache/pinot/pull/12976?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
Attention: Patch coverage is `43.65079%` with `71 lines` in your changes are missing coverage. Please review.
> Project coverage is 62.10%. Comparing base [(`59551e4`)](https://app.codecov.io/gh/apache/pinot/commit/59551e45224f1535c4863fd577622b37366ccc97?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) to head [(`de05748`)](https://app.codecov.io/gh/apache/pinot/pull/12976?dropdown=coverage&src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
> Report is 345 commits behind head on master.
| [Files](https://app.codecov.io/gh/apache/pinot/pull/12976?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
|---|---|---|
| [...cal/upsert/BasePartitionUpsertMetadataManager.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-segment-local%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fsegment%2Flocal%2Fupsert%2FBasePartitionUpsertMetadataManager.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91cHNlcnQvQmFzZVBhcnRpdGlvblVwc2VydE1ldGFkYXRhTWFuYWdlci5qYXZh) | 20.73% | [55 Missing and 10 partials :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...e/pinot/common/utils/config/QueryOptionsUtils.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-common%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fcommon%2Futils%2Fconfig%2FQueryOptionsUtils.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vdXRpbHMvY29uZmlnL1F1ZXJ5T3B0aW9uc1V0aWxzLmphdmE=) | 0.00% | [2 Missing :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...ata/manager/realtime/RealtimeTableDataManager.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-core%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fcore%2Fdata%2Fmanager%2Frealtime%2FRealtimeTableDataManager.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9kYXRhL21hbmFnZXIvcmVhbHRpbWUvUmVhbHRpbWVUYWJsZURhdGFNYW5hZ2VyLmphdmE=) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...t/ConcurrentMapPartitionUpsertMetadataManager.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-segment-local%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fsegment%2Flocal%2Fupsert%2FConcurrentMapPartitionUpsertMetadataManager.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91cHNlcnQvQ29uY3VycmVudE1hcFBhcnRpdGlvblVwc2VydE1ldGFkYXRhTWFuYWdlci5qYXZh) | 88.88% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...psert/ConcurrentMapTableUpsertMetadataManager.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-segment-local%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fsegment%2Flocal%2Fupsert%2FConcurrentMapTableUpsertMetadataManager.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91cHNlcnQvQ29uY3VycmVudE1hcFRhYmxlVXBzZXJ0TWV0YWRhdGFNYW5hZ2VyLmphdmE=) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [...ache/pinot/segment/local/upsert/UpsertContext.java](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&filepath=pinot-segment-local%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fpinot%2Fsegment%2Flocal%2Fupsert%2FUpsertContext.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91cHNlcnQvVXBzZXJ0Q29udGV4dC5qYXZh) | 92.30% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/pinot/pull/12976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## master #12976 +/- ##
============================================
+ Coverage 61.75% 62.10% +0.35%
+ Complexity 207 198 -9
============================================
Files 2436 2502 +66
Lines 133233 136615 +3382
Branches 20636 21147 +511
============================================
+ Hits 82274 84846 +2572
- Misses 44911 45471 +560
- Partials 6048 6298 +250
```
| [Flag](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
|---|---|---|
| [custom-integration1](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `<0.01% <0.00%> (-0.01%)` | :arrow_down: |
| [integration](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `<0.01% <0.00%> (-0.01%)` | :arrow_down: |
| [integration1](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `<0.01% <0.00%> (-0.01%)` | :arrow_down: |
| [integration2](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `0.00% <0.00%> (ø)` | |
| [java-11](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `62.10% <43.65%> (+0.39%)` | :arrow_up: |
| [java-21](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `<0.01% <0.00%> (-61.63%)` | :arrow_down: |
| [skip-bytebuffers-false](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `62.10% <43.65%> (+0.35%)` | :arrow_up: |
| [skip-bytebuffers-true](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `0.00% <0.00%> (-27.73%)` | :arrow_down: |
| [temurin](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `62.10% <43.65%> (+0.35%)` | :arrow_up: |
| [unittests](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `62.10% <43.65%> (+0.35%)` | :arrow_up: |
| [unittests1](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `46.63% <7.14%> (-0.27%)` | :arrow_down: |
| [unittests2](https://app.codecov.io/gh/apache/pinot/pull/12976/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `27.93% <36.50%> (+0.20%)` | :arrow_up: |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
</details>
[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/apache/pinot/pull/12976?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
Re: [PR] [WIP] add locking logic to get consistent table view for upsert tables [pinot]
Posted by "klsince (via GitHub)" <gi...@apache.org>.
klsince commented on code in PR #12976:
URL: https://github.com/apache/pinot/pull/12976#discussion_r1576744981
##########
pinot-segment-local/src/main/java/org/apache/pinot/segment/local/upsert/BasePartitionUpsertMetadataManager.java:
##########
@@ -1103,6 +1210,48 @@ private static MutableRoaringBitmap getQueryableDocIdsSnapshotFromSegment(IndexS
return queryableDocIdsSnapshot;
}
+ private void setSegmentContexts(List<SegmentContext> segmentContexts) {
+ for (SegmentContext segmentContext : segmentContexts) {
+ IndexSegment segment = segmentContext.getIndexSegment();
+ if (_trackedSegments.contains(segment)) {
+ segmentContext.setQueryableDocIdsSnapshot(getQueryableDocIdsSnapshotFromSegment(segment));
+ }
+ }
+ }
+
+ private boolean skipUpsertViewRefresh(long upsertViewFreshnessMs) {
+ long nowMs = System.currentTimeMillis();
+ if (upsertViewFreshnessMs >= 0) {
+ return _lastUpsertViewRefreshTimeMs + upsertViewFreshnessMs > nowMs;
+ }
+ return _lastUpsertViewRefreshTimeMs + _upsertViewRefreshIntervalMs > nowMs;
+ }
+
+ private void doBatchRefreshUpsertView(long upsertViewFreshnessMs) {
Review Comment:
Thanks for sharing the code changes, and I read it through. The refreshing logic is similar with the batch mode here although done at table mgr level. But your changes didn't allow query threads to force update the view to ensure data freshness.
I think it's more intuitive to handle data consistency in table partition mgr, as table partition is the unit for managing upsert states in upsert table.
Today, the table partition mgr `enriches` the segment contexts, which are provided by table partition mgr, so there shouldn't be limitation to extending segment contexts later. In fact hiding the consistency logic away from table mgr would make it easier to iterate in future.
```
public void setSegmentContexts(List<SegmentContext> segmentContexts) {
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org