Skip to content

PageCache warmup on Server Restarts and Segment Refresh - #16033

Open
praveenc7 wants to merge 13 commits into
apache:masterfrom
praveenc7:pagecache
Open

PageCache warmup on Server Restarts and Segment Refresh#16033
praveenc7 wants to merge 13 commits into
apache:masterfrom
praveenc7:pagecache

Conversation

@praveenc7

@praveenc7 praveenc7 commented Jun 6, 2025

Copy link
Copy Markdown
Contributor

Summary

Issue link : #15675

What this PR delivers

Screenshot 2025-06-22 at 3 32 48 PM

Screenshot 2025-06-19 at 11 31 50 AM


🔄 Typical flow

  1. Create Query file

curl -X POST /pagecache/queries/airlineStats?tableType=OFFLINE \
     -d '["SELECT …", "SELECT …"]' -H 'Content-Type: application/json'

2. Server restart

Startup hook calls warm-up for each enabled table; queries run for the configured warmup duration

3. Segment refresh

Controller triggers warm-up for only the newly uploaded segments using the consistent protocol feature.


Backward compatibility

  • Fully opt-in – no existing table is affected until pageCacheWarmupConfig is set.

  • Query path remains unchanged; warm-up traffic stays on the secondary queue during refresh if BinaryWorkloadScheduler is enabled. During restart it uses the same primary queue since it is not competing with live traffic

Testing

unit test, manually tested using quick-starter and test actual servers

@praveenc7
praveenc7 force-pushed the pagecache branch 5 times, most recently from d27abf6 to 0def567 Compare June 23, 2025 16:37
@praveenc7
praveenc7 force-pushed the pagecache branch 3 times, most recently from ae48688 to 8110c5c Compare November 16, 2025 22:52
@codecov-commenter

codecov-commenter commented Nov 16, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.71336% with 380 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.65%. Comparing base (d40dceb) to head (436bffd).
⚠️ Report is 99 commits behind head on master.

Files with missing lines Patch % Lines
.../api/resources/PageCacheWarmupRestletResource.java 0.00% 94 Missing ⚠️
...ver/warmup/PageCacheWarmupServerQueryExecutor.java 52.94% 54 Missing and 18 partials ⚠️
...roller/util/PageCacheWarmupControllerExecutor.java 63.09% 50 Missing and 12 partials ⚠️
...pinot/server/warmup/PageCacheWarmupQueryUtils.java 0.00% 37 Missing ⚠️
...g/apache/pinot/common/utils/helix/HelixHelper.java 3.57% 27 Missing ⚠️
...che/pinot/server/api/resources/TablesResource.java 4.00% 24 Missing ⚠️
...pache/pinot/common/pagecache/WarmupQueryUtils.java 88.60% 9 Missing and 13 partials ⚠️
...pinot/client/admin/PageCacheWarmupAdminClient.java 0.00% 14 Missing ⚠️
.../pinot/server/starter/helix/BaseServerStarter.java 0.00% 7 Missing ⚠️
.../pinot/spi/config/table/PageCacheWarmupConfig.java 70.58% 4 Missing and 1 partial ⚠️
... and 7 more
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #16033      +/-   ##
============================================
+ Coverage     67.44%   67.65%   +0.21%     
- Complexity     1430     1450      +20     
============================================
  Files          3485     3498      +13     
  Lines        223874   225738    +1864     
  Branches      35300    35626     +326     
============================================
+ Hits         150987   152733    +1746     
- Misses        60890    60924      +34     
- Partials      11997    12081      +84     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 67.65% <50.71%> (+0.21%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 67.65% <50.71%> (+0.21%) ⬆️
unittests 67.65% <50.71%> (+0.21%) ⬆️
unittests1 57.83% <69.05%> (+0.29%) ⬆️
unittests2 39.43% <33.85%> (+0.13%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

# Conflicts:
#	pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerMeter.java
#	pinot-common/src/main/java/org/apache/pinot/common/utils/config/TableConfigSerDeUtils.java
#	pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
#	pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/OfflineClusterIntegrationTest.java
#	pinot-segment-local/src/test/java/org/apache/pinot/segment/local/utils/TableConfigUtilsTest.java
#	pinot-server/src/main/java/org/apache/pinot/server/starter/ServerInstance.java
#	pinot-server/src/main/java/org/apache/pinot/server/starter/helix/BaseServerStarter.java
#	pinot-spi/src/main/java/org/apache/pinot/spi/config/table/TableConfig.java
#	pinot-spi/src/main/java/org/apache/pinot/spi/utils/builder/TableConfigBuilder.java
@praveenc7
praveenc7 force-pushed the pagecache branch 2 times, most recently from 70006bc to 006052f Compare June 12, 2026 22:06
…tighter executors, simpler metrics

- Consolidate PageCacheWarmupConfig into a reusable nested Spec
  {enabled, maxWarmupDurationSeconds, qpsLimit, policy} used as optional
  onRestart/onRefresh blocks, giving per-case control without field duplication.
- Discover any live controller via HelixHelper.getControllerUrl(HelixManager)
  (moved out of QueryWorkloadConfigUtils so QRI and warmup share one copy),
  replacing the segment-download-URL parsing.
- Harden executors: fix TablesResource concurrent-warmup race (atomic claim),
  replace prod asserts with guards, fix restart-loop early return, make the
  per-query timeout effective, run controller HTTP fan-out on a dedicated
  bounded pool (shut down on stop), cancel work on timeout.
- Simplify metrics to host-level only; fold timeout errors into server errors
  and remove PAGE_CACHE_WARMUP_TIMEOUT_ERRORS.
- Fix TableConfigSerDeUtils.toZNRecord to serialize pageCacheWarmupConfig so it
  survives ZK round-trip; add controller.page.cache.warmup.duration.ms config.
@praveenc7
praveenc7 marked this pull request as ready for review June 12, 2026 22:30
praveenc7 and others added 3 commits June 18, 2026 14:04

PinotFS pinotFS = PinotFSFactory.create(URIUtils.getUri(_pageCacheWarmupQueriesDataDir).getScheme());
File tableDir = new File(_pageCacheWarmupQueriesDataDir, tableNameWithType);
File[] files = tableDir.listFiles(File::isFile);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we keep this lookup entirely within PinotFS? _pageCacheWarmupQueriesDataDir is resolved to a PinotFS above, and the upload/REST-read paths support filesystem URI schemes, but java.io.File.listFiles() can only enumerate local/POSIX paths. With an S3/HDFS-style data directory this will return null, causing onRefresh warmup to be silently skipped; queryFile.toURI() would also produce a file:// URI. This is especially relevant for multiple controllers, where the query files may need shared storage. PinotFS supports local disk through LocalPinotFS, so this could use pinotFS.listFiles(tableDirUri, false), filter entries with !pinotFS.isDirectory(uri), select by pinotFS.lastModified(uri), and then call pinotFS.open(uri).

@praveenc7 praveenc7 Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in fd08de7 and 0d12182. Query discovery now stays within PinotFS using listFilesWithMetadata(), filters directories through FileMetadata, selects the newest entry, and opens that same filesystem URI. It queries lastModified() only when an entry does not include a modification timestamp. Added coverage for S3/S3A raw keys, HDFS path-only metadata, LocalPinotFS, relative local paths, and missing directories.

praveenc7 and others added 3 commits September 10, 2026 00:07
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@praveenc7

Copy link
Copy Markdown
Contributor Author

The binary compact failure is expected because it checks for new delta in SPI class. This is harmless and this change is backward compatible the new field is defined as nullable

@praveenc7
praveenc7 requested a review from somandal September 10, 2026 18:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants