- उच्च-प्रदर्शन वेब सर्वर बनाने के लिए पहले select(), poll(), epoll जैसे विभिन्न event-based मॉडल इस्तेमाल किए जाते थे
- लेकिन इन system call की performance सीमाओं के कारण io_uring आया, जिसने request को queue में डालकर kernel द्वारा asynchronous processing की विधि अपनाई
- kTLS में kernel TLS encryption processing संभालता है, जिससे sendfile() के उपयोग की संभावना और hardware offloading जैसी अतिरिक्त optimization संभव हो जाती है
- Descriptorless files के परिचय से file descriptor को सीधे पास किए बिना io_uring के लिए optimized access तरीका मिलता है
- Rust, io_uring, kTLS को जोड़ने वाले tarweb open source project के जरिए प्रति-request अतिरिक्त system call के बिना HTTPS उपलब्ध कराया जाता है, और safety व memory management से जुड़े मुद्दों पर भी चर्चा होती है
उच्च-प्रदर्शन वेब सर्वर आर्किटेक्चर का विकास
- 2000 के शुरुआती दशक से high-volume web server की मांग बढ़ी
- शुरुआत में हर request के लिए नया process बनाने का तरीका आम था, लेकिन इसकी ऊंची लागत के कारण preforking तकनीक सामने आई
- इसके बाद thread का उपयोग और select(), poll() के सक्रिय इस्तेमाल के जरिए context switching लागत कम करने की दिशा में विकास हुआ
- लेकिन select() और poll() में भी connection बढ़ने पर kernel को बार-बार बड़े array देने पड़ते हैं, इसलिए scalability की सीमा मौजूद रहती है
epoll का आगमन
- Linux environment में epoll आने से पुराने तरीकों की तुलना में multi-connection handling अधिक efficient हो गया
- epoll केवल बदलावों (delta) को process करता है, जिससे अनावश्यक resource consumption कम होता है
- सभी system call पूरी तरह खत्म नहीं होते, लेकिन लागत काफी कम हो जाती है
io_uring का अवलोकन
- io_uring में हर request पर system call करने के बजाय request को memory queue में जोड़ा जाता है ताकि kernel उसे asynchronous तरीके से process कर सके
- उदाहरण के लिए, accept() को queue में डाल देने पर kernel उसे process करके completion queue में result लौटाता है
- web server queue में request जोड़ता है और result को अलग memory area में जांचता है
- busy loop से बचने के लिए, queue में बदलाव न होने पर web server और kernel दोनों केवल जरूरत पड़ने पर ही system call करते हैं, जिससे power saving का लाभ मिलता है
- उपयुक्त library का उपयोग करने पर, active server request processing के दौरान अलग system call के बिना काम कर सकता है
multi-core और NUMA environment
- आधुनिक CPU के multi-core environment को देखते हुए प्रति-core single thread चलाना और data structure sharing को न्यूनतम करना प्रभावी रणनीति है
- NUMA environment में प्रत्येक thread केवल अपने local node memory तक पहुंचकर optimization करता है
- request distribution का पूर्ण संतुलन अभी अतिरिक्त शोध का विषय है
memory allocation
- kernel और web server दोनों में memory allocation बना रहता है, और user space में allocation भी अंततः system call से जुड़ता है
- web server की ओर से प्रति-connection fixed-size memory block पहले से allocate करके fragmentation और shortage की समस्या रोकी जाती है
- kernel की ओर भी प्रति-connection I/O buffer चाहिए, जिसे socket option आदि से कुछ हद तक समायोजित किया जा सकता है
- memory shortage होने पर गंभीर failure हो सकता है
kTLS (kernel TLS) परिचय
- kTLS Linux kernel में encryption और decryption operations संभालने वाली सुविधा है
- handshake application में process होता है, लेकिन उसके बाद kernel data transfer को plain text की तरह संभालता है
- sendfile() का उपयोग संभव हो जाता है, जिससे user-kernel space के बीच memory copy कम होती है
- अगर network card समर्थन दे, तो encryption operation को hardware पर offload करने का लाभ भी मिलता है
Descriptorless Files
- user space से kernel space तक file descriptor सीधे पहुंचाने पर होने वाले overhead को कम करने के लिए यह तरीका आया
- register_files का उपयोग कर io_uring के लिए ही मान्य अलग 'integer' file number इस्तेमाल किया जाता है, जो /proc/pid/fd में दिखाई नहीं देता
- system का ulimit limit फिर भी लागू रहता है
tarweb project परिचय
- tarweb ऊपर की सभी तकनीकों को लागू करने वाला एक example web server open source project है
- यह single tar file की सामग्री serve करने वाली संरचना है, जिसमें Rust, io_uring, kTLS जैसी आधुनिक high-performance तकनीकें जुड़ी हैं
- वास्तविक उपयोग के दौरान io_uring और kTLS की compatibility समस्याएं (जैसे setsockopt support न होना) थीं, जिनमें से कुछ issues को Pull Request के जरिए हल किया गया
- project अभी अधूरा है, और Rust की rustls library handshake प्रक्रिया में memory allocation कर सकती है
- मुख्य बात यह है कि प्रति request अतिरिक्त system call के बिना HTTPS service संभव है
benchmark और performance measurement
- लेखक ने अभी पर्याप्त benchmark नहीं किए हैं, और code को व्यवस्थित करने के बाद performance test करने की योजना है
io_uring और Rust की safety समस्याएं
- synchronous system call से अलग, io_uring में completion event आने तक memory buffer को release नहीं किया जाना चाहिए
- io-uring crate Rust की compile-time safety की guarantee नहीं देता, और runtime check भी पर्याप्त नहीं हैं
- गलत उपयोग होने पर C++ जैसी गंभीर समस्याएं हो सकती हैं, जिससे Rust की मूल safety कमजोर पड़ती है
- pinning और borrow checker का सक्रिय उपयोग करने वाला अलग safer-ring crate आवश्यक है
- इस मुद्दे पर community में पहले से चर्चा चल रही है
संदर्भ और अतिरिक्त लिंक
- यह सामग्री 2025-08-22 के अनुसार HackerNews में चर्चा किए गए पोस्ट पर आधारित है
अभी कोई टिप्पणी नहीं है.