Use batch endpoint in URLFrontier module for DISCOVERED urls - #2117
Open
abhinav-phi wants to merge 1 commit into
Open
Use batch endpoint in URLFrontier module for DISCOVERED urls#2117abhinav-phi wants to merge 1 commit into
abhinav-phi wants to merge 1 commit into
Conversation
… StatusUpdaterBolt Discovered URLs, which are the bulk of what a crawl writes, are now grouped into batches and sent on the PutDiscovered endpoint introduced in URLFrontier 2.6, amortising the per-message cost that limits the ingestion rate. Known URLs keep using the streaming PutURLs endpoint. - new config key urlfrontier.batch.size (default 100, 0 disables batching) - partially filled batches are flushed after 1s by a scheduled flusher, and whenever a known URL arrives (natural end-of-page boundary) or permits run short - batches are acked as a whole through BatchAck: one status per URL in the order they were sent, each resolved against the waitAck cache - frontiers without PutDiscovered (pre-2.6) are detected via UNIMPLEMENTED and the bolt falls back to sending discovered URLs individually - flow control follows the PutURLs client shipped with URLFrontier: throttled sends wait on a monitor woken by acks and by the transports' on-ready notifications instead of polling - requires urlfrontier-API 2.6 (wire compatible with 2.5 servers) Fixes apache#2062
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
URLFrontier 2.6 added a batched endpoint for ingesting discovered URLs,
PutDiscovered(stream DiscoveredBatch) returns (stream BatchAck). The per-message cost of the streamingPutURLsendpoint is what caps the ingestion rate, and discovered URLs — the outlinks of the pages being parsed — are the bulk of what a crawl writes. This PR routes them through the batched endpoint, grouping up tourlfrontier.batch.sizeURLs (default 100) into one message, while known URLs (fetched, redirections, errors...) keep using the streaming mode, as suggested in #2062. The control-flow mechanism follows the best practices of the client shipped with URLFrontier (PutURLs.java).Fixes #2062
What the bolt does now
StatusUpdaterBoltkeeps its overall structure: awaitAckcache holds the tuples per URL until the frontier acks them, and a semaphore bounds the messages in flight. What changes is the path each URL takes:Discovered URLs →
PutDiscovered. A DISCOVERED URL is appended to a buffer instead of being sent on its own. The buffer leaves as oneDiscoveredBatchmessage when:urlfrontier.batch.sizeentries;Each batch carries a unique ID (
batch-N); the frontier echoes it in theBatchAckwith one status per URL, in the order they were sent, so every URL can be resolved againstwaitAckand its tuples acked (or failed onFAIL) exactly as the streaming path did. Permits are released in bulk per URL, unchanged.Known URLs →
PutURLs, one message per URL, untouched behaviour.Flow control without polling.
store()used to busy-polltryAcquirewith a sleep. It now waits on a monitor (flow) and is woken bynotifyAll()from the places that change its conditions: permit releases (acks, evictions), transport on-ready notifications, and stream errors. The wait timeout (urlfrontier.throttling.time.msec, unchanged, 10 ms) is a backstop that also drives the periodicwaitAck.cleanUp()which prevents the deadlock the old code guarded against. This mirrors theisReady()/on-ready pattern of the reference client instead of polling.Fallback for older frontiers. If the frontier does not implement
PutDiscovered(i.e. predates 2.6), the stream fails withUNIMPLEMENTED. The bolt detects this, switches batching off permanently for its lifetime, and re-sends whatever was buffered or still in flight individually on the streaming endpoint — no URLs are lost, and a pre-2.6 frontier behaves exactly as before this PR. A dead batch stream (any other error) drops the pending batch IDs and opens a fresh stream on the next flush; the affected tuples are failed locally so Storm replays them.Configuration
New key, documented in the module README:
The module now depends on
urlfrontier-API2.6 (bumped from 2.5). The schema stays wire-compatible with 2.5 apart from the semantics noted in the 2.6 release notes, and the fallback covers servers that do not implement the new RPC, so no frontier upgrade is strictly required — though the batching only pays off against a 2.6 server.Tests
StatusUpdaterBoltTest.acknowledgesDiscoveredURLsSentInBatches— 6 discovered URLs against a 2.6 frontier with batch size 2: all acked, ≥ 3 batches sent, nothing failed;StatusUpdaterBoltTest.sendsDiscoveredURLsIndividuallyWhenBatchingDisabled—urlfrontier.batch.size: 0sends individually and never opens a batch;StatusUpdaterBoltTest.acksKnownURLsThroughStreamingEndpoint— known URLs still ack through the streaming endpoint;StatusUpdaterBoltFallbackTest— runs the bolt against acrawlercommons/url-frontier:2.5container: theUNIMPLEMENTEDerror is caught, batching is switched off, and discovered URLs are acked through the streaming fallback;StatusUpdaterBoltTestcases (ack with metadata, queue-stream emission, semaphore recovery after a frontier restart) pass unchanged on the new implementation.All 64 module tests pass locally against real frontier containers (testcontainers), checkstyle, forbiddenapis and the google-java-format check are clean. The
StatusUpdaterBoltJaCoCo ratios configured for this module still pass.Notes for reviewers
urlfrontier-APIstill lists 2.5 as latest; the portal deployment likely awaits the manual publish step, sincecentral-publishing-maven-plugindefaults toautoPublish=false). This PR builds against the 2.6 API regardless — the protobuf/gRPC API is stable in the 2.6 tag — but CI will needurlfrontier-API:2.6to be resolvable; it may be worth pinging the crawler-commons maintainers to complete the release on the portal. If 2.6 cannot be published soon, an alternative is to keep the dependency at 2.5 and build the batch messages from the proto (not possible:DiscoveredBatch/BatchAckand theputDiscoveredstub only exist in 2.6), so the version bump is inherent to the feature.waitAck-cache eviction semantics, the semaphore accounting, the queue-stream emission and the channel management (multi-address assignment, reconnect onTRANSIENT_FAILURE) are carried over unchanged from the previous implementation.PutDiscoveredstream is deliberately not re-created on channelTRANSIENT_FAILURE(unlike thePutURLsstream): withwaitForReadyit survives connection blips, and abandoning it would orphan the batches already sent on it.