"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > काउचगो! - गो में लिखे गए क्वेरी सर्वर के साथ CouchDB को बढ़ाना

काउचगो! - गो में लिखे गए क्वेरी सर्वर के साथ CouchDB को बढ़ाना

2024-08-06 को प्रकाशित
ब्राउज़ करें:407

CouchGO! — Enhancing CouchDB with Query Server Written in Go

पिछले महीने से, मैं CouchDB से संबंधित प्रूफ-ऑफ-कॉन्सेप्ट परियोजनाओं पर सक्रिय रूप से काम कर रहा हूं, इसकी विशेषताओं की खोज कर रहा हूं और भविष्य के कार्यों की तैयारी कर रहा हूं। इस अवधि के दौरान, मैंने यह सुनिश्चित करने के लिए कि सब कुछ कैसे काम करता है, CouchDB दस्तावेज़ का कई बार अध्ययन किया है। दस्तावेज़ पढ़ते समय, मुझे एक बयान मिला कि जावास्क्रिप्ट में लिखे डिफ़ॉल्ट क्वेरी सर्वर के साथ CouchDB शिपिंग के बावजूद, एक कस्टम कार्यान्वयन बनाना अपेक्षाकृत सरल है और कस्टम समाधान पहले से ही मौजूद हैं।

मैंने कुछ त्वरित शोध किया और कार्यान्वयन को पायथन, रूबी या क्लोजर में लिखा हुआ पाया। चूंकि संपूर्ण कार्यान्वयन बहुत लंबा नहीं लग रहा था, इसलिए मैंने अपना स्वयं का कस्टम क्वेरी सर्वर लिखने का प्रयास करके CouchDB के साथ प्रयोग करने का निर्णय लिया। ऐसा करने के लिए, मैंने गो को भाषा के रूप में चुना। हेल्म के चार्ट में गो टेम्प्लेट का उपयोग करने के अलावा, मुझे पहले इस भाषा के साथ ज्यादा अनुभव नहीं था, लेकिन मैं कुछ नया आज़माना चाहता था और सोचा कि यह प्रोजेक्ट इसके लिए एक शानदार अवसर होगा।

क्वेरी सर्वर को समझना

काम शुरू करने से पहले, मैंने यह समझने के लिए कि क्वेरी सर्वर वास्तव में कैसे काम करता है, CouchDB दस्तावेज़ को एक बार फिर से देखा। दस्तावेज़ीकरण के अनुसार, क्वेरी सर्वर का उच्च-स्तरीय अवलोकन काफी सरल है:

क्वेरी सर्वर एक बाहरी प्रक्रिया है जो एक stdio इंटरफ़ेस पर JSON प्रोटोकॉल के माध्यम से CouchDB के साथ संचार करता है और सभी डिज़ाइन फ़ंक्शन कॉल को संभालता है…।

CouchDB द्वारा क्वेरी सर्वर पर भेजे गए कमांड की संरचना को [, ] या ["ddoc", , [, ], [के रूप में व्यक्त किया जा सकता है। डिज़ाइन दस्तावेज़ों के मामले में , , …]]।

तो मूल रूप से, मुझे जो करना था वह STDIO से इस प्रकार के JSON को पार्स करने, अपेक्षित संचालन करने और दस्तावेज़ में निर्दिष्ट प्रतिक्रियाओं को वापस करने में सक्षम एक एप्लिकेशन लिखना था। गो कोड में कमांड की एक विस्तृत श्रृंखला को संभालने के लिए कई प्रकार की कास्टिंग शामिल थी। प्रत्येक कमांड के बारे में विशिष्ट विवरण दस्तावेज़ के क्वेरी सर्वर प्रोटोकॉल अनुभाग के अंतर्गत पाया जा सकता है।

एक समस्या जिसका मुझे यहां सामना करना पड़ा वह यह थी कि क्वेरी सर्वर को डिज़ाइन दस्तावेज़ों में प्रदान किए गए मनमाने कोड की व्याख्या और निष्पादन करने में सक्षम होना चाहिए। यह जानते हुए कि गो एक संकलित भाषा है, मुझे इस बिंदु पर फंसने की उम्मीद थी। शुक्र है, मुझे तुरंत येगी पैकेज मिल गया, जो आसानी से गो कोड की व्याख्या करने में सक्षम है। यह एक सैंडबॉक्स बनाने और व्याख्या किए गए कोड में कौन से पैकेज आयात किए जा सकते हैं, इसकी पहुंच को नियंत्रित करने की अनुमति देता है। मेरे मामले में, मैंने केवल काउचगो नामक अपने पैकेज को उजागर करने का निर्णय लिया, लेकिन अन्य मानक पैकेज भी आसानी से जोड़े जा सकते हैं।

काउचगो का परिचय!

मेरे काम के परिणामस्वरूप, काउचगो नामक एक एप्लिकेशन! उभरा। हालाँकि यह क्वेरी सर्वर प्रोटोकॉल का पालन करता है, यह जावास्क्रिप्ट संस्करण का एक-से-एक पुन: कार्यान्वयन नहीं है क्योंकि डिज़ाइन दस्तावेज़ कार्यों को संभालने के लिए इसके अपने दृष्टिकोण हैं।

उदाहरण के लिए, CouchGO! में, एमिट जैसा कोई सहायक कार्य नहीं है। मान उत्सर्जित करने के लिए, आप बस उन्हें मानचित्र फ़ंक्शन से वापस कर दें। इसके अतिरिक्त, डिज़ाइन दस्तावेज़ में प्रत्येक फ़ंक्शन एक ही पैटर्न का पालन करता है: इसमें केवल एक तर्क होता है, जो फ़ंक्शन-विशिष्ट गुणों वाला एक ऑब्जेक्ट होता है, और परिणामस्वरूप केवल एक मान लौटाना होता है। इस मान का आदिम होना आवश्यक नहीं है; फ़ंक्शन के आधार पर, यह एक ऑब्जेक्ट, एक मानचित्र या एक त्रुटि भी हो सकती है।

CouchGO! के साथ काम करना शुरू करने के लिए, आपको बस मेरे GitHub रिपॉजिटरी से निष्पादन योग्य बाइनरी डाउनलोड करना होगा, इसे CouchDB इंस्टेंस में कहीं रखना होगा, और एक पर्यावरण चर जोड़ना होगा जो CouchDB को CouchGO शुरू करने की अनुमति देता है! प्रक्रिया।

उदाहरण के लिए, यदि आप काउचगो निष्पादन योग्य को /opt/couchdb/bin निर्देशिका में रखते हैं, तो आप इसे काम करने में सक्षम करने के लिए निम्नलिखित पर्यावरण चर जोड़ेंगे।

export COUCHDB_QUERY_SERVER_GO="/opt/couchdb/bin/couchgo"

CouchGO के साथ लेखन कार्य!

काउचगो के साथ फ़ंक्शन लिखने के तरीके की त्वरित समझ हासिल करने के लिए, आइए निम्नलिखित फ़ंक्शन इंटरफ़ेस का पता लगाएं:

func Func(args couchgo.FuncInput) couchgo.FuncOutput { ... }

काउचगो में प्रत्येक फ़ंक्शन! इस पैटर्न का अनुसरण करेगा, जहां Func को उपयुक्त फ़ंक्शन नाम से बदल दिया गया है। वर्तमान में, काउचगो! निम्नलिखित फ़ंक्शन प्रकारों का समर्थन करता है:

  • नक्शा
  • कम करना
  • फ़िल्टर
  • अद्यतन
  • मान्य करें (validate_doc_update)

आइए एक उदाहरण डिज़ाइन दस्तावेज़ की जांच करें जो मानचित्र और कम कार्यों के साथ-साथ एक मान्य_doc_update फ़ंक्शन के साथ एक दृश्य निर्दिष्ट करता है। इसके अतिरिक्त, हमें यह निर्दिष्ट करने की आवश्यकता है कि हम भाषा के रूप में गो का उपयोग कर रहे हैं।

{
  "_id": "_design/ddoc-go",
  "views": {
    "view": {
      "map": "func Map(args couchgo.MapInput) couchgo.MapOutput {\n\tout := couchgo.MapOutput{}\n\tout = append(out, [2]interface{}{args.Doc[\"_id\"], 1})\n\tout = append(out, [2]interface{}{args.Doc[\"_id\"], 2})\n\tout = append(out, [2]interface{}{args.Doc[\"_id\"], 3})\n\t\n\treturn out\n}",
      "reduce": "func Reduce(args couchgo.ReduceInput) couchgo.ReduceOutput {\n\tout := 0.0\n\n\tfor _, value := range args.Values {\n\t\tout  = value.(float64)\n\t}\n\n\treturn out\n}"
    }
  },
  "validate_doc_update": "func Validate(args couchgo.ValidateInput) couchgo.ValidateOutput {\n\tif args.NewDoc[\"type\"] == \"post\" {\n\t\tif args.NewDoc[\"title\"] == nil || args.NewDoc[\"content\"] == nil {\n\t\t\treturn couchgo.ForbiddenError{Message: \"Title and content are required\"}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif args.NewDoc[\"type\"] == \"comment\" {\n\t\tif args.NewDoc[\"post\"] == nil || args.NewDoc[\"author\"] == nil || args.NewDoc[\"content\"] == nil {\n\t\t\treturn couchgo.ForbiddenError{Message: \"Post, author, and content are required\"}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif args.NewDoc[\"type\"] == \"user\" {\n\t\tif args.NewDoc[\"username\"] == nil || args.NewDoc[\"email\"] == nil {\n\t\t\treturn couchgo.ForbiddenError{Message: \"Username and email are required\"}\n\t\t}\n\n\t\treturn nil\n\t}\n\n\treturn couchgo.ForbiddenError{Message: \"Invalid document type\"}\n}",
  "language": "go"
}

अब, मानचित्र फ़ंक्शन से शुरू होने वाले प्रत्येक फ़ंक्शन को तोड़ें:

func Map(args couchgo.MapInput) couchgo.MapOutput {
  out := couchgo.MapOutput{}
  out = append(out, [2]interface{}{args.Doc["_id"], 1})
  out = append(out, [2]interface{}{args.Doc["_id"], 2})
  out = append(out, [2]interface{}{args.Doc["_id"], 3})

  return out
}

CouchGO! में, कोई उत्सर्जन फ़ंक्शन नहीं है; इसके बजाय, आप कुंजी-मूल्य टुपल्स का एक टुकड़ा लौटाते हैं जहां कुंजी और मूल्य दोनों किसी भी प्रकार के हो सकते हैं। दस्तावेज़ ऑब्जेक्ट को जावास्क्रिप्ट की तरह सीधे फ़ंक्शन में पास नहीं किया जाता है; बल्कि, यह किसी वस्तु में लिपटा हुआ है। दस्तावेज़ स्वयं विभिन्न मूल्यों का एक हैशमैप मात्र है।

अगला, आइए कम फ़ंक्शन की जांच करें:

func Reduce(args couchgo.ReduceInput) couchgo.ReduceOutput {
  out := 0.0
  for _, value := range args.Values {
    out  = value.(float64)
  }
  return out
}

जावास्क्रिप्ट के समान, काउचगो में रिड्यूस फ़ंक्शन! कुंजियाँ, मान और एक पुनः कम करने वाला पैरामीटर लेता है, सभी को एक ही ऑब्जेक्ट में लपेटा जाता है। इस फ़ंक्शन को किसी भी प्रकार का एकल मान लौटाना चाहिए जो कमी ऑपरेशन के परिणाम का प्रतिनिधित्व करता है।

अंत में, आइए वैलिडेट फ़ंक्शन को देखें, जो वैलिडेट_डॉक_अपडेट प्रॉपर्टी से मेल खाता है:

func Validate(args couchgo.ValidateInput) couchgo.ValidateOutput {
  if args.NewDoc["type"] == "post" {
    if args.NewDoc["title"] == nil || args.NewDoc["content"] == nil {
      return couchgo.ForbiddenError{Message: "Title and content are required"}
    }

    return nil
  }

  if args.NewDoc["type"] == "comment" {
    if args.NewDoc["post"] == nil || args.NewDoc["author"] == nil || args.NewDoc["content"] == nil {
      return couchgo.ForbiddenError{Message: "Post, author, and content are required"}
    }

    return nil
  }

  return nil
}

इस फ़ंक्शन में, हमें नए दस्तावेज़, पुराने दस्तावेज़, उपयोगकर्ता संदर्भ और सुरक्षा ऑब्जेक्ट जैसे पैरामीटर प्राप्त होते हैं, सभी एक फ़ंक्शन तर्क के रूप में पारित एक ऑब्जेक्ट में लपेटे जाते हैं। यहां, हमसे अपेक्षा की जाती है कि हम सत्यापित करें कि क्या दस्तावेज़ को अद्यतन किया जा सकता है और यदि नहीं तो एक त्रुटि लौटाएँ। जावास्क्रिप्ट संस्करण के समान, हम दो प्रकार की त्रुटियाँ लौटा सकते हैं: ForbiddenError या UnauthorizedError। यदि दस्तावेज़ अद्यतन किया जा सकता है, तो हमें शून्य लौटना चाहिए।

अधिक विस्तृत उदाहरणों के लिए, वे मेरे GitHub रिपॉजिटरी में पाए जा सकते हैं। ध्यान देने योग्य एक महत्वपूर्ण बात यह है कि फ़ंक्शन नाम मनमाने नहीं हैं; उन्हें हमेशा उस फ़ंक्शन के प्रकार से मेल खाना चाहिए जिसका वे प्रतिनिधित्व करते हैं, जैसे मानचित्र, रिड्यूस, फ़िल्टर, आदि।

काउचगो! प्रदर्शन

हालाँकि अपना स्वयं का क्वेरी सर्वर लिखना वास्तव में एक मजेदार अनुभव था, अगर मैं मौजूदा समाधानों के साथ इसकी तुलना नहीं करता तो इसका कोई मतलब नहीं होता। इसलिए, मैंने यह जांचने के लिए डॉकर कंटेनर में कुछ सरल परीक्षण तैयार किए कि काउचगो कितना तेज़ है! कर सकना:

  • सूचकांक 100k दस्तावेज़ (CouchDB में अनुक्रमण का अर्थ है दृश्यों से मानचित्र कार्यों को निष्पादित करना)
  • 100k दस्तावेज़ों के लिए रिड्यूस फ़ंक्शन निष्पादित करें
  • 100k दस्तावेज़ों के लिए फ़िल्टर परिवर्तन फ़ीड
  • 1k अनुरोधों के लिए अद्यतन फ़ंक्शन निष्पादित करें

मैंने डेटाबेस को दस्तावेज़ों की अपेक्षित संख्या के साथ जोड़ा और समर्पित शेल स्क्रिप्ट का उपयोग करके डॉकर कंटेनर से प्रतिक्रिया समय या विभेदित टाइमस्टैम्प लॉग को मापा। कार्यान्वयन का विवरण मेरे GitHub रिपॉजिटरी में पाया जा सकता है। परिणाम नीचे दी गई तालिका में प्रस्तुत किए गए हैं।

परीक्षा काउचगो! काउचजेएस बढ़ाना
अनुक्रमण 141.713s 421.529s 2.97x
कम करना 7672 एमएस 15642 एमएस 2.04x
फ़िल्टरिंग 28.928s 80.594s 2.79x
अपडेट किया जा रहा है 7.742s 9.661s 1.25x

जैसा कि आप देख सकते हैं, जावास्क्रिप्ट कार्यान्वयन पर वृद्धि महत्वपूर्ण है: अनुक्रमण के मामले में लगभग तीन गुना तेज, कम करने और फ़िल्टर कार्यों के लिए दोगुने से अधिक तेज। अपडेट फ़ंक्शंस के लिए बूस्ट अपेक्षाकृत छोटा है, लेकिन फिर भी जावास्क्रिप्ट से तेज़ है।

निष्कर्ष

जैसा कि दस्तावेज़ के लेखक ने वादा किया था, क्वेरी सर्वर प्रोटोकॉल का पालन करते समय एक कस्टम क्वेरी सर्वर लिखना उतना कठिन नहीं था। हालांकि काउचगो! सामान्य तौर पर इसमें कुछ अप्रचलित कार्यों का अभाव है, यह विकास के इस प्रारंभिक चरण में भी जावास्क्रिप्ट संस्करण पर एक महत्वपूर्ण बढ़ावा प्रदान करता है। मेरा मानना ​​है कि अभी भी सुधार की काफी गुंजाइश है।

यदि आपको इस लेख के सभी कोड एक ही स्थान पर चाहिए, तो आप इसे मेरे GitHub रिपॉजिटरी में पा सकते हैं।

इस आलेख को पढ़ने के लिए धन्यवाद। मुझे इस समाधान के बारे में आपके विचार सुनना अच्छा लगेगा। क्या आप इसे अपने CouchDB इंस्टेंस के साथ उपयोग करेंगे, या हो सकता है कि आप पहले से ही कुछ कस्टम-निर्मित क्वेरी सर्वर का उपयोग कर रहे हों? मुझे टिप्पणियों में इसके बारे में सुनकर खुशी होगी।

अधिक युक्तियों, अंतर्दृष्टियों और इस श्रृंखला के अन्य भागों के निर्माण के लिए मेरे अन्य लेखों को देखना न भूलें। हैप्पी हैकिंग!

विज्ञप्ति वक्तव्य यह आलेख यहां पुन: प्रस्तुत किया गया है: https://dev.to/kishieel/couchgo-enhancing-couchdb-with-query-server-writing-in-go-304n?1 यदि कोई उल्लंघन है, तो कृपया स्टडी_गोलंग@163.com पर संपर्क करें। इसे हटाने के लिए
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3