paint-brush
PostgreSQL डेटा के लिए एक मजबूत वेक्टर एंबेडिंग क्रिएशन सिस्टम का आर्किटेक्चरद्वारा@timescale
8,028 रीडिंग
8,028 रीडिंग

PostgreSQL डेटा के लिए एक मजबूत वेक्टर एंबेडिंग क्रिएशन सिस्टम का आर्किटेक्चर

द्वारा Timescale16m2023/11/14
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

"PgVectorizer की दुनिया में प्रवेश करें, जो PostgreSQL तालिकाओं में डेटा को निर्बाध रूप से एम्बेड करने के लिए एक अत्याधुनिक समाधान है। सरलता, लचीलापन और उच्च प्रदर्शन सुनिश्चित करने के लिए किए गए जटिल तकनीकी डिजाइन निर्णयों और ट्रेड-ऑफ के बारे में जानें। यह प्रणाली, टाइमस्केल से सुसज्जित है वेक्टर पायथन लाइब्रेरी, डेवलपर्स को डेटा को सहजता से सिंक्रोनाइज़ और अपडेट करने का अधिकार देती है, जो सिमेंटिक सर्च से लेकर जेनरेटिव एआई तक, पोस्टग्रेएसक्यूएल पर निर्भर अनुप्रयोगों में दक्षता का एक नया स्तर लाती है।"
featured image - PostgreSQL डेटा के लिए एक मजबूत वेक्टर एंबेडिंग क्रिएशन सिस्टम का आर्किटेक्चर
Timescale HackerNoon profile picture


PostgreSQL तालिका में संग्रहीत डेटा को एंबेड करना निस्संदेह उपयोगी है - सिमेंटिक खोज और अनुशंसा प्रणालियों से लेकर जेनरेटिव एआई अनुप्रयोगों और पुनर्प्राप्ति संवर्धित पीढ़ी तक के अनुप्रयोगों के साथ। लेकिन PostgreSQL तालिकाओं में डेटा के लिए एम्बेडिंग बनाना और प्रबंधित करना मुश्किल हो सकता है, जिसमें कई विचारों और किनारे के मामलों को ध्यान में रखना शामिल है, जैसे टेबल अपडेट और डिलीट के साथ एम्बेडिंग को अद्यतित रखना, विफलताओं के खिलाफ लचीलापन सुनिश्चित करना, और मौजूदा सिस्टम पर निर्भर प्रभाव टेबल।


पिछले ब्लॉग पोस्ट में, हमने एम्बेडिंग बनाने और प्रबंधित करने की प्रक्रिया पर चरण-दर-चरण मार्गदर्शिका विस्तृत की थी PostgreSQL में मौजूद डेटा का उपयोग करने के लिए पीजीवेक्टराइज़र - PostgreSQL में मौजूद डेटा के लिए हमारी सरल और लचीली एम्बेडिंग निर्माण प्रणाली। उदाहरण के तौर पर PostgreSQL डेटाबेस में संग्रहीत डेटा के साथ एक ब्लॉग एप्लिकेशन का उपयोग करते हुए, हमने पायथन, लैंगचेन और टाइमस्केल वेक्टर का उपयोग करके अद्यतित वेक्टर एम्बेडिंग बनाने और रखने का तरीका बताया।


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


आइए इसमें कूदें।

PostgreSQL डेटा (PgVectorizer) के लिए एक उच्च-प्रदर्शन वेक्टराइज़र का डिज़ाइन

सबसे पहले, आइए बताएं कि हम जो सिस्टम बना रहे हैं वह कैसे काम करेगा। यदि आप पहले ही पढ़ चुके हैं तो बेझिझक इस अनुभाग को छोड़ दें पीजीवेक्टराइज़र पोस्ट .


तंत्र अवलोकन

एक उदाहरण के रूप में, हम निम्नानुसार परिभाषित तालिका का उपयोग करके PostgreSQL में डेटा संग्रहीत करने वाले एक सरल ब्लॉग एप्लिकेशन का उपयोग करेंगे:


 CREATE TABLE blog ( id SERIAL PRIMARY KEY NOT NULL, title TEXT NOT NULL, author TEXT NOT NULL, contents TEXT NOT NULL, category TEXT NOT NULL, published_time TIMESTAMPTZ NULL --NULL if not yet published );


हम ब्लॉग पोस्ट की सामग्री पर एम्बेडिंग बनाना चाहते हैं ताकि हम बाद में इसका उपयोग सिमेंटिक खोज और पावर पुनर्प्राप्ति संवर्धित पीढ़ी के लिए कर सकें। एंबेडिंग केवल उन्हीं ब्लॉगों के लिए मौजूद होनी चाहिए और खोज योग्य होनी चाहिए जो प्रकाशित हो चुके हैं (जहां published_time NOT NULL है)।


इस एम्बेडिंग सिस्टम का निर्माण करते समय, हम कई लक्ष्यों की पहचान करने में सक्षम थे जो एम्बेडिंग बनाने वाले किसी भी सीधे और लचीले सिस्टम में होने चाहिए:


  • मूल तालिका में कोई संशोधन नहीं. यह उन सिस्टमों और अनुप्रयोगों को अनुमति देता है जो पहले से ही इस तालिका का उपयोग करते हैं, एम्बेडिंग सिस्टम में परिवर्तनों से प्रभावित नहीं होते हैं। यह विरासत प्रणालियों के लिए विशेष रूप से महत्वपूर्ण है।


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


  • जब स्रोत तालिका में पंक्तियाँ बदलती हैं (इस मामले में, ब्लॉग तालिका) तो एम्बेडिंग को स्वचालित रूप से अपडेट करें । यह रखरखाव के बोझ को कम करता है और चिंता मुक्त सॉफ़्टवेयर में योगदान देता है। साथ ही, इस अद्यतन को तत्काल या उसी प्रतिबद्धता के भीतर होने की आवश्यकता नहीं है। अधिकांश प्रणालियों के लिए, "अंतिम स्थिरता" ठीक है।


  • नेटवर्क और सेवा विफलताओं के खिलाफ लचीलापन सुनिश्चित करें: अधिकांश सिस्टम ओपनएआई एपीआई जैसे बाहरी सिस्टम पर कॉल के माध्यम से एम्बेडिंग उत्पन्न करते हैं। ऐसे परिदृश्यों में जहां बाहरी सिस्टम बंद है, या नेटवर्क में खराबी आती है, यह जरूरी है कि आपके डेटाबेस सिस्टम का शेष काम करता रहे।


ये दिशानिर्देश एक मजबूत वास्तुकला का आधार थे जिसे हमने इसका उपयोग करके लागू किया था टाइमस्केल वेक्टर पायथन लाइब्रेरी , PostgreSQL का उपयोग करके वेक्टर डेटा के साथ काम करने के लिए एक लाइब्रेरी। कार्य को सफलतापूर्वक पूरा करने के लिए, इस लाइब्रेरी में नई कार्यक्षमता जोड़ी गई- पीजीवेक्टराइज़र - PostgreSQL डेटा को एम्बेड करना यथासंभव सरल बनाना।


यहां वह वास्तुकला है जिस पर हमने निर्णय लिया है:


मौजूदा PostgreSQL तालिका में डेटा एम्बेड करने के लिए एक सरल और लचीली प्रणाली के लिए संदर्भ वास्तुकला। हम ब्लॉगिंग एप्लिकेशन के उदाहरण उपयोग के मामले का उपयोग करते हैं, इसलिए ऊपर दी गई तालिका के नाम।


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


एक निश्चित शेड्यूल पर, एक एम्बेडिंग निर्माता कार्य blog_work_queue तालिका का सर्वेक्षण करेगा, और यदि उसे करने के लिए काम मिलता है, तो वह एक लूप में निम्नलिखित कार्य करेगा:


  • blog_work_queue तालिका में एक पंक्ति पढ़ें और लॉक करें
  • ब्लॉग तालिका में संबंधित पंक्ति पढ़ें
  • ब्लॉग पंक्ति में डेटा के लिए एक एम्बेडिंग बनाएं
  • एम्बेडिंग को blog_embedding तालिका में लिखें
  • blog_work_queue तालिका में लॉक की गई पंक्ति हटाएँ


इस प्रणाली को क्रियाशील देखने के लिए, इसके उपयोग का एक उदाहरण देखें इस ब्लॉग पोस्ट में OpenAI, LangChain और Timescale वेक्टर का उपयोग करके PostgreSQL तालिका में एम्बेडिंग बनाएं और बनाए रखें .


हमारे ब्लॉग एप्लिकेशन तालिका के उदाहरण पर वापस जाएं, तो उच्च स्तर पर, PgVectorizer को दो काम करने होंगे:


  • यह जानने के लिए कि कौन सी पंक्तियाँ बदल गई हैं, ब्लॉग पंक्तियों में परिवर्तनों को ट्रैक करें।


  • एम्बेडिंग बनाने के लिए परिवर्तनों को संसाधित करने की एक विधि प्रदान करें।


इन दोनों को अत्यधिक समवर्ती और निष्पादक होना चाहिए। आइए देखें कि यह कैसे काम करता है।


blog_work_queue तालिका के साथ ब्लॉग तालिका में परिवर्तन को ट्रैक करें

आप निम्नलिखित के साथ एक सरल कार्य कतार तालिका बना सकते हैं:


 CREATE TABLE blog_embedding_work_queue ( id INT ); CREATE INDEX ON blog_embedding_work_queue(id);


यह एक बहुत ही सरल तालिका है, लेकिन एक बात ध्यान देने योग्य है: इस तालिका में कोई अद्वितीय कुंजी नहीं है। कतार को संसाधित करते समय लॉकिंग समस्याओं से बचने के लिए ऐसा किया गया था, लेकिन इसका मतलब यह है कि हमारे पास डुप्लिकेट हो सकते हैं। हम नीचे वैकल्पिक 1 में बाद में ट्रेड-ऑफ़ पर चर्चा करते हैं।


फिर आप blog में किए गए किसी भी परिवर्तन को ट्रैक करने के लिए एक ट्रिगर बनाते हैं:


 CREATE OR REPLACE FUNCTION blog_wq_for_embedding() RETURNS TRIGGER LANGUAGE PLPGSQL AS $$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO blog_embedding_work_queue VALUES (OLD.id); ELSE INSERT INTO blog_embedding_work_queue VALUES (NEW.id); END IF; RETURN NULL; END; $$; CREATE TRIGGER track_changes_for_embedding AFTER INSERT OR UPDATE OR DELETE ON blog FOR EACH ROW EXECUTE PROCEDURE blog_wq_for_embedding(); INSERT INTO blog_embedding_work_queue SELECT id FROM blog WHERE published_time is NOT NULL;


ट्रिगर उस ब्लॉग की आईडी सम्मिलित करता है जो blog_work_queue में बदल गई है। हम ट्रिगर स्थापित करते हैं और फिर किसी भी मौजूदा ब्लॉग को वर्क_क्यू में सम्मिलित करते हैं। यह आदेश यह सुनिश्चित करने के लिए महत्वपूर्ण है कि कोई भी आईडी छूट न जाए।


अब, आइए कुछ वैकल्पिक डिज़ाइनों का वर्णन करें और हमने उन्हें क्यों अस्वीकार कर दिया।


विकल्प 1: blog_work_queue तालिका के लिए एक प्राथमिक या अद्वितीय कुंजी लागू करें।

इस कुंजी के आने से डुप्लिकेट प्रविष्टियों की समस्या समाप्त हो जाएगी। हालाँकि, यह अपनी चुनौतियों के बिना नहीं है, विशेष रूप से क्योंकि ऐसी कुंजी हमें तालिका में नई आईडी डालने के लिए INSERT…ON CONFLICT DO NOTHING क्लॉज का उपयोग करने के लिए मजबूर करेगी, और वह क्लॉज बी-ट्री में आईडी पर लॉक लगा देता है।


यहां दुविधा है: प्रसंस्करण चरण के दौरान, एक साथ प्रसंस्करण को रोकने के लिए जिन पंक्तियों पर काम किया जा रहा है उन्हें हटाना आवश्यक है। फिर भी, यह विलोपन केवल तभी किया जा सकता है जब संबंधित एम्बेडिंग को blog_embeddings में रखा गया हो। यह सुनिश्चित करता है कि यदि बीच में कोई व्यवधान होता है तो कोई भी आईडी खो न जाए - मान लीजिए, यदि एम्बेडिंग निर्माण हटाने के बाद लेकिन एम्बेडिंग लिखे जाने से पहले क्रैश हो जाता है।


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


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


वैकल्पिक 2: अप-टू-डेट एम्बेडिंग मौजूद है या नहीं, यह ट्रैक करने के लिए ब्लॉग तालिका में एक कॉलम जोड़कर उस कार्य को ट्रैक करें जिसे करने की आवश्यकता है।

उदाहरण के लिए, हम एक embedded बूलियन कॉलम को संशोधन पर गलत पर सेट कर सकते हैं और एम्बेडिंग बनने पर सत्य पर फ़्लिप कर सकते हैं। इस डिज़ाइन को अस्वीकार करने के तीन कारण हैं:

  • हम ऊपर बताए गए कारणों से blog तालिका को संशोधित नहीं करना चाहते हैं।


  • गैर-एम्बेडेड ब्लॉगों की सूची कुशलतापूर्वक प्राप्त करने के लिए ब्लॉग तालिका पर एक अतिरिक्त सूचकांक (या आंशिक सूचकांक) की आवश्यकता होगी। इससे अन्य कार्य धीमे हो जाएंगे।


  • इससे मेज पर मंथन बढ़ जाता है क्योंकि PostgreSQL की MVCC प्रकृति के कारण प्रत्येक संशोधन अब दो बार लिखा जाएगा (एक बार एम्बेडिंग = गलत और एक बार एम्बेडिंग = सही के साथ)।


एक अलग वर्क_क्यू_टेबल इन समस्याओं का समाधान करती है।


विकल्प 3: सीधे ट्रिगर में एंबेडिंग्स बनाएं।

इस दृष्टिकोण में कई मुद्दे हैं:


  • यदि एम्बेडिंग सेवा बंद है, तो या तो ट्रिगर को विफल करने की आवश्यकता है (आपके लेनदेन को निरस्त करना), या आपको एक बैकअप कोड पथ बनाने की आवश्यकता है जो ... उन आईडी को संग्रहीत करता है जिन्हें कतार में एम्बेड नहीं किया जा सकता है। बाद वाला समाधान हमें हमारे प्रस्तावित डिज़ाइन पर वापस ले जाता है लेकिन शीर्ष पर अधिक जटिलता के साथ।


  • बाहरी सेवा से संपर्क करने के लिए आवश्यक विलंबता के कारण यह ट्रिगर संभवतः बाकी डेटाबेस परिचालनों की तुलना में बहुत धीमा होगा। यह टेबल पर आपके बाकी डेटाबेस संचालन को धीमा कर देगा।


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


अब हमारे पास उन ब्लॉगों की एक सूची है जिन्हें एम्बेड करने की आवश्यकता है, आइए सूची पर कार्रवाई करें!


एम्बेडिंग बनाएं

एम्बेडिंग बनाने के कई तरीके हैं. हम बाहरी पायथन स्क्रिप्ट का उपयोग करने की अनुशंसा करते हैं। यह स्क्रिप्ट कार्य कतार और संबंधित ब्लॉग पोस्ट को स्कैन करेगी, एम्बेडिंग तैयार करने के लिए एक बाहरी सेवा शुरू करेगी, और फिर इन एम्बेडिंग को वापस डेटाबेस में संग्रहीत करेगी। इस रणनीति के लिए हमारा तर्क इस प्रकार है:


  • पायथन का विकल्प : हम पायथन की अनुशंसा करते हैं क्योंकि यह एआई डेटा कार्यों के लिए एक समृद्ध, बेजोड़ पारिस्थितिकी तंत्र प्रदान करता है, जो शक्तिशाली एलएलएम विकास और डेटा लाइब्रेरीज़ द्वारा हाइलाइट किया गया है। लैंगचेन और लामाइंडेक्स।


  • पीएल/पायथन के बजाय एक बाहरी स्क्रिप्ट का विकल्प : हम चाहते थे कि उपयोगकर्ताओं का इस पर नियंत्रण हो कि वे अपने डेटा को कैसे एम्बेड करते हैं। फिर भी, एक ही समय में, कई पोस्टग्रेज़ क्लाउड प्रदाता सुरक्षा चिंताओं के कारण डेटाबेस के अंदर मनमाने पायथन कोड के निष्पादन की अनुमति नहीं देते हैं। इसलिए, उपयोगकर्ताओं को उनकी एम्बेडिंग स्क्रिप्ट के साथ-साथ जहां वे अपने डेटाबेस को होस्ट करते हैं, दोनों में लचीलेपन की अनुमति देने के लिए, हमने एक ऐसा डिज़ाइन तैयार किया जिसमें बाहरी पायथन स्क्रिप्ट का उपयोग किया गया।


कार्य निष्पादक और समवर्ती-सुरक्षित दोनों होने चाहिए। कॉनकरेंसी गारंटी देती है कि यदि नौकरियां पीछे चलने लगती हैं, तो सिस्टम को पकड़ने और लोड को संभालने में मदद करने के लिए शेड्यूलर अधिक नौकरियां शुरू कर सकते हैं।


हम बाद में जानेंगे कि उनमें से प्रत्येक विधि को कैसे सेट किया जाए, लेकिन पहले, आइए देखें कि पायथन लिपि कैसी दिखेगी। मौलिक रूप से, स्क्रिप्ट के तीन भाग हैं:


  • कार्य कतार और ब्लॉग पोस्ट पढ़ें

  • ब्लॉग पोस्ट के लिए एक एम्बेडिंग बनाएं

  • एम्बेडिंग को blog_embedding तालिका में लिखें


चरण 2 और 3 एक embed_and_write कॉलबैक द्वारा निष्पादित किए जाते हैं जिसे हम परिभाषित करते हैं पीजीवेक्टराइज़र ब्लॉग पोस्ट . तो, आइए अधिक गहराई से देखें कि हम कार्य कतार को कैसे संसाधित करते हैं।

कार्य कतार को संसाधित करें

हम पहले आपको कोड दिखाएंगे और फिर इसमें शामिल प्रमुख तत्वों पर प्रकाश डालेंगे:


 def process_queue(embed_and_write_cb, batch_size:int=10): with psycopg2.connect(TIMESCALE_SERVICE_URL) as conn: with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cursor: cursor.execute(f""" SELECT to_regclass('blog_embedding_work_queue')::oid; """) table_oid = cursor.fetchone()[0] cursor.execute(f""" WITH selected_rows AS ( SELECT id FROM blog_embedding_work_queue LIMIT {int(batch_size)} FOR UPDATE SKIP LOCKED ), locked_items AS ( SELECT id, pg_try_advisory_xact_lock( {int(table_oid)}, id) AS locked FROM ( SELECT DISTINCT id FROM selected_rows ORDER BY id ) as ids ), deleted_rows AS ( DELETE FROM blog_embedding_work_queue WHERE id IN ( SELECT id FROM locked_items WHERE locked = true ORDER BY id ) ) SELECT locked_items.id as locked_id, {self.table_name}.* FROM locked_items LEFT JOIN blog ON blog.id = locked_items.id WHERE locked = true ORDER BY locked_items.id """) res = cursor.fetchall() if len(res) > 0: embed_and_write_cb(res) return len(res) process_queue(embed_and_write)


उपरोक्त स्निपेट में SQL कोड सूक्ष्म है क्योंकि इसे प्रदर्शनकर्ता और समवर्ती-सुरक्षित दोनों के लिए डिज़ाइन किया गया है, तो आइए इसके बारे में जानें:


  • कार्य कतार से आइटम निकालना : प्रारंभ में, सिस्टम कार्य कतार से प्रविष्टियों की एक निर्दिष्ट संख्या को पुनर्प्राप्त करता है, जो बैच कतार आकार पैरामीटर द्वारा निर्धारित की जाती है। यह सुनिश्चित करने के लिए FOR UPDATE लॉक लिया जाता है कि समवर्ती रूप से निष्पादित स्क्रिप्ट समान कतार आइटम को संसाधित करने का प्रयास न करें। SKIP LOCKED निर्देश यह सुनिश्चित करता है कि यदि कोई प्रविष्टि वर्तमान में किसी अन्य स्क्रिप्ट द्वारा नियंत्रित की जा रही है, तो सिस्टम अनावश्यक देरी से बचने के लिए प्रतीक्षा करने के बजाय इसे छोड़ देगा।


  • ब्लॉग आईडी को लॉक करना : कार्य-कतार तालिका के भीतर एक ही ब्लॉग_आईडी के लिए डुप्लिकेट प्रविष्टियों की संभावना के कारण, केवल उक्त तालिका को लॉक करना अपर्याप्त है। विभिन्न नौकरियों द्वारा एक ही आईडी का समवर्ती प्रसंस्करण हानिकारक होगा। निम्नलिखित संभावित दौड़-स्थिति पर विचार करें:


  • जॉब 1 संस्करण 1 को पुनः प्राप्त करते हुए, ब्लॉग शुरू करता है और उस तक पहुँचता है।


  • ब्लॉग पर एक बाहरी अद्यतन होता है.


  • इसके बाद, संस्करण 2 प्राप्त करते हुए, जॉब 2 शुरू होता है।


  • दोनों नौकरियां एम्बेडिंग जनरेशन प्रक्रिया शुरू करती हैं।


  • जॉब 2 ब्लॉग संस्करण 2 के अनुरूप एम्बेडिंग को संग्रहीत करते हुए समाप्त होता है।


  • कार्य 1, निष्कर्ष पर, ग़लती से पुराने संस्करण 1 के साथ एम्बेडिंग संस्करण 2 को अधिलेखित कर देता है।


हालाँकि कोई स्पष्ट संस्करण ट्रैकिंग शुरू करके इस समस्या का मुकाबला कर सकता है, लेकिन यह प्रदर्शन लाभ के बिना काफी जटिलता पेश करता है। हमने जो रणनीति चुनी वह न केवल इस समस्या को कम करती है बल्कि स्क्रिप्ट को समवर्ती रूप से निष्पादित करके अनावश्यक संचालन और व्यर्थ काम को भी रोकती है।


ऐसे अन्य तालों के साथ संभावित ओवरलैप से बचने के लिए तालिका पहचानकर्ता के साथ पहले से जुड़ा एक पोस्टग्रेज सलाहकार लॉक नियोजित किया जाता है। try संस्करण, SKIP LOCKED के पहले एप्लिकेशन के अनुरूप, यह सुनिश्चित करता है कि सिस्टम लॉक पर प्रतीक्षा करने से बचता है। ORDER BY blog_id क्लॉज को शामिल करने से संभावित गतिरोधों को रोकने में मदद मिलती है। हम नीचे कुछ विकल्पों पर चर्चा करेंगे।


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


  • ब्लॉगों को संसाधित करना: अंतिम चरण में, हम ब्लॉगों को संसाधित करने के लिए लाते हैं। लेफ्ट जॉइन के उपयोग पर ध्यान दें: यह हमें उन हटाए गए आइटमों के लिए ब्लॉग आईडी पुनर्प्राप्त करने की अनुमति देता है जिनमें ब्लॉग पंक्ति नहीं होगी। हमें उन आइटमों की एम्बेडिंग हटाने के लिए उन्हें ट्रैक करने की आवश्यकता है। embed_and_write कॉलबैक में, हम ब्लॉग को हटाए जाने (या अप्रकाशित होने की स्थिति में, जिस स्थिति में हम एम्बेडिंग को भी हटाना चाहते हैं) के लिए एक प्रहरी के रूप में प्रकाशित_टाइम को NULL के रूप में उपयोग करते हैं।

विकल्प 4: किसी अन्य तालिका का उपयोग करके सलाहकार ताले का उपयोग करने से बचें।

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


वैकल्पिक रूप से, आपके पास केवल इस उद्देश्य के लिए एक blog_embedding_locks तालिका हो सकती है। हमने उस तालिका को बनाने का सुझाव नहीं दिया क्योंकि हमें लगता है कि यह जगह के मामले में काफी बेकार हो सकती है, और सलाहकार ताले का उपयोग करने से इस ओवरहेड से बचा जा सकता है।

निष्कर्ष और अगले चरण

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


इस ब्लॉग पोस्ट में, हमने आपको पर्दे के पीछे की एक झलक दी कि कैसे हमने एक ऐसा सिस्टम बनाया जो लचीलेपन का दावा करता है, एम्बेडिंग-जेनरेशन सेवा के संभावित डाउनटाइम को प्रभावी ढंग से संभालता है। इसका डिज़ाइन डेटा संशोधनों की उच्च दर को प्रबंधित करने में कुशल है और बढ़े हुए भार को समायोजित करने के लिए समवर्ती एम्बेडिंग-जनरेशन प्रक्रियाओं का निर्बाध रूप से उपयोग कर सकता है।


इसके अलावा, PostgreSQL में डेटा जमा करने और पृष्ठभूमि में एम्बेडिंग पीढ़ी को प्रबंधित करने के लिए डेटाबेस का उपयोग करने का प्रतिमान डेटा संशोधनों के बीच एम्बेडिंग रखरखाव की निगरानी के लिए एक आसान तंत्र के रूप में उभरता है। एआई क्षेत्र में असंख्य डेमो और ट्यूटोरियल दस्तावेज़ों से डेटा के प्रारंभिक निर्माण पर विशेष रूप से ध्यान केंद्रित करते हैं, जैसे-जैसे यह विकसित होता है, डेटा सिंक्रोनाइज़ेशन को संरक्षित करने से जुड़ी जटिल बारीकियों को नज़रअंदाज कर दिया जाता है।


हालाँकि, वास्तविक उत्पादन परिवेश में, डेटा हमेशा बदलता रहता है, और इन बदलावों को ट्रैक करने और सिंक्रनाइज़ करने की जटिलताओं से जूझना कोई मामूली प्रयास नहीं है। लेकिन डेटाबेस इसी के लिए डिज़ाइन किया गया है! इसका उपयोग ही क्यों न करें?


आपकी सीखने की यात्रा जारी रखने के लिए यहां कुछ संसाधन दिए गए हैं :



मैटवे आर्य द्वारा लिखित।