LuaJIT क्या है? APISIX ने LuaJIT को क्यों चुना?
Tao Yang
April 14, 2023
क्या आप अपने API गेटवे गेम को अगले स्तर पर ले जाने के लिए तैयार हैं? तो आपको Apache APISIX पर ध्यान देना चाहिए, एक क्लाउड-नेटिव API गेटवे जो डेवलपर समुदाय में तहलका मचा रहा है। और भी दिलचस्प बात यह है कि Apache APISIX मुख्य रूप से LuaJIT का उपयोग करके बनाया गया है, एक हल्की और कुशल भाषा जो अपने समकक्षों की तरह प्रसिद्ध नहीं है।
इस लेख में, हम गहराई से देखेंगे कि Apache APISIX ने अधिक लोकप्रिय भाषाओं और तकनीकों के बजाय LuaJIT को क्यों चुना, और LuaJIT की अनूठी विशेषताओं और फायदों से आप कैसे ब्लेज़िंग-फास्ट API गेटवे बना सकते हैं जो सबसे मांग वाले वर्कलोड को भी संभाल सकते हैं। तो, यदि आप अपने API गेटवे को सुपरचार्ज करना चाहते हैं, तो पढ़ते रहें!
LuaJIT क्या है
परिभाषा
सरल शब्दों में, LuaJIT Lua प्रोग्रामिंग भाषा के लिए एक जस्ट-इन-टाइम (JIT) कंपाइलर का कार्यान्वयन है। बेहतर समझ के लिए, जो पाठक LuaJIT से अपरिचित हैं, वे इसे दो भागों में तोड़ सकते हैं: Lua और JIT।
Lua
Lua एक सुंदर और सीखने में आसान प्रोग्रामिंग भाषा है जिसमें स्वचालित मेमोरी प्रबंधन, पूर्ण लेक्सिकल स्कोपिंग, क्लोजर, इटरेटर, कोरोटीन्स, उचित टेल कॉल, और एसोसिएटिव एरेज़ का उपयोग करके व्यावहारिक डेटा हैंडलिंग शामिल है। Lua सिंटैक्स के बारे में अधिक पढ़ने के लिए, Getting Started With Lua पढ़ने के लिए आपका स्वागत है।
Lua को C या अन्य व्यापक रूप से उपयोग की जाने वाली प्रोग्रामिंग भाषाओं के साथ आसानी से एकीकृत करने के लिए डिज़ाइन किया गया है, जिससे डेवलपर्स उन भाषाओं की ताकतों का लाभ उठा सकते हैं। यह ऐसी विशेषताएं प्रदान करता है जो आमतौर पर C जैसी भाषाओं की मजबूत बिंदु नहीं होती हैं, जैसे हार्डवेयर के सापेक्ष उच्च-स्तरीय एब्स्ट्रक्शन, डायनामिक स्ट्रक्चर, और सरल परीक्षण। इसका छोटा भाषा कर्नेल और ANSI C मानक पर निर्भरता इसे विभिन्न प्लेटफॉर्म्स पर अत्यधिक पोर्टेबल बनाता है। परिणामस्वरूप, Lua न केवल एक स्टैंडअलोन प्रोग्राम के रूप में चलने वाली स्क्रिप्टिंग भाषा है, बल्कि यह एक एम्बेडेड भाषा भी है जिसे अन्य एप्लिकेशन्स में एकीकृत किया जा सकता है।

हालांकि, इस समय, Lua में अभी भी पारंपरिक स्क्रिप्टिंग भाषाओं में पाए जाने वाले दो सामान्य समस्याएं थीं: कम दक्षता और एक्सपोज़्ड कोड। LuaJIT द्वारा पेश की गई JIT तकनीक इन दोनों समस्याओं को प्रभावी ढंग से हल कर सकती है।
JIT
JIT (जस्ट-इन-टाइम कंपाइलेशन), डायनामिक कंपाइलेशन का एक रूप है। डायनामिक कंपाइलेशन कंप्यूटर विज्ञान में एकमात्र कंपाइलेशन का रूप नहीं है। उदाहरण के लिए, व्यापक रूप से उपयोग की जाने वाली C भाषा एक अलग प्रकार की कंपाइलेशन का उपयोग करती है, जिसे स्टैटिक कंपाइलेशन के रूप में जाना जाता है।
यह ध्यान रखना महत्वपूर्ण है कि जबकि हम अक्सर C में उपयोग की जाने वाली डायनामिक कंपाइलेशन के विपरीत का वर्णन करने के लिए Ahead-of-Time Compilation (AOT) शब्द का उपयोग करते हैं, ये दोनों पूरी तरह से समान नहीं हैं। AOT केवल प्रोग्राम को निष्पादित करने से पहले एक "उच्च-स्तरीय" भाषा को "निम्न-स्तरीय" भाषा में कंपाइल करने के व्यवहार का वर्णन करता है। इसकी कंपाइलेशन का लक्ष्य भाषा आवश्यक रूप से प्रोग्राम होस्ट मशीन के लिए विशिष्ट मशीन कोड नहीं है, बल्कि मनमाने ढंग से परिभाषित है। उदाहरण के लिए, Java को C में कंपाइल करना या JavaScript को V8 में कंपाइल करना भी AOT के रूप में माना जाएगा। चूंकि सभी स्टैटिक कंपाइलेशन तकनीकी रूप से समय से पहले निष्पादित की जाती है, इस विशिष्ट संदर्भ में, AOT को JIT के विपरीत स्टैटिक कंपाइलेशन के रूप में देखा जा सकता है।
इन जटिल शब्दों को छोड़कर, जब स्टैटिक कंपाइलेशन के आउटपुट पर विचार करते हैं, तो आप पा सकते हैं कि Lua भाषा द्वारा सामना की जाने वाली समस्याओं को स्टैटिक कंपाइलेशन द्वारा भी हल किया जा सकता है। हालांकि, इससे Lua के स्क्रिप्टिंग भाषा के रूप में प्रदान किए जाने वाले लाभ का नुकसान होगा: हॉट अपडेट की लचीलापन और अच्छी प्लेटफॉर्म संगतता। इसलिए, वर्तमान में, विशेष आवश्यकताओं वाली भाषाओं को छोड़कर, अधिकांश स्क्रिप्टिंग भाषाएं JIT का उपयोग करके भाषा प्रदर्शन को सुधारने का प्रयास कर रही हैं, जैसे कि Chromium प्लेटफॉर्म पर V8 का JavaScript और Ruby YJIT का उपयोग कर रहा है।
JIT Lua की डायनामिक इंटरप्रिटेशन और C की स्टैटिक कंपाइलेशन के फायदे और नुकसान को जोड़ने का प्रयास करता है। स्क्रिप्टिंग भाषा के निष्पादन के दौरान, JIT निष्पादित किए जा रहे कोड फ़्रैगमेंट्स का लगातार विश्लेषण करता है, और उन्हें कंपाइल या रीकंपाइल करके निष्पादन दक्षता में सुधार करता है। इस बिंदु पर, JIT के पीछे की धारणा यह है कि इस प्रक्रिया से प्राप्त प्रदर्शन लाभ कोड को कंपाइल या रीकंपाइल करने की लागत से अधिक होगा। सिद्धांत रूप में, चूंकि इसे डायनामिक रूप से रीकंपाइल किया जा सकता है, JIT चल रहे प्रोग्राम के आधार पर विशिष्ट प्लेटफॉर्म आर्किटेक्चर के लिए अनुकूलन और त्वरण कर सकता है, और कुछ मामलों में, स्टैटिक कंपाइलेशन से तेज़ निष्पादन गति प्रदान कर सकता है।
JIT दो प्रकारों में विभाजित है: पारंपरिक Method JIT और LuaJIT द्वारा वर्तमान में उपयोग किया जाने वाला Trace JIT। Method JIT प्रत्येक मेथड को मशीन कोड में अनुवाद करता है, जबकि Trace JIT, जो अधिक उन्नत है, यह मानता है कि "जो कोड केवल एक या दो बार निष्पादित होता है, उसके लिए इंटरप्रिटेड निष्पादन JIT कंपाइल्ड निष्पादन से तेज़ है"। इसके आधार पर, Trace JIT पारंपरिक JIT को अनुकूलित करता है, जो अक्सर निष्पादित होने वाले कोड फ़्रैगमेंट्स (यानी, हॉट पाथ पर कोड) की पहचान करता है और इस कोड को मशीन कोड में कंपाइल करके निष्पादित करता है, जैसा कि नीचे दिए गए चित्र में दिखाया गया है।

LuaJIT
LuaJIT (संस्करण 2.x) असेंबली भाषा में लिखे गए एक हाई-स्पीड इंटरप्रिटर और Static Single Assignment (SSA) पर आधारित एक अनुकूलित कोड जनरेटर बैकएंड को एकीकृत करके JIT प्रदर्शन में महत्वपूर्ण सुधार करता है। परिणामस्वरूप, LuaJIT सबसे तेज़ डायनामिक भाषा कार्यान्वयन में से एक बन गया है।
इसके अलावा, C इंटरैक्शन के लिए मूल Lua में Lua और C के बीच जटिल बाइंडिंग की तुलना में, LuaJIT ने FFI (Foreign Function Interface) भी लागू किया है। यह तकनीक हमें Lua कोड से सीधे बाहरी C फ़ंक्शन को कॉल करने और C डेटा स्ट्रक्चर का उपयोग करने की अनुमति देती है, बिना पैरामीटर की संख्या और प्रकार को जाने। इस सुविधा के साथ, हम प्रदर्शन-संवेदनशील परिदृश्यों में प्रोग्राम प्रदर्शन को और बेहतर बनाने के लिए मूल Lua Table प्रकार के बजाय FFI का उपयोग करके आवश्यक डेटा स्ट्रक्चर को सीधे लागू कर सकते हैं। FFI का उपयोग करके प्रदर्शन को सुधारने की तकनीकें इस लेख के दायरे से बाहर हैं, और अधिक गहराई से जानकारी के लिए आप Why Does lua-resty-core Perform Better? लेख पढ़ सकते हैं।
संक्षेप में, LuaJIT ने Lua सिंटैक्स का उपयोग करके स्क्रिप्टिंग भाषाओं में अब तक के सबसे तेज़ Trace JIT में से एक को लागू किया है। इसके अलावा, यह Lua की कम दक्षता और एक्सपोज़्ड कोड समस्याओं को हल करने के लिए FFI जैसी सुविधाएं प्रदान करता है, जिससे Lua एक अत्यधिक लचीली, उच्च-प्रदर्शन और अल्ट्रा-लो मेमोरी फुटप्रिंट वाली स्क्रिप्टिंग और एम्बेडेड भाषा बन जाती है।
WASM और अन्य भाषाओं से तुलना
Lua और LuaJIT की तुलना में, हम कुछ अन्य भाषाओं से अधिक परिचित हो सकते हैं, जैसे JavaScript (Node.js), Python, Golang, Java, आदि। Lua/LuaJIT की इन लोकप्रिय भाषाओं के साथ तुलना करके, हम LuaJIT की अनूठी विशेषताओं और फायदों को बेहतर ढंग से समझ सकते हैं। नीचे कुछ संक्षिप्त तुलनाएं दी गई हैं:
- Lua का सिंटैक्स गैर-सॉफ्टवेयर इंजीनियरों के लिए डिज़ाइन किया गया है। R भाषा की तरह, Lua में भी एरे इंडेक्स 1 से शुरू होता है, जो सामान्य लोगों के लिए उपयुक्त है।
- Lua एक एम्बेडेड भाषा के रूप में बहुत उपयुक्त है। Lua में ही एक हल्का VM है, और LuaJIT विभिन्न सुविधाओं और अनुकूलन को जोड़ने के बाद भी हल्का है। परिणामस्वरूप, LuaJIT का आकार C प्रोग्राम में सीधे एकीकृत करने पर भी बहुत अधिक नहीं बढ़ता है, जैसे कि Node.js और Python जैसे बड़े रनटाइम वातावरण। इस प्रकार, Lua वास्तव में सभी एम्बेडेड भाषाओं में सबसे व्यापक रूप से उपयोग की जाने वाली और मुख्यधारा वाली पसंद है।
- Lua एक "ग्लू" भाषा के रूप में भी बहुत उपयुक्त है। JavaScript (Node.js) और Python की तरह, Lua भी विभिन्न लाइब्रेरीज़ और कोड को बहुत अच्छी तरह से जोड़ सकता है। हालांकि, अन्य भाषाओं से थोड़ा अलग, Lua का अंतर्निहित इकोसिस्टम के साथ अधिक युग्मन होता है, इसलिए Lua इकोसिस्टम विभिन्न क्षेत्रों में सार्वभौमिक नहीं हो सकता है।
WASM (वेब असेंबली) एक उभरती हुई क्रॉस-प्लेटफॉर्म तकनीक है। यह तकनीक, जो शुरू में JavaScript को प्रतिस्थापित करने के बजाय पूरक करने के लिए डिज़ाइन की गई थी, अन्य भाषाओं को WASM बाइटकोड में कंपाइल कर सकती है और कोड को एक सुरक्षित सैंडबॉक्स के रूप में चला सकती है, जिससे अधिक से अधिक प्रोग्राम WASM को एक एम्बेडेड या "ग्लू" प्लेटफॉर्म के रूप में उपयोग करने पर विचार कर रहे हैं। फिर भी, Lua/LuaJIT की तुलना में उभरती हुई WASM के साथ अभी भी कई फायदे हैं:
- WASM का प्रदर्शन सीमित है और असेंबली के स्तर तक नहीं पहुंच सकता है। सामान्य परिदृश्यों में, WASM निश्चित रूप से Lua की तुलना में प्रदर्शन में बेहतर है, लेकिन WASM और LuaJIT के बीच अभी भी एक अंतर है।
- WASM और होस्ट प्रोग्राम के बीच डेटा ट्रांसमिशन दक्षता अपेक्षाकृत कम है। दूसरी ओर, LuaJIT FFI के माध्यम से कुशल डेटा ट्रांसमिशन कर सकता है।
Apache APISIX ने LuaJIT को क्यों चुना?
हालांकि LuaJIT के कई फायदे ऊपर वर्णित किए गए हैं, Lua न तो एक लोकप्रिय भाषा है और न ही अधिकांश डेवलपर्स के लिए एक लोकप्रिय विकल्प। तो फिर Apache APISIX, Apache Foundation के तहत एक क्लाउड-नेटिव API गेटवे, ने LuaJIT को क्यों चुना?
एक क्लाउड-नेटिव API गेटवे के रूप में, Apache APISIX में डायनामिक, रियल-टाइम, और उच्च-प्रदर्शन की विशेषताएं हैं, जो लोड बैलेंसिंग, डायनामिक अपस्ट्रीम, कैनरी रिलीज़, सर्विस डिग्रेडेशन, पहचान प्रमाणीकरण, ऑब्जर्वेबिलिटी जैसे समृद्ध ट्रैफिक प्रबंधन कार्य प्रदान करता है। हम Apache APISIX का उपयोग करके पारंपरिक उत्तर-दक्षिण ट्रैफिक को संभाल सकते हैं, साथ ही सेवाओं के बीच पूर्व-पश्चिम ट्रैफिक को भी, और यह k8s के लिए एक Ingress कंट्रोलर के रूप में भी काम कर सकता है।
ये सभी Apache APISIX द्वारा चुने गए NGINX और LuaJIT टेक्नोलॉजी स्टैक पर बनाए गए हैं।
LuaJIT और NGINX को जोड़ने के फायदे
NGINX एक प्रसिद्ध उच्च-प्रदर्शन वेब सर्वर है जो HTTP, TCP/UDP प्रॉक्सी और रिवर्स प्रॉक्सी के रूप में कार्य करता है।
हालांकि, व्यवहार में, हमें यह परेशान करने वाला लगता है कि हर बार जब हम NGINX कॉन्फ़िगरेशन फ़ाइल को संशोधित करते हैं, तो हमें NGINX कॉन्फ़िगरेशन को रीलोड करने के लिए nginx -s reload कमांड का उपयोग करना पड़ता है।
इसके अलावा, इस कमांड का बार-बार उपयोग करके कॉन्फ़िगरेशन को रीलोड करने से कनेक्शन अस्थिरता हो सकती है और व्यापारिक नुकसान की संभावना बढ़ सकती है। कुछ मामलों में, NGINX कॉन्फ़िगरेशन रीलोडिंग मैकेनिज्म के कारण पुराने प्रक्रियाओं को रिक्लेम होने में बहुत अधिक समय लग सकता है, जिससे सामान्य व्यापारिक संचालन प्रभावित हो सकता है। इस विषय पर अधिक व्यापक विश्लेषण के लिए, हम Why NGINX's reload is not a hot reload? लेख पढ़ने की सलाह देते हैं। हम यहां इस विषय पर और अधिक विस्तार से नहीं जाएंगे।
Apache APISIX का एक उद्देश्य NGINX की डायनामिक कॉन्फ़िगरेशन समस्या को हल करना है। LuaJIT की उच्च लचीलापन, उच्च प्रदर्शन, और अल्ट्रा-लो मेमोरी उपयोग इसे संभव बनाता है। सबसे सामान्य रूट के उदाहरण के रूप में, Apache APISIX NGINX कॉन्फ़िगरेशन फ़ाइल में केवल एक सिंगल लोकेशन को मुख्य प्रवेश बिंदु के रूप में कॉन्फ़िगर करता है, और बाद के रूट वितरण को APISIX के रूट वितरण मॉड्यूल द्वारा पूरा किया जाता है, जिससे रूट की डायनामिक कॉन्फ़िगरेशन प्राप्त होती है।
उच्च प्रदर्शन प्राप्त करने के लिए, Apache APISIX C में लिखे गए एक प्रीफिक्स ट्री-आधारित रूट-मिलान एल्गोरिदम का उपयोग करता है, और इसके आधार पर, यह LuaJIT द्वारा प्रदान किए गए FFI का उपयोग करके Lua के लिए एक इंटरफ़ेस प्रदान करता है। Lua की लचीलापन Apache APISIX के रूट वितरण मॉड्यूल को विशिष्ट एक्सप्रेशन और अन्य तरीकों से एक ही प्रीफिक्स के अधीन रूट के मिलान को आसानी से समर्थन करने में सक्षम बनाता है। अंततः, NGINX के मूल रूट वितरण फ़ंक्शन को प्रतिस्थापित करके, यह उच्च प्रदर्शन और लचीलापन के साथ डायनामिक कॉन्फ़िगरेशन कार्यक्षमता प्राप्त करता है। इस सुविधा के विस्तृत कार्यान्वयन के लिए, आप lua-resty-radixtree और route.lua देख सकते हैं।
रूटिंग के अलावा, APISIX बैलेंसिंग, हेल्थ चेक, अपस्ट्रीम नोड कॉन्फ़िगरेशन, सर्वर सर्टिफिकेट, और APISIX क्षमताओं को विस्तारित करने वाले प्लगइन जैसे फ़ंक्शन को सर्वर को रीस्टार्ट किए बिना रीलोड कर सकता है।
इसके अलावा, LuaJIT का उपयोग करके प्लगइन और अन्य सुविधाओं को विकसित करने के अलावा, Apache APISIX Java, Go, Node, Python, और WASM जैसी विभिन्न भाषाओं का उपयोग करके प्लगइन विकसित करने का भी समर्थन करता है। इससे Apache APISIX के कस्टम विकास की दहलीज काफी कम हो जाती है, जिसके परिणामस्वरूप एक समृद्ध प्लगइन इकोसिस्टम और एक सक्रिय ओपन-सोर्स समुदाय बनता है।

निष्कर्ष
LuaJIT Lua का एक कार्यान्वयन है, एक जस्ट-इन-टाइम कंपाइलर।
एक डायनामिक, रियल-टाइम, उच्च-प्रदर्शन ओपन-सोर्स API गेटवे के रूप में, Apache APISIX NGINX और LuaJIT द्वारा लाए गए उच्च प्रदर्शन और उच्च लचीलापन के आधार पर लोड बैलेंसिंग, डायनामिक अपस्ट्रीम, कैनरी रिलीज़, सर्किट ब्रेकर, पहचान प्रमाणीकरण, और ऑब्जर्वेबिलिटी जैसे समृद्ध ट्रैफिक प्रबंधन कार्य प्रदान करता है।
वर्तमान में, Apache APISIX ने एक नया संस्करण, 3.x, जारी किया है, जिसमें ओपन-सोर्स प्रोजेक्ट्स और क्लाउड प्रदाताओं के साथ अधिक एकीकरण, नेटिव gRPC समर्थन, अतिरिक्त प्लगइन विकास विकल्प, और सर्विस मेश समर्थन शामिल है। Apache APISIX समुदाय में शामिल हों और क्लाउड-नेटिव API गेटवे में LuaJIT के अनुप्रयोग के बारे में अधिक जानें।