द्वारा आंद्रेई चेर्निकोव
Redis अंतर-प्रक्रिया संचार और डेटा स्टोरेज के लिए उपयोग किया जाने वाला एक लोकप्रिय इन-मेमोरी ग्रिड है। आपने सुना होगा कि यह आपको Lua स्क्रिप्ट चलाने देता है, लेकिन आप अभी भी निश्चित नहीं हैं कि क्यों। अगर यह आपकी तरह लगता है, तो पढ़ते रहें।
पूर्वापेक्षाएँ
इस गाइड का पालन करने के लिए आपके सिस्टम पर Redis इंस्टॉल होना चाहिए। पढ़ते समय Redis कमांड रेफरेंस जांचना मददगार हो सकता है।
मुझे Lua स्क्रिप्ट की आवश्यकता क्यों है?
संक्षेप में: प्रदर्शन लाभ। Redis में आपके द्वारा किए जाने वाले अधिकांश कार्यों में कई चरण शामिल होते हैं। अपने एप्लिकेशन की भाषा में इन चरणों को करने के बजाय, आप इसे Lua के साथ Redis के अंदर कर सकते हैं।
- इसके परिणामस्वरूप बेहतर प्रदर्शन हो सकता है।
- साथ ही, एक स्क्रिप्ट के भीतर सभी चरण एक एटॉमिक तरीके से निष्पादित होते हैं। जब एक स्क्रिप्ट चल रही होती है तो कोई अन्य Redis कमांड नहीं चल सकती।
उदाहरण के लिए, मैं Redis में स्टोर JSON स्ट्रिंग्स को बदलने के लिए Lua स्क्रिप्ट का उपयोग करता हूं। मैं इस लेख के अंत के करीब इसका विस्तार से वर्णन करता हूं।
लेकिन मुझे Lua नहीं आती
एक व्यक्ति जिसे कोई Lua नहीं आती
चिंता न करें, Lua समझना बहुत कठिन नहीं है। यदि आप C परिवार की किसी भाषा को जानते हैं, तो आपको Lua के साथ ठीक होना चाहिए। साथ ही, मैं इस लेख में काम करने वाले उदाहरण प्रदान कर रहा हूं।
मुझे एक उदाहरण दिखाएं
आइए redis-cli के माध्यम से स्क्रिप्ट चलाकर शुरू करें। इसे इसके साथ शुरू करें:
redis-cli
अब निम्न कमांड चलाएं:
eval "redis.call('set', KEYS[1], ARGV[1])" 1 key:name value
EVAL कमांड वही है जो Redis को उसके बाद आने वाली स्क्रिप्ट चलाने के लिए कहता है। स्ट्रिंग "redis.call('set', KEYS[1], ARGV[1])" हमारी स्क्रिप्ट है जो कार्यात्मक रूप से Redis के set कमांड के समान है। स्क्रिप्ट टेक्स्ट के बाद तीन पैरामीटर आते हैं:
- प्रदान की गई कीज़ की संख्या
- की नाम
- पहला आर्गुमेंट
स्क्रिप्ट आर्गुमेंट दो समूहों में आते हैं: KEYS और ARGV।
हम स्क्रिप्ट के तुरंत बाद की संख्या के साथ निर्दिष्ट करते हैं कि स्क्रिप्ट को कितनी कीज़ की आवश्यकता है। हमारे उदाहरण में, यह 1 है। इस संख्या के तुरंत बाद, हमें इन कीज़ को एक के बाद एक प्रदान करने की आवश्यकता है। वे स्क्रिप्ट के भीतर KEYS टेबल के रूप में सुलभ हैं। हमारे मामले में, इसमें इंडेक्स 1 पर एक सिंगल वैल्यू key:name है।
नोट करें, कि Lua इंडेक्स्ड टेबल इंडेक्स 1 से शुरू होते हैं, 0 से नहीं।
हम कीज़ के बाद किसी भी संख्या में आर्गुमेंट प्रदान कर सकते हैं, जो Lua में ARGV टेबल के रूप में उपलब्ध होंगे। इस उदाहरण में, हम एक सिंगल ARGV-आर्गुमेंट प्रदान करते हैं: स्ट्रिंग value। जैसा कि आप पहले ही अनुमान लगा चुके हैं, उपरोक्त कमांड की key:name को वैल्यू value पर सेट करता है।
यह एक अच्छी प्रैक्टिस मानी जाती है कि स्क्रिप्ट द्वारा उपयोग की जाने वाली कीज़ को KEYS के रूप में प्रदान करें, और अन्य सभी आर्गुमेंट को ARGV के रूप में। इसलिए आपको KEYS को 0 के रूप में निर्दिष्ट नहीं करना चाहिए और फिर सभी कीज़ को ARGV टेबल के भीतर प्रदान करना चाहिए।
आइए अब जांचें कि क्या स्क्रिप्ट सफलतापूर्वक पूरी हुई। हम एक और स्क्रिप्ट चलाकर ऐसा करने जा रहे हैं जो Redis से की प्राप्त करती है:
eval "return redis.call('get', KEYS[1])" 1 key:name
आउटपुट "value" होना चाहिए, जिसका अर्थ है कि पिछली स्क्रिप्ट ने की "key:name" को सफलतापूर्वक सेट कर दिया।
क्या आप स्क्रिप्ट को समझा सकते हैं?
ऊपर दी गई स्क्रिप्ट देखने के बाद डोज
हमारी पहली स्क्रिप्ट में एक सिंगल स्टेटमेंट होता है: redis.call फंक्शन:
redis.call('set', KEYS[1], ARGV[1])
redis.call के साथ आप किसी भी Redis कमांड को निष्पादित कर सकते हैं। पहला आर्गुमेंट इस कमांड का नाम है जिसके बाद इसके पैरामीटर्स आते हैं। set कमांड के मामले में, ये आर्गुमेंट की और वैल्यू हैं। सभी Redis कमांड सपोर्टेड हैं। डॉक्यूमेंटेशन के अनुसार:
Redis सभी कमांड चलाने के लिए एक ही Lua इंटरप्रेटर का उपयोग करता है
हमारी दूसरी स्क्रिप्ट सिर्फ एक कमांड चलाने से थोड़ा अधिक करती है — यह एक वैल्यू भी लौटाती है:
eval "return redis.call('get', KEYS[1])" 1 key:name
स्क्रिप्ट द्वारा लौटाई गई हर चीज कॉलिंग प्रोसेस को भेजी जाती है। हमारे मामले में, यह प्रोसेस redis-cli है और आप अपने टर्मिनल विंडो में परिणाम देखेंगे।
कुछ अधिक जटिल?
एक जटिल Redis स्क्रिप्ट बनाने की योजना बना रहा व्यक्ति
मैंने एक बार Lua स्क्रिप्ट का उपयोग एक हैश मैप से तत्वों को एक विशेष क्रम में लौटाने के लिए किया था। क्रम स्वयं एक सॉर्टेड सेट में स्टोर हैश कीज़ द्वारा निर्दिष्ट किया गया था।
आइए पहले इन कमांड्स को redis-cli में चलाकर अपना डेटा सेट करें:
hmset hkeys key:1 value:1 key:2 value:2 key:3 value:3 key:4 value:4 key:5 value:5 key:6 value:6
zadd order 1 key:3 2 key:1 3 key:2
ये कमांड hkeys की पर एक हैश मैप और order की पर एक सॉर्टेड सेट बनाते हैं जिसमें hkeys से चयनित कीज़ एक विशिष्ट क्रम में होती हैं।
आप विवरण के लिए hmset और zadd कमांड रेफरेंस जांचना चाह सकते हैं।
आइए निम्न स्क्रिप्ट चलाएं:
eval "local order = redis.call('zrange', KEYS[1], 0, -1); return redis.call('hmget', KEYS[2], unpack(order));" 2 order hkeys
आपको निम्न आउटपुट देखना चाहिए:
"value:3" "value:1" "value:2"
जिसका अर्थ है कि हमें उन कीज़ के वैल्यू मिल गए जो हम चाहते थे और सही क्रम में।
क्या मुझे इसे चलाने के लिए पूरा स्क्रिप्ट टेक्स्ट निर्दिष्ट करना होगा?
नहीं! Redis आपको SCRIPT LOAD कमांड के साथ एक स्क्रिप्ट को मेमोरी में प्रीलोड करने की अनुमति देता है:
script load "return redis.call('get', KEYS[1])"
आपको ऐसा आउटपुट देखना चाहिए:
"4e6d8fc8bb01276962cce5371fa795a7763657ae"
यह स्क्रिप्ट का यूनिक हैश है जिसे आपको स्क्रिप्ट चलाने के लिए EVALSHA कमांड को प्रदान करने की आवश्यकता है:
evalsha 4e6d8fc8bb01276962cce5371fa795a7763657ae 1 key:name
नोट: आपको SCRIPT LOAD कमांड द्वारा लौटाए गए वास्तविक SHA1 हैश का उपयोग करना चाहिए, ऊपर दिया गया हैश केवल एक उदाहरण है।
आपने JSON बदलने के बारे में क्या उल्लेख किया था?
कभी-कभी लोग Redis में JSON ऑब्जेक्ट स्टोर करते हैं। चाहे यह एक अच्छा विचार है या नहीं यह एक और कहानी है, लेकिन व्यवहार में, यह बहुत होता है।
यदि आपको इस JSON ऑब्जेक्ट में एक की बदलनी है, तो आपको इसे Redis से प्राप्त करना होगा, इसे पार्स करना होगा, की बदलनी होगी, फिर सीरियलाइज़ करके वापस Redis में सेट करना होगा। इस दृष्टिकोण के साथ कुछ समस्याएं हैं:
- कॉन्करेंसी। एक अन्य प्रक्रिया हमारे get और set ऑपरेशन के बीच इस JSON को बदल सकती है। इस मामले में, परिवर्तन खो जाएगा।
- प्रदर्शन। यदि आप ये परिवर्तन अक्सर करते हैं और यदि ऑब्जेक्ट काफी बड़ा है, तो यह आपके ऐप का बॉटलनेक बन सकता है। आप इस लॉजिक को Lua में लागू करके कुछ प्रदर्शन जीत सकते हैं।
आइए एक टेस्ट JSON स्ट्रिंग को obj की के तहत Redis में जोड़ें:
set obj '{"a":"foo","b":"bar"}'
अब आइए हमारी स्क्रिप्ट चलाएं:
EVAL 'local obj = redis.call("get",KEYS[1]); local obj2 = string.gsub(obj,"(" .. ARGV[1] .. "\":)([^,}]+)", "%1" .. ARGV[2]); return redis.call("set",KEYS[1],obj2);' 1 obj b bar2
अब हमारे पास obj की के तहत निम्न ऑब्जेक्ट होगा:
{"a":"foo","b":"bar2"}
आप इसके बजाय इस स्क्रिप्ट को SCRIPT LOAD कमांड के साथ लोड कर सकते हैं:
SCRIPT LOAD 'local obj = redis.call("get",KEYS[1]); local obj2 = string.gsub(obj,"(" .. ARGV[1] .. "\":)([^,}]+)", "%1" .. ARGV[2]); return redis.call("set",KEYS[1],obj2);'
और फिर इसे इस तरह चलाएं:
EVALSHA <your_script_sha> 1 obj b bar2
कुछ नोट्स:
..Lua में स्ट्रिंग कन्कैटनेशन ऑपरेटर है।- हम की से मिलान करने और उसके वैल्यू को बदलने के लिए एक RegEx पैटर्न का उपयोग करते हैं। यदि आप इस रेगुलर एक्सप्रेशन को नहीं समझते हैं, तो आप मेरा हालिया गाइड देख सकते हैं।
- Lua RegEx फ्लेवर का अधिकांश अन्य फ्लेवर से एक अंतर यह है कि हम RegEx विशेष प्रतीकों के लिए बैकरेफरेंस मार्क और एस्केप कैरेक्टर दोनों के रूप में
%का उपयोग करते हैं। - हम अभी भी
"को\के साथ और%के साथ नहीं बचाते हैं क्योंकि हम Lua स्ट्रिंग डिलीमीटर को एस्केप कर रहे हैं, न कि RegEx विशेष प्रतीक को।
क्या मुझे हमेशा Lua स्क्रिप्ट का उपयोग करना चाहिए?
नहीं। मैं केवल उनका उपयोग करने की सलाह देता हूं जब आप साबित कर सकते हैं कि इसका परिणाम बेहतर प्रदर्शन में होता है। हमेशा पहले बेंचमार्क चलाएं।
यदि आप केवल एटॉमिसिटी चाहते हैं, तो आपको Redis ट्रांजैक्शन की जांच करनी चाहिए।
साथ ही, आपकी स्क्रिप्ट बहुत लंबी नहीं होनी चाहिए। याद रखें कि जब एक स्क्रिप्ट चल रही होती है, तो बाकी सब इसके खत्म होने का इंतजार कर रहे होते हैं। यदि आपकी स्क्रिप्ट को कुछ समय लगता है, तो यह प्रदर्शन सुधारने के बजाय बॉटलनेक पैदा कर सकती है। स्क्रिप्ट डिफ़ॉल्ट रूप से 5 सेकंड का टाइमआउट होने पर रुक जाती है।
Redis स्क्रिप्ट को बहुत अधिक समय नहीं लेना चाहिए
अंतिम शब्द
Lua पर अधिक जानकारी के लिए lua.org देखें।
आप मेरे node.js लाइब्रेरी को GitHub पर Lua स्क्रिप्ट के कुछ उदाहरणों के लिए देख सकते हैं (src/lua फोल्डर देखें)। आप इस लाइब्रेरी का उपयोग node.js में किसी भी Lua स्क्रिप्ट को लिखे बिना JSON ऑब्जेक्ट बदलने के लिए भी कर सकते हैं।
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
इस लेख को पढ़ने के लिए धन्यवाद। प्रश्न और टिप्पणियां बहुत सराहनीय हैं। आप मुझे ट्विटर पर फॉलो करने के लिए भी स्वागत हैं।
मुफ़्त में कोड करना सीखें। freeCodeCamp का ओपन सोर्स पाठ्यक्रम 40,000 से अधिक लोगों को डेवलपर के रूप में नौकरी पाने में मदद कर चुका है। शुरू करें