Geyser gRPC - Best practices

यह गाइड Geyser gRPC के साथ मज़बूत, production के लिए तैयार applications बनाने के ज़रूरी patterns बताती है। Solana Stream SDK, Geyser gRPC को support करता है।

शुरुआत

  • सरल शुरुआत करें: जटिल filters जोड़ने से पहले streaming को समझने के लिए slot subscriptions से शुरू करें।
  • Filters समझदारी से इस्तेमाल करें: bandwidth/CPU कम करने के लिए केवल उसी चीज़ को subscribe करें जिसकी आपको ज़रूरत है।
rust
SubscribeRequestFilterTransactions {
    vote: Some(false),   // Exclude vote txs
    failed: Some(false), // Exclude failed txs
    ..Default::default()
}

Connection प्रबंधन

  • अपने-आप reconnection: नेटवर्क की समस्याओं की उम्मीद रखें; exponential backoff के साथ reconnect करें।
  • Ping/pong handling: Yellowstone gRPC servers ping भेजते हैं। हमेशा pong से जवाब दें, वरना server connection बंद कर सकता है (~30 सेकंड में disconnect होने की आम वजह)।
rust
if matches!(update.update_oneof, Some(UpdateOneof::Ping(_))) {
    subscribe_tx.send(SubscribeRequest {
        ping: Some(SubscribeRequestPing { id: 1 }),
        ..Default::default()
    }).await?;
}
  • Gap recovery: data खोने से बचने के लिए reconnect करने के बाद from_slot इस्तेमाल करें (duplicates स्वीकार्य हैं)।
rust
subscribe_request.from_slot = if tracked_slot > 0 {
    Some(tracked_slot) // Optionally subtract a small buffer to dodge reorgs
} else {
    None
};

वास्तुकला पैटर्न

  • Network IO को business logic से अलग करने और backpressure जोड़ने के लिए, ingress और processing को channels से अलग रखें।
rust
let (tx, rx) = mpsc::channel::<SubscribeUpdate>(10_000);
// ingress task reads stream and tx.send(...)
// processing task consumes rx and does business logic
  • Bounded channels इस्तेमाल करें: processing की गति और data-loss सहन करने की सीमा के आधार पर क्षमता चुनें (छोटा = कम memory, ज़्यादा drops; बड़ा = ज़्यादा memory, कम drops)।

Performance और resiliency

  • Processing विलंबता पर नज़र रखें और सीमा पार होने पर log करें।
  • DB writes को batch में करें; batch size या interval पूरा होने पर flush करें।
  • बाहरी calls के लिए async IO इस्तेमाल करें; भारी computation को worker tasks/threads पर डालें।
  • Allocations कम करने के लिए subscription requests को दोबारा इस्तेमाल करें।

त्रुटि हैंडलिंग

  • Error के प्रकारों को अलग पहचानें (stream, processing और channel)।
  • अमान्य request को retry करने से पहले ठीक करें; pause को ध्यान में रखने वाला exponential backoff केवल तब इस्तेमाल करें जब response retry की माँग करे।
  • Slow-consumer की स्थितियों पर नज़र रखने के लिए drop हुए updates को log/metric में दर्ज करें।

Retry से पहले सुधार और pause को ध्यान में रखने वाला backoff

Reconnect loop के उसे बदल देने से पहले पहला gRPC error सँभालकर रखें। उसका status और message दर्ज करें, साथ ही जो भी x-erpc-error-code, x-erpc-error-reason, x-erpc-doc-url, x-erpc-retry-after-seconds और x-erpc-retry-at metadata मौजूद हो। Connection जल्दी बंद होने पर वह एक सामान्य transport error जैसा दिख सकता है, इसलिए उसमें हर trailer मौजूद न हो, ऐसा हो सकता है।
Retry करने से पहले अमान्य request, अस्वीकार किए गए filter shape या IP registration के mismatch को ठीक करें। ERPC pause होने पर लौटाई गई deadline तक प्रतीक्षा करें; यह local backoff से ज़्यादा सटीक है। Availability failures और retry किए जा सकने वाले दूसरे responses के लिए सीमित exponential backoff इस्तेमाल करें। सिर्फ़ इसलिए कि non-zero status लौटा, बिना बदले request को बार-बार retry न करें।

Resource उपयोग और processing क्षमता

Shared सुरक्षा व्यवस्थाएँ किसी एक workload को उस delivery क्षमता का उपभोग करने से रोकती हैं जिसकी ज़रूरत दूसरे ERPC customers को होती है। कोई stream प्रभावी bandwidth, CPU, memory, consumer queue, database writes या बाहरी calls की वजह से धीमा हो सकता है। पर्याप्त resources का workload से मेल खाना ज़रूरी है; केवल धीमा receiver यह नहीं बताता कि कौन-सा हिस्सा सीमित है।
Consumer पर peak data rate मापें। MB/s × 8 से MB/s को Mbps में बदलें, फिर मापे गए peak से ऊपर headroom छोड़ें। बिना मापे तय कोई न्यूनतम मान नहीं है। Receive का काम छोटा रखें, updates को bounded queue में भेजें, और अगर processing साथ नहीं दे पा रही हो तो scale करें या subscription घटाएँ। Bounded queue memory के उपयोग को सीमित करती है; लगातार धीमे consumer की समस्या वह हल नहीं कर सकती।

Data प्रबंधन

  • from_slot इस्तेमाल करते समय duplicates को संभालें (समय-सीमित cache या DB constraints)।
  • उपयोग के अनुसार commitment चुनें:
    • processed: सबसे तेज़ dashboards के लिए, roll back हो सकता है
    • confirmed: ज़्यादातर apps/indexers के लिए अच्छा default
    • finalized: जब पूरी निश्चितता चाहिए

गतिशील सदस्यता

Reconnect किए बिना runtime पर subscriptions बदलने के लिए bidirectional stream इस्तेमाल करें (filters को hot-swap करना, कवरेज बढ़ाना)।

उत्पादन चेकलिस्ट

  • ✅ Exponential backoff के साथ अपने-आप reconnection
  • ✅ from_slot से gap recovery
  • ✅ Ping/pong handling (30 सेकंड वाले disconnects से बचाव)
  • ✅ Bounded channels/backpressure के साथ ingress और processing को अलग रखना
  • ✅ Error logging और metrics/alerting
  • ✅ Processing विलंबता की ट्रैकिंग
  • ✅ Duplicate handling और filter optimization
  • ✅ Batch writes (अगर data persist किया जा रहा हो)
  • ✅ Graceful shutdown और health checks

अतिरिक्त संसाधन