একটি PostgreSQL টেবিলে সংরক্ষিত ডেটা এম্বেড করা নিঃসন্দেহে দরকারী - শব্দার্থক অনুসন্ধান এবং সুপারিশ সিস্টেম থেকে শুরু করে জেনারেটিভ এআই অ্যাপ্লিকেশন এবং পুনরুদ্ধার বর্ধিত প্রজন্ম পর্যন্ত অ্যাপ্লিকেশন সহ। কিন্তু 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
)।
এই এমবেডিং সিস্টেমটি তৈরি করার সময়, আমরা বেশ কয়েকটি লক্ষ্য চিহ্নিত করতে সক্ষম হয়েছিলাম যেগুলি এম্বেডিং তৈরি করে এমন যেকোন সহজবোধ্য এবং স্থিতিস্থাপক সিস্টেমের থাকা উচিত:
মূল টেবিলে কোন পরিবর্তন নেই। এটি ইতিমধ্যেই এই টেবিলটি ব্যবহার করা সিস্টেম এবং অ্যাপ্লিকেশনগুলিকে এমবেডিং সিস্টেমের পরিবর্তন দ্বারা প্রভাবিত না হওয়ার অনুমতি দেয়৷ এটি লিগ্যাসি সিস্টেমের জন্য বিশেষভাবে গুরুত্বপূর্ণ।
টেবিলের সাথে ইন্টারঅ্যাক্ট করে এমন অ্যাপ্লিকেশনগুলিতে কোন পরিবর্তন নেই। সারণীকে পরিবর্তন করে এমন কোডটি পরিবর্তন করা লিগ্যাসি সিস্টেমের জন্য সম্ভব নাও হতে পারে। এটি দুর্বল সফ্টওয়্যার ডিজাইন কারণ এটি এমন সিস্টেমগুলিকে সংযুক্ত করে যা এম্বেডিং তৈরি করে এমন কোডের সাথে এমবেডিং ব্যবহার করে না।
উৎস টেবিলের সারি পরিবর্তন হলে স্বয়ংক্রিয়ভাবে এমবেডিং আপডেট করুন (এই ক্ষেত্রে, ব্লগ টেবিল)। এটি রক্ষণাবেক্ষণের বোঝা হ্রাস করে এবং উদ্বেগ-মুক্ত সফ্টওয়্যারটিতে অবদান রাখে। একই সময়ে, এই আপডেটটি তাত্ক্ষণিক বা একই প্রতিশ্রুতির মধ্যে হওয়া উচিত নয়। বেশিরভাগ সিস্টেমের জন্য, "পরিশেষে ধারাবাহিকতা" ঠিক আছে।
নেটওয়ার্ক এবং পরিষেবা ব্যর্থতার বিরুদ্ধে স্থিতিস্থাপকতা নিশ্চিত করুন: বেশিরভাগ সিস্টেমই একটি বহিরাগত সিস্টেমে কলের মাধ্যমে এম্বেডিং তৈরি করে, যেমন OpenAI API। এমন পরিস্থিতিতে যেখানে বাহ্যিক সিস্টেম ডাউন, বা একটি নেটওয়ার্ক ত্রুটি দেখা দেয়, আপনার ডাটাবেস সিস্টেমের অবশিষ্টাংশ কাজ চালিয়ে যাওয়া অপরিহার্য।
এই নির্দেশিকাগুলি একটি শক্তিশালী আর্কিটেকচারের ভিত্তি ছিল যা আমরা ব্যবহার করে প্রয়োগ করেছি
এখানে আমরা স্থির স্থাপত্য:
এই ডিজাইনে, আমরা প্রথমে ব্লগ টেবিলে একটি ট্রিগার যোগ করি যা পরিবর্তনের জন্য নিরীক্ষণ করে এবং একটি পরিবর্তন দেখে, blog_work_queue টেবিলে একটি কাজ সন্নিবেশ করাই যা ইঙ্গিত করে যে ব্লগ টেবিলের একটি সারি তার এম্বেডিংয়ের সাথে পুরানো।
একটি নির্দিষ্ট সময়সূচীতে, একটি এম্বেডিং ক্রিয়েটর কাজ blog_work_queue টেবিলে পোল করবে, এবং যদি এটি করার মতো কাজ খুঁজে পায়, তাহলে লুপে নিম্নলিখিতগুলি করবে:
এই সিস্টেমটি কার্যকর দেখতে, ব্যবহারের একটি উদাহরণ দেখুন
আমাদের ব্লগ অ্যাপ্লিকেশন টেবিলের উদাহরণে ফিরে যাওয়া, একটি উচ্চ স্তরে, PgVectorizer কে দুটি জিনিস করতে হবে:
কোন সারি পরিবর্তিত হয়েছে তা জানতে ব্লগের সারিগুলির পরিবর্তনগুলি ট্র্যাক করুন৷
এম্বেডিং তৈরি করতে পরিবর্তনগুলি প্রক্রিয়া করার একটি পদ্ধতি প্রদান করুন।
এই উভয় অত্যন্ত সমসাময়িক এবং কর্মক্ষম হতে হবে. দেখা যাক এটা কিভাবে কাজ করে।
আপনি নিম্নলিখিতগুলির সাথে একটি সাধারণ কাজের সারি টেবিল তৈরি করতে পারেন:
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;
ট্রিগারটি ব্লগের ID সন্নিবেশ করায় যা blog_work_queue এ পরিবর্তিত হয়েছে। আমরা ট্রিগার ইন্সটল করি এবং তারপর যেকোন বিদ্যমান ব্লগকে work_queue-এ সন্নিবেশ করি। কোনো আইডি যাতে বাদ না যায় তা নিশ্চিত করার জন্য এই অর্ডারিং গুরুত্বপূর্ণ।
এখন, আসুন কিছু বিকল্প ডিজাইন বর্ণনা করি এবং কেন আমরা সেগুলি প্রত্যাখ্যান করেছি।
এই কী প্রবর্তন করলে ডুপ্লিকেট এন্ট্রির সমস্যা দূর হবে। যাইহোক, এটি তার চ্যালেঞ্জ ছাড়া নয়, বিশেষ করে কারণ এই ধরনের কী আমাদেরকে INSERT…ON CONFLICT DO NOTHING
ক্লজ ব্যবহার করতে বাধ্য করবে টেবিলে নতুন আইডি ঢোকানোর জন্য, এবং সেই ধারাটি বি-ট্রিতে আইডিতে একটি লক করে দেয়।
এখানে দ্বিধা আছে: প্রক্রিয়াকরণ পর্যায়ে, একযোগে প্রক্রিয়াকরণ প্রতিরোধ করার জন্য কাজ করা সারিগুলি মুছে ফেলা প্রয়োজন। তবুও, ব্লগ_এম্বেডিং-এ সংশ্লিষ্ট এমবেডিং স্থাপন করার পরেই এই মুছে ফেলার কাজটি করা যেতে পারে। মাঝপথে কোনো ব্যাঘাত ঘটলে এটি নিশ্চিত করে যে কোনো আইডি হারিয়ে যাবে না—বলুন, যদি এম্বেডিং তৈরি করা মুছে ফেলার পরে ক্র্যাশ হয়ে যায় কিন্তু এমবেডিং লেখার আগে।
এখন, যদি আমরা একটি অনন্য বা প্রাথমিক কী তৈরি করি, তাহলে মুছে ফেলার তত্ত্বাবধানে লেনদেন খোলা থাকে। ফলস্বরূপ, এটি সেই নির্দিষ্ট আইডিগুলিতে লক হিসাবে কাজ করে, এমবেডিং তৈরির কাজের পুরো সময়কালের জন্য ব্লগ_ওয়ার্ক_সারিতে তাদের সন্নিবেশ রোধ করে৷ প্রদত্ত যে আপনার সাধারণ ডাটাবেস লেনদেনের চেয়ে এম্বেডিং তৈরি করতে বেশি সময় লাগে, এটি সমস্যা তৈরি করে। লকটি মূল 'ব্লগ' টেবিলের জন্য ট্রিগারকে আটকে দেবে, যার ফলে প্রাথমিক অ্যাপ্লিকেশনের কর্মক্ষমতা কমে যাবে। জিনিসগুলিকে আরও খারাপ করে তোলে, যদি একটি ব্যাচে একাধিক সারি প্রক্রিয়াকরণ করা হয়, অচলাবস্থাও একটি সম্ভাব্য সমস্যা হয়ে দাঁড়ায়।
যাইহোক, মাঝে মাঝে ডুপ্লিকেট এন্ট্রি থেকে উদ্ভূত সম্ভাব্য সমস্যাগুলি প্রক্রিয়াকরণ পর্যায়ে পরিচালনা করা যেতে পারে, যেমনটি পরে দেখানো হয়েছে। এখানে একটি বিক্ষিপ্ত সদৃশ এবং কোনও সমস্যা নেই কারণ এটি এমবেডিং কাজ সম্পাদন করার পরিমাণকে সামান্য পরিমাণে বাড়িয়ে দেয়। এটি অবশ্যই উপরে উল্লিখিত লকিং চ্যালেঞ্জগুলির সাথে লড়াই করার চেয়ে আরও মজাদার।
উদাহরণ স্বরূপ, আমরা একটি embedded
বুলিয়ান কলাম যুক্ত করতে পারি পরিবর্তনের সময় মিথ্যাতে সেট করতে এবং এম্বেডিং তৈরি হলে সত্যে ফ্লিপ করতে পারি। এই নকশা প্রত্যাখ্যান করার তিনটি কারণ আছে:
আমরা ইতিমধ্যে উপরে উল্লেখিত কারণে blog
টেবিল পরিবর্তন করতে চাই না.
নন-এমবেডেড ব্লগের একটি তালিকা দক্ষতার সাথে পাওয়ার জন্য ব্লগ টেবিলে একটি অতিরিক্ত সূচক (বা আংশিক সূচক) প্রয়োজন। এটি অন্যান্য ক্রিয়াকলাপকে ধীর করে দেবে।
এটি টেবিলে মন্থন বাড়ায় কারণ PostgreSQL-এর MVCC প্রকৃতির কারণে প্রতিটি পরিবর্তন এখন দুবার লেখা হবে (একবার এমবেডিং=ফলস এবং একবার এমবেডিং=সত্য সহ)।
একটি পৃথক ওয়ার্ক_কিউ_টেবিল এই সমস্যাগুলি সমাধান করে।
এই পদ্ধতির বেশ কয়েকটি সমস্যা রয়েছে:
যদি এমবেডিং পরিষেবা বন্ধ থাকে, হয় ট্রিগারটি ব্যর্থ হতে হবে (আপনার লেনদেন বাতিল করা হচ্ছে), অথবা আপনাকে একটি ব্যাকআপ কোড পাথ তৈরি করতে হবে যা … আইডিগুলিকে সঞ্চয় করে যা একটি সারিতে এম্বেড করা যায়নি৷ পরবর্তী সমাধানটি আমাদের প্রস্তাবিত ডিজাইনে ফিরে আসে তবে আরও জটিলতার সাথে উপরে বোল্ট করা হয়েছে।
এই ট্রিগারটি সম্ভবত বাকি ডাটাবেস ক্রিয়াকলাপগুলির তুলনায় অনেক ধীর হবে কারণ একটি বহিরাগত পরিষেবার সাথে যোগাযোগ করতে দেরি হওয়া প্রয়োজন৷ এটি টেবিলে আপনার বাকি ডাটাবেস ক্রিয়াকলাপকে ধীর করে দেবে।
এটি ব্যবহারকারীকে সরাসরি ডাটাবেসে তৈরি এমবেডিং কোড লিখতে বাধ্য করে। প্রদত্ত যে AI এর ভাষা ফ্রাঙ্কা হল পাইথন এবং এমবেডিং তৈরির জন্য প্রায়শই অন্যান্য অনেক লাইব্রেরির প্রয়োজন হয়, এটি সর্বদা সহজ বা এমনকি সম্ভবও নয় (বিশেষত যদি একটি হোস্ট করা PostgreSQL ক্লাউড পরিবেশের মধ্যে চলে)। ডাটাবেসের ভিতরে বা বাইরে এমবেডিং তৈরি করার জন্য আপনার পছন্দ আছে এমন একটি ডিজাইন থাকা অনেক ভালো।
এখন আমাদের কাছে ব্লগের একটি তালিকা রয়েছে যা এম্বেড করা দরকার, আসুন তালিকাটি প্রক্রিয়া করি!
এমবেডিং তৈরি করার অনেক উপায় আছে। আমরা একটি বহিরাগত পাইথন স্ক্রিপ্ট ব্যবহার করার পরামর্শ দিই। এই স্ক্রিপ্টটি কাজের সারি এবং সম্পর্কিত ব্লগ পোস্টগুলিকে স্ক্যান করবে, এমবেডিংগুলি তৈরি করার জন্য একটি বহিরাগত পরিষেবা চালু করবে এবং তারপরে এই এমবেডিংগুলিকে ডাটাবেসে আবার সংরক্ষণ করবে৷ এই কৌশলটির জন্য আমাদের যুক্তি নিম্নরূপ:
পাইথনের পছন্দ : আমরা পাইথনকে সুপারিশ করছি কারণ এটি AI ডেটা টাস্কগুলির জন্য একটি সমৃদ্ধ, অতুলনীয় ইকোসিস্টেম অফার করে, যা শক্তিশালী এলএলএম ডেভেলপমেন্ট এবং ডেটা লাইব্রেরি দ্বারা হাইলাইট করা হয়েছে
PL/Python এর পরিবর্তে একটি বাহ্যিক স্ক্রিপ্ট বেছে নেওয়া : আমরা ব্যবহারকারীদের তাদের ডেটা এম্বেড করার উপর নিয়ন্ত্রণ রাখতে চাই। তবুও, একই সময়ে, অনেক Postgres ক্লাউড প্রদানকারী নিরাপত্তা উদ্বেগের কারণে ডাটাবেসের ভিতরে নির্বিচারে Python কোড কার্যকর করার অনুমতি দেয় না। সুতরাং, ব্যবহারকারীদের তাদের এমবেডিং স্ক্রিপ্টের পাশাপাশি যেখানে তারা তাদের ডাটাবেস হোস্ট করে সেখানে নমনীয়তা রাখার অনুমতি দেওয়ার জন্য, আমরা একটি ডিজাইন নিয়ে গিয়েছিলাম যা বহিরাগত পাইথন স্ক্রিপ্ট ব্যবহার করে।
কাজগুলি অবশ্যই পারফরম্যান্ট এবং কনকারেন্সি-সুরক্ষিত হতে হবে। কনকারেন্সি গ্যারান্টি দেয় যে যদি কাজগুলি পিছিয়ে চলতে শুরু করে, তবে সিস্টেমকে ধরতে এবং লোড পরিচালনা করতে সহায়তা করার জন্য শিডিউলাররা আরও কাজ শুরু করতে পারে।
আমরা পরে সেই পদ্ধতিগুলির প্রতিটি কীভাবে সেট আপ করব তা দেখব, কিন্তু প্রথমে, পাইথন স্ক্রিপ্টটি কেমন হবে তা দেখা যাক। মৌলিকভাবে, স্ক্রিপ্টের তিনটি অংশ রয়েছে:
কাজের সারি এবং ব্লগ পোস্ট পড়ুন
ব্লগ পোস্টের জন্য একটি এম্বেডিং তৈরি করুন
ব্লগ_এম্বেডিং টেবিলে এমবেডিং লিখুন
ধাপ 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)
উপরের স্নিপেটে এসকিউএল কোডটি সূক্ষ্ম কারণ এটি পারফরম্যান্ট এবং কনকারেন্সি-সুরক্ষিত উভয়ের জন্য ডিজাইন করা হয়েছে, তাই আসুন এটির মধ্য দিয়ে যাওয়া যাক:
কাজের সারি থেকে আইটেমগুলি বের করা : প্রাথমিকভাবে, সিস্টেমটি ব্যাচ কিউ আকারের প্যারামিটার দ্বারা নির্ধারিত কাজের সারি থেকে একটি নির্দিষ্ট সংখ্যক এন্ট্রি পুনরুদ্ধার করে। আপডেট করার জন্য একটি লক নেওয়া হয়েছে যাতে একইসাথে এক্সিকিউট করা স্ক্রিপ্টগুলি একই সারি আইটেমগুলি প্রক্রিয়া করার চেষ্টা না করে। SKIP LOCKED নির্দেশটি নিশ্চিত করে যে যদি কোনো এন্ট্রি বর্তমানে অন্য স্ক্রিপ্ট দ্বারা পরিচালিত হয়, তবে সিস্টেমটি অপেক্ষা করার পরিবর্তে এটিকে এড়িয়ে যাবে, অপ্রয়োজনীয় বিলম্ব এড়ানো।
ব্লগ আইডি লক করা : ওয়ার্ক-কিউ টেবিলের মধ্যে একই blog_id-এর জন্য ডুপ্লিকেট এন্ট্রির সম্ভাবনার কারণে, শুধুমাত্র বলা টেবিল লক করা অপর্যাপ্ত। বিভিন্ন কাজের দ্বারা একই আইডির একযোগে প্রক্রিয়াকরণ ক্ষতিকারক হবে। নিম্নলিখিত সম্ভাব্য জাতি-শর্ত বিবেচনা করুন:
কাজ 1 একটি ব্লগ শুরু করে এবং অ্যাক্সেস করে, সংস্করণ 1 পুনরুদ্ধার করে।
ব্লগে একটি বাহ্যিক আপডেট ঘটে।
পরবর্তীকালে, কাজ 2 শুরু হয়, সংস্করণ 2 পেয়ে।
উভয় কাজই এমবেডিং জেনারেশন প্রক্রিয়া শুরু করে।
কাজ 2 সমাপ্ত হয়েছে, ব্লগ সংস্করণ 2 এর সাথে সম্পর্কিত এমবেডিং সংরক্ষণ করে৷
কাজ 1, উপসংহারে, পুরানো সংস্করণ 1 এর সাথে এম্বেডিং সংস্করণ 2কে ভুলভাবে ওভাররাইট করে।
যদিও কেউ স্পষ্ট সংস্করণ ট্র্যাকিং প্রবর্তন করে এই সমস্যাটির মোকাবিলা করতে পারে, এটি কার্যকারিতা সুবিধা ছাড়াই যথেষ্ট জটিলতার পরিচয় দেয়। আমরা যে কৌশলটির জন্য বেছে নিয়েছি তা শুধুমাত্র এই সমস্যাটিকে প্রশমিত করে না বরং একই সাথে স্ক্রিপ্টগুলি সম্পাদন করে অপ্রয়োজনীয় ক্রিয়াকলাপ এবং নষ্ট কাজ প্রতিরোধ করে।
একটি Postgres উপদেষ্টা লক, অন্যান্য এই ধরনের লকগুলির সাথে সম্ভাব্য ওভারল্যাপ এড়াতে টেবিল শনাক্তকারীর সাথে প্রিফিক্স করা হয়। try
ভেরিয়েন্ট, SKIP LOCKED এর আগের প্রয়োগের সাথে সাদৃশ্যপূর্ণ, নিশ্চিত করে যে সিস্টেমটি লকগুলিতে অপেক্ষা করা এড়ায়। ORDER BY blog_id ধারার অন্তর্ভুক্তি সম্ভাব্য অচলাবস্থা প্রতিরোধ করতে সাহায্য করে। আমরা নীচে কিছু বিকল্প কভার করব।
কাজের সারি পরিষ্কার করা : স্ক্রিপ্টটি তারপরে আমরা সফলভাবে লক করা ব্লগগুলির জন্য সমস্ত কাজের সারি আইটেম মুছে দেয়৷ যদি এই সারি আইটেমগুলি মাল্টি-ভার্সন কনকারেন্সি কন্ট্রোল (MVCC) এর মাধ্যমে দৃশ্যমান হয়, তবে তাদের আপডেটগুলি পুনরুদ্ধার করা ব্লগ সারিতে প্রকাশিত হয়৷ মনে রাখবেন যে আমরা প্রদত্ত ব্লগ আইডি সহ সমস্ত আইটেম মুছে ফেলি, সারি নির্বাচন করার সময় শুধুমাত্র পড়া আইটেম নয়: এটি একই ব্লগ আইডির জন্য ডুপ্লিকেট এন্ট্রিগুলি কার্যকরভাবে পরিচালনা করে৷ এটা মনে রাখা গুরুত্বপূর্ণ যে এই মুছে ফেলার কাজটি শুধুমাত্র embed_and_write() ফাংশন এবং আপডেট করা এমবেডিংয়ের পরবর্তী স্টোরেজ চালু করার পরেই করা হয়। এই ক্রমটি নিশ্চিত করে যে এমবেডিং জেনারেশন পর্বের সময় স্ক্রিপ্ট ব্যর্থ হলেও আমরা কোনো আপডেট হারাবো না।
ব্লগগুলিকে প্রসেস করার জন্য নেওয়া: শেষ ধাপে, আমরা ব্লগগুলিকে প্রসেস করার জন্য নিয়ে আসি। বাম যোগদানের ব্যবহার নোট করুন: এটি আমাদের মুছে ফেলা আইটেমগুলির জন্য ব্লগ আইডিগুলি পুনরুদ্ধার করতে দেয় যেগুলির ব্লগ সারি থাকবে না৷ তাদের এমবেডিং মুছে ফেলার জন্য আমাদের সেই আইটেমগুলিকে ট্র্যাক করতে হবে। embed_and_write
কলব্যাকে, আমরা ব্লগ মুছে ফেলার জন্য একটি সেন্টিনেল হিসাবে প্রকাশিত_সময় NULL ব্যবহার করি (বা অপ্রকাশিত, এই ক্ষেত্রে আমরা এমবেডিংটি মুছে ফেলতে চাই)।
যদি সিস্টেমটি ইতিমধ্যেই উপদেষ্টা লক ব্যবহার করে এবং আপনি সংঘর্ষের বিষয়ে চিন্তিত হন, তাহলে প্রাথমিক কী হিসাবে একটি ব্লগ আইডি সহ একটি টেবিল ব্যবহার করা এবং সারিগুলি লক করা সম্ভব৷ প্রকৃতপক্ষে, এটি নিজেই ব্লগ টেবিল হতে পারে যদি আপনি নিশ্চিত হন যে এই লকগুলি অন্য কোনও সিস্টেমকে ধীর করবে না (মনে রাখবেন, এই লকগুলিকে এমবেডিং প্রক্রিয়া জুড়ে ধরে রাখতে হবে, যা কিছু সময় নিতে পারে)৷
বিকল্পভাবে, আপনি শুধুমাত্র এই উদ্দেশ্যে একটি blog_embedding_locks টেবিল রাখতে পারেন। আমরা সেই টেবিলটি তৈরি করার পরামর্শ দিইনি কারণ আমরা মনে করি এটি স্থানের পরিপ্রেক্ষিতে বেশ অপচয় হতে পারে এবং পরামর্শমূলক লক ব্যবহার করা এই ওভারহেড এড়িয়ে যায়।
এই ব্লগ পোস্টে, আমরা আপনাকে একটি পর্দার পেছনের দৃষ্টিভঙ্গি দিয়েছি কিভাবে আমরা এমন একটি সিস্টেম তৈরি করেছি যা স্থিতিস্থাপকতার গর্ব করে, কার্যকরভাবে এমবেডিং-জেনারেশন পরিষেবার সম্ভাব্য ডাউনটাইমগুলি পরিচালনা করে৷ এর ডিজাইনটি ডেটা পরিবর্তনের উচ্চ হার পরিচালনা করতে পারদর্শী এবং উচ্চতর লোডগুলিকে মিটমাট করার জন্য সমসাময়িক এমবেডিং-জেনারেশন প্রক্রিয়াগুলিকে নির্বিঘ্নে ব্যবহার করতে পারে।
অধিকন্তু, PostgreSQL-এ ডেটা কমিট করার এবং ব্যাকগ্রাউন্ডে এম্বেডিং জেনারেশন পরিচালনা করতে ডাটাবেস ব্যবহার করার দৃষ্টান্ত ডেটা পরিবর্তনের মধ্যে এম্বেডিং রক্ষণাবেক্ষণের তত্ত্বাবধানের একটি সহজ প্রক্রিয়া হিসাবে আবির্ভূত হয়। AI স্পেসে অসংখ্য ডেমো এবং টিউটোরিয়াল এককভাবে ডকুমেন্ট থেকে ডেটা তৈরির উপর ফোকাস করে, ডেটা সিঙ্ক্রোনাইজেশন সংরক্ষণের সাথে সম্পর্কিত জটিল সূক্ষ্মতাগুলিকে উপেক্ষা করে এটি বিকশিত হয়।
যাইহোক, বাস্তব উত্পাদন পরিবেশে, ডেটা সর্বদাই পরিবর্তিত হয় এবং এই পরিবর্তনগুলিকে ট্র্যাকিং এবং সিঙ্ক্রোনাইজ করার জটিলতার সাথে লড়াই করা কোন তুচ্ছ প্রচেষ্টা নয়। কিন্তু যে কি একটি ডাটাবেস ডিজাইন করা হয়! কেন শুধু এটা ব্যবহার করবেন না?
লিখেছেন Matvey Arye.
এছাড়াও এখানে প্রকাশিত.