01Crawl किस लिए है — search index, LLM training data, archival? यह size और freshness तय करता है।
Seeds से शुरू करके pages fetch करें और downstream उपयोग के लिए raw content store करें — consumer तय करता है कि 'done' का मतलब क्या है।
मुफ़्त पूरी गाइड
वेब क्रॉलर डिज़ाइन करें। इसमें URL frontier design: priority queues for scheduling and re-crawl ordering, Politeness: robots.txt compliance and per-domain rate limiting to avoid hammering one host,...
Interview की लय संक्षिप्त रहती है, ताकि page असली design निर्णयों पर ध्यान लगा सके.
सिर्फ requirements मत बताइए — पूछिए। हर card एक design constraint को उस clarification सवाल से जोड़ता है जो आप architecture बनाने से पहले बोल सकते हैं.
01Crawl किस लिए है — search index, LLM training data, archival? यह size और freshness तय करता है।
Seeds से शुरू करके pages fetch करें और downstream उपयोग के लिए raw content store करें — consumer तय करता है कि 'done' का मतलब क्या है।
02Crawl कैसे बढ़ता है — क्या extracted links वापस feed होते हैं?
हर fetched page से links parse होते हैं, जो filter होकर वापस frontier में feed होते हैं — crawl seeds से ख़ुद को क़ायम रखता है।
03Politeness: requirement या nice-to-have?
एक requirement: robots.txt (crawl-delay समेत) का पालन करें, user-agent के ज़रिए ईमानदारी से पहचान बताएँ, और किसी भी एक host को कभी overload न करें।
04क्या operators crawl के बीच में seeds और priority URLs inject कर सकते हैं?
हाँ। Operators URLs को high priority पर धकेल सकते हैं, उन links से आगे जो crawl खुद ढूँढता है। एक crawl को steer किया जा सकता है, बस चलता छोड़ नहीं दिया जाता।
05हम असल में क्या store करते हैं — raw bytes, parsed text, या दोनों?
दोनों। हम raw content को blob storage में रखते हैं, साथ में निकाला गया text और metadata। बाद में reprocess करने का मतलब page को दोबारा fetch करना कभी नहीं होना चाहिए।
06robots.txt कितनी fresh होनी चाहिए?
घंटों के भीतर fresh: एक host को कभी कुछ घंटे से पुराने robots.txt rules पर crawl न किया जाए — एक stale allow पर काम करना एक compliance risk है।
Scope से बाहरSearch ranking और indexing (crawler corpus बनाता है, index नहीं) · Dynamic pages की JavaScript rendering · Freshness के लिए continuous re-crawling (पहले एक single full crawl)
01कितने pages, और कितनी तेज़ी से?
5 दिन से कम में 10B pages — यह एक लाइन ही fleet size और queue throughput तय कर देती है।
02जिन websites को हम crawl करते हैं उन्हें क्या protect करता है?
Backlog चाहे जो हो, हर host का crawl-delay honor कीजिए: एक ही site के लिए दस लाख queued URLs धीरे-धीरे drain हों, कभी एक flood की तरह नहीं।
03एक ही page अक्सर कई URLs पर रहती है — mirrors, tracking parameters, www variants। क्या corpus को हर page केवल एक बार रखनी चाहिए?
एक ही URL को कभी दो बार fetch न कीजिए, और अलग-अलग URLs के ज़रिए पहुँची एक ही page corpus में केवल एक बार उतरे।
04अगर एक machine crawl के बीच crash हो जाए, तो क्या हम उन URLs को खो सकते हैं जिन पर वह काम कर रही थी, या हर URL का अंततः हिसाब होना ही होगा?
कुछ भी चुपचाप न खोए: हर URL अंततः या तो fetch हो या स्पष्ट रूप से failed record हो — एक machine crash कभी काम को गायब न कर दे।
05Infinite URL spaces के बारे में क्या?
Depth caps, per-domain page budgets, और URL-pattern filters calendar pages और ad farms को crawl खाने से रोकते हैं।
असली interview एक साफ list से कहीं गहरा probe करते हैं. ये scope सवाल उन्हें अलग करते हैं जो problem को कुरेदते हैं बनाम जो रटते हैं.
हर estimate को एक दबाव मानिए जो किसी component को justify करता है: cache, queue, partition, replica, worker pool, या fallback path.
Required fetch rate
10B pages ÷ 5 days10,000,000,000 ÷ 432,000 s ≈ 23K pages/s sustained
यह एक fleet है, एक server नहीं — और frontier को हर second 23K URL बाँटने होते हैं, वो भी politeness का पालन करते हुए (हर host की crawl-delay माने, किसी एक host को कभी overload न करे)।
Fleet size
प्रति page ~2 s औसत fetch latency, यानी प्रति connection ~0.5 pages/s · प्रति box ~4K उपयोगी concurrent connections23K ÷ (4,000 × 0.5) ≈ 12 machines sustained — retries और slow hosts के लिए ~2× provision करें
दो-चार दर्जन fetchers deadline पूरी कर देते हैं; bottleneck politeness है, compute नहीं।
URL-seen memory
1% false positives पर एक Bloom filter में 10B URLs (~10 bits हर एक)10B × 10 b ≈ 12 GB — बनाम exact strings के लिए ~400 GB
जो मायने रखता है वह Bloom का जवाब है "पक्का नया।" एक false positive बस एक URL छोड़ देता है। एक false negative कभी नहीं होता, इसलिए कुछ भी दो बार crawl नहीं होता।
Storage for the corpus
10B pages × ~100 KB stored HTML — जो multi-MB page weight quote होता है वह ज़्यादातर images और scripts हैं जिन्हें यह crawler कभी fetch नहीं करता≈ 1 PB raw
Compression के साथ blob storage; metadata (hashes, URLs) एक अलग store में queryable रहता है।
DNS pressure
23K fetches/s, हर एक को resolution चाहिएबिना caching: 23K lookups/s · per-fetcher DNS cache के साथ: प्रति नए host ~1
Fleet के भीतर एक DNS cache अनिवार्य है — public resolvers crawl को rate-limit करके मार डालेंगे।
निर्णय उदाहरण
तेईस हज़ार pages प्रति सेकंड, लगातार पाँच दिन। पर असली अड़चन उल्टी दिशा में है: किसी एक website को कभी एक trickle से ज़्यादा महसूस न हो।
मैं frontier को दो stages में बाँटूँगा। Front queues URLs को priority से order करती हैं; back queues हर host को उसका अपना queue देती हैं, हर host के लिए एक token bucket के साथ जो crawl-delay का पालन करता है। Fetchers URLs को delete करने की बजाय lease लेते हैं, success पर ack करते हैं, और lease timeouts crashes से recover कर देते हैं। एक URL enqueue से पहले एक Bloom-filter seen-check पास करता है, और fetch के बाद एक content hash उसी page को पकड़ लेता है जो अलग-अलग URLs से पहुँचा हो। Robots rules प्रति domain एक TTL के साथ cache होते हैं, और DNS को fleet के अंदर अपना cache मिलता है।
जो मैं नहीं करूँगा: एक global priority queue इस्तेमाल करना। जिस पल एक बड़ी site दस लाख URLs उड़ेलती है, fetchers उस host को ठोकते हैं और crawl एक DDoS बन जाता है। मैं seen URLs को एक exact database table में भी track नहीं करूँगा। यानी 400 GB strings और प्रति enqueue एक lookup, जबकि एक 12 GB Bloom filter मुफ़्त में "पक्का नया" का जवाब दे देता है। इसका कभी-कभार का false positive बस एक URL छोड़ देता है, जो चूकने की सुरक्षित दिशा है।
अगर corpus को एक crawl के बजाय continuous freshness चाहिए, तो frontier को एक re-crawl scheduler मिलता है: pages change frequency और importance से दोबारा enter होते हैं, और seen-filter एक ऐसी structure में बदल जाता है जो aging out सपोर्ट करती है।
पहले एक पूरी तस्वीर, फिर हर path को अपना अलग diagram — write path और read path अलग traffic ढोते हैं और अलग components justify करते हैं.
पूरी तस्वीर
Path 1
एक URL तभी बाँटा जाता है जब उसके host के पास एक token हो; crash पर lease queue में लौटता है, retries backoff करती हैं, और बार-बार failures एक dead-letter queue में गिरती हैं।
Path 2
हर page links देता है; filters traps और junk गिराते हैं, Bloom filter हर पहले से देखी चीज़ गिराता है, और बचे हुए frontier में दोबारा enter होते हैं।
optimize करने से पहले contract को inspectable बनाइए: endpoints, entities, ownership, retries, और state.
QUEUEfrontier.enqueue(url, depth)
resaccepted · dropped (seen / filtered / budget से ऊपर)
Internal contract, REST नहीं — एक crawler का कोई public API नहीं होता। Enqueue पहले URL-seen filter और pattern filters से गुज़रता है।
QUEUEfrontier.lease(fetcher_id) → CrawlTask
restask with lease TTL · ack(task) on success · nack → retry with backoff
Per-host back-queues politeness enforce करती हैं: एक fetcher को एक URL तभी मिलता है जब उस host के token bucket में एक token हो।
GEThttps://{host}/robots.txt (external)
resrules DomainState में TTL के साथ cached
एकमात्र external contract: Disallow और crawl-delay का पालन करें, और एक ईमानदार User-Agent भेजें।
Core entities
CrawlTaskurl · domain · depth · status: queued/leased/done/failed · retries
काम की इकाई; जब एक fetcher इस पर काम करता है तब leased (delete नहीं) रहती है, इसलिए crashes ख़ुद ठीक हो जाते हैं।
DomainStatedomain (PK) · robots_rules · crawl_delay · last_fetch_at · pages_crawled
Robots rules प्रति domain एक TTL के साथ cached होते हैं; token bucket यहीं रहता है।
Pageurl · content_hash (SHA-256) · fetched_at · blob_ref
content_hash दूसरे dedup layer को शक्ति देता है — अलग URLs के नीचे एक जैसा content एक बार store होता है।
interview के आखिरी एक-तिहाई के लिए एक lane चुनें. हर lane आपको topic, वह interviewer सवाल जिसका जवाब देना है, और बचने वाला failure mode देती है.
frontier एक मामूली website के लिए दस लाख URLs रखता है। क्या गारंटी देता है कि उस host पर कभी हद से ज़्यादा दबाव न पड़े?
वे सारे URLs उस host के लिए एक ही queue में जाते हैं। site के crawl-delay से बंधा एक token bucket उन्हें एक-एक करके छोड़ता है, और fetchers बस उतना ही ले सकते हैं जितना bucket देता है। हज़ार machines जोड़ दो और उस host को फिर भी वही trickle दिखती है — इसे queue लागू करता है, कोई goodwill नहीं।
fetchers के भीतर rate-limiting — politeness structural होनी चाहिए, per-host queue में, वरना एक scaled-out fleet इसे तोड़ देता है।
दस अरब URLs — आप memory में प्रति enqueue 'पहले देखा?' का जवाब कैसे देते हैं, और यहाँ एक Bloom false positive की क्या कीमत है?
हर enqueue से पहले एक Bloom filter check करो। दस अरब URLs, हर एक करीब 10 bits पर, लगभग 12 GB में समा जाते हैं — exact strings के 400 GB के मुक़ाबले। यह कभी false negative नहीं देता, तो कुछ भी दो बार crawl नहीं होता। एक दुर्लभ false positive बस एक URL छोड़ देता है — चूकने की सुरक्षित दिशा।
false positive को एक error मानना — एक URL skip करना designed cost है; दो बार crawl करना failure है।
Mirrors, tracking parameters, और www/non-www सब एक जैसा content serve करते हैं। दूसरा dedup layer कहाँ बैठता है, और किस key पर?
दूसरी layer fetch के बाद बैठती है, एक content hash पर keyed। Page body को hash करो और उसे एक seen-hashes store में देखो। match होने पर, एक canonical copy रखो और दूसरे URL को एक alias के तौर पर record करो। Normalization tracking parameters और www variants संभालता है; अलग-अलग hosts से आए एक जैसे pages सिर्फ़ hash पकड़ता है।
अकेले URL normalization — सिर्फ़ एक content hash hosts के पार असली duplicates पकड़ता है।
एक site हमेशा के लिए एक valid 'next month' link बनाती रहती है। crawl को क्या सीमित करता है, और आप trap को कैसे detect करते हैं?
तीन bounds एक साथ लगते हैं: एक depth cap, एक per-domain page budget, और URL-pattern filters जो machine-made shapes को flag करते हैं, जैसे लगातार बढ़ती dates। असली पहचान budget करता है। जब एक छोटा domain हज़ारों लगभग एक जैसे pages फूँक डालता है, तो उसे throttle या cut off कर दिया जाता है — तो कोई अकेला trap पूरे crawl को नहीं खा सकता।
अकेले depth पर भरोसा — per-domain budgets और URL-pattern heuristics को इसका साथ देना होगा।
एक machine fetch के बीच crash होती है। इसके in-flight काम का क्या होता है, और recovery की क्या कीमत है?
कुछ भी नहीं खोता, क्योंकि हर URL lease पर दिया गया था, delete नहीं। जब मरी हुई machine acking बंद कर देती है, उसके 4,000 leases time out हो जाते हैं और URLs दूसरे fetchers के लिए वापस queue में चले जाते हैं। Recovery की कीमत बस lease-timeout delay है, साथ में जो in flight था उसे दोबारा fetch करना — bounded और सस्ता।
hand-out के समय queue से एक URL delete करना — timeout वाला lease लो, completion पर ack करो।
वेब क्रॉलर को ज़ोर से समझाइए और अपनी व्याख्या पर AI scoring पाइए.