ইলাস্টিকসার্চ হল একটি ওপেন সোর্স সার্চ এবং অ্যানালিটিক্স ইঞ্জিন যা Apache Lucene-এর উপর ভিত্তি করে। ইলাস্টিকসার্চ ব্যবহার করে পরিবর্তন ডেটা ক্যাপচার (সিডিসি) ডেটাতে অ্যাপ্লিকেশন তৈরি করার সময়, আপনি একটি সূচকে বিদ্যমান নথিতে ঘন ঘন আপডেট বা পরিবর্তনগুলি পরিচালনা করার জন্য সিস্টেমটিকে আর্কিটেক্ট করতে চাইবেন।
এই ব্লগে, আমরা সম্পূর্ণ আপডেট, আংশিক আপডেট এবং স্ক্রিপ্টেড আপডেট সহ আপডেটের জন্য উপলব্ধ বিভিন্ন বিকল্পের মধ্য দিয়ে চলে যাব। একটি নথি সংশোধন করার সময় ইলাস্টিকসার্চে হুডের নীচে কী ঘটে এবং কীভাবে ঘন ঘন আপডেটগুলি সিস্টেমে CPU ব্যবহারকে প্রভাবিত করে তা নিয়েও আমরা আলোচনা করব।
ঘন ঘন আপডেট আছে এমন ব্যবহারের ক্ষেত্রে আরও ভালভাবে বোঝার জন্য, আসুন Netflix-এর মতো একটি ভিডিও স্ট্রিমিং পরিষেবার জন্য একটি অনুসন্ধান অ্যাপ্লিকেশন দেখি। যখন একজন ব্যবহারকারী একটি শো, যেমন "রাজনৈতিক থ্রিলার" অনুসন্ধান করে, তখন তাদের কীওয়ার্ড এবং অন্যান্য মেটাডেটার উপর ভিত্তি করে প্রাসঙ্গিক ফলাফলের একটি সেট ফিরিয়ে দেওয়া হয়।
আসুন "হাউস অফ কার্ডস" শো এর ইলাস্টিকসার্চে একটি উদাহরণ দস্তাবেজ দেখি:
{ "name": "House of Cards", "description": "Frank Underwood is a Democrat appointed as the Secretary of State. Along with his wife, he sets out on a quest to seek revenge from the people who betrayed him while successfully rising to supremacy.", "genres": ["drama", "thriller"], "views": 100, }
পূর্ণ-পাঠ্য অনুসন্ধান ক্ষেত্র হিসাবে name
এবং description
ব্যবহার করার জন্য অনুসন্ধানটি ইলাস্টিকসার্চে কনফিগার করা যেতে পারে। views
ফিল্ড, যা প্রতি শিরোনাম প্রতি ভিউ সংখ্যা সঞ্চয় করে, কন্টেন্ট বাড়ানোর জন্য ব্যবহার করা যেতে পারে, আরও জনপ্রিয় শোগুলিকে উচ্চতর র্যাঙ্কিং করতে। একজন ব্যবহারকারী যখনই কোনো শো বা সিনেমার কোনো পর্ব দেখেন তখনই views
ফিল্ড বাড়ানো হয়।
Netflix এর স্কেল একটি অ্যাপ্লিকেশনে এই অনুসন্ধান কনফিগারেশন ব্যবহার করার সময়, Netflix এনগেজমেন্ট রিপোর্ট দ্বারা নির্ধারিত আপডেটের সংখ্যা সহজেই প্রতি মিনিটে মিলিয়ন অতিক্রম করতে পারে। প্রতিবেদন অনুসারে, ব্যবহারকারীরা জানুয়ারি থেকে জুলাই পর্যন্ত ~100 বিলিয়ন ঘন্টা সামগ্রী দেখেছেন। প্রতি এপিসোড বা সিনেমার গড় দেখার সময় 15 মিনিট ধরে নিলে, প্রতি মিনিটে ভিউ সংখ্যা গড়ে 1.3 মিলিয়নে পৌঁছায়। উপরে উল্লিখিত অনুসন্ধান কনফিগারেশনের সাথে, প্রতিটি দৃশ্যের লক্ষ লক্ষ স্কেলে একটি আপডেটের প্রয়োজন হবে।
অনেক অনুসন্ধান এবং বিশ্লেষণ অ্যাপ্লিকেশন ঘন ঘন আপডেট অনুভব করতে পারে, বিশেষ করে যখন সিডিসি ডেটার উপর নির্মিত।
আসুন নীচের কোডের সাথে ইলাস্টিকসার্চে একটি আপডেট কীভাবে সম্পাদন করতে হয় তার একটি সাধারণ উদাহরণে অনুসন্ধান করা যাক:
- from elasticsearch import Elasticsearch # Connect to your Elasticsearch instance es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # Index name and document ID you want to update index_name = 'movies' document_id = 'your_document_id' # Retrieve the current document to get the current 'views' value try: current_doc = es.get(index=index_name, id=document_id) current_views = current_doc['_source']['views'] except Exception as e: print(f"Error retrieving current document: {e}") current_views = 0 # Set a default value if there's an error # Define the update body to increment 'views' by 1 update_body = { "doc": { "views": current_views + 1 # Increment 'views' by 1 } } # Perform the update try: es.update(index=index_name, id=document_id, body=update_body) print("Document updated successfully!") except Exception as e: print(f"Error updating document: {e}")
ইলাস্টিকসার্চে একটি আপডেট সম্পাদন করার সময়, আপনি একটি বিদ্যমান নথি প্রতিস্থাপন করতে সূচক API বা একটি নথিতে একটি আংশিক আপডেট করতে আপডেট API ব্যবহার করতে পারেন।
সূচী API সম্পূর্ণ নথি পুনরুদ্ধার করে, নথিতে পরিবর্তন করে এবং তারপর নথিটিকে পুনঃসূচীকরণ করে। আপডেট API এর সাথে, আপনি সম্পূর্ণ নথির পরিবর্তে আপনি যে ক্ষেত্রগুলি পরিবর্তন করতে চান তা পাঠান। এর ফলে ডকুমেন্টটি পুনঃসূচীকরণ হয় কিন্তু নেটওয়ার্কে পাঠানো ডেটার পরিমাণ কমিয়ে দেয়। আপডেট এপিআই বিশেষত সেই ক্ষেত্রে উপযোগী যেখানে নথির আকার বড় এবং নেটওয়ার্কের মাধ্যমে সমগ্র নথি পাঠানো সময়সাপেক্ষ হবে৷
আসুন দেখি কিভাবে ইন্ডেক্স এপিআই এবং আপডেট এপিআই উভয়ই পাইথন কোড ব্যবহার করে কাজ করে।
from elasticsearch import Elasticsearch # Connect to Elasticsearch es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # Index name and document ID index_name = "your_index" document_id = "1" # Retrieve the existing document existing_document = es.get(index=index_name, id=document_id) # Make your changes to the document existing_document["_source"]["field1"] = "new_value1" existing_document["_source"]["field2"] = "new_value2" # Call the index API to perform the full update es.index(index=index_name, id=document_id, body=existing_document["_source"])
আপনি উপরের কোডে দেখতে পাচ্ছেন, সূচী API-এর জন্য ইলাস্টিকসার্চে দুটি পৃথক কল প্রয়োজন যার ফলে আপনার ক্লাস্টারে কর্মক্ষমতা ধীর এবং উচ্চ লোড হতে পারে।
আংশিক আপডেটগুলি অভ্যন্তরীণভাবে রিইন্ডেক্স API ব্যবহার করে, তবে আরও ভাল পারফরম্যান্সের জন্য শুধুমাত্র একটি একক নেটওয়ার্ক কল প্রয়োজন বলে কনফিগার করা হয়েছে৷
from elasticsearch import Elasticsearch # Connect to Elasticsearch es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # Index name and document ID index_name = "your_index" document_id = "1" # Specify the fields to be updated update_fields = { "field1": "new_value1", "field2": "new_value2" } # Use the update API to perform a partial update es.update(index=index_name, id=document_id, body={"doc": update_fields})
আপনি ইলাস্টিকসার্চে আপডেট এপিআই ব্যবহার করতে পারেন ভিউ কাউন্ট আপডেট করতে কিন্তু, নিজে থেকেই আপডেট এপিআই ব্যবহার করা যাবে না আগের মানের উপর ভিত্তি করে ভিউ কাউন্ট বাড়ানোর জন্য। কারণ নতুন ভিউ কাউন্ট মান সেট করতে আমাদের পুরানো ভিউ কাউন্টের প্রয়োজন।
আসুন দেখি কিভাবে আমরা একটি শক্তিশালী স্ক্রিপ্টিং ভাষা, ব্যথাহীন ব্যবহার করে এটি ঠিক করতে পারি।
পেইনলেস হল ইলাস্টিকসার্চের জন্য ডিজাইন করা একটি স্ক্রিপ্টিং ভাষা এবং এটি ক্যোয়ারী এবং অ্যাগ্রিগেশন ক্যালকুলেশন, জটিল শর্তাবলী, ডেটা ট্রান্সফর্মেশন এবং আরও অনেক কিছুর জন্য ব্যবহার করা যেতে পারে। ব্যথাহীন জটিল যুক্তির উপর ভিত্তি করে নথি সংশোধন করতে আপডেট কোয়েরিতে স্ক্রিপ্ট ব্যবহার করতে সক্ষম করে।
নীচের উদাহরণে, আমরা একটি একক API কলে একটি আপডেট করার জন্য একটি ব্যথাহীন স্ক্রিপ্ট ব্যবহার করি এবং পুরানো ভিউ গণনার মানের উপর ভিত্তি করে নতুন ভিউ সংখ্যা বৃদ্ধি করি।
from elasticsearch import Elasticsearch # Connect to your Elasticsearch instance es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # Index name and document ID you want to update index_name = 'movies' document_id = 'your_document_id' # Define the Painless script for the update update_script = { "script": { "lang": "painless", "source": "ctx._source.views += 1" # Increment 'views' by 1 } } # Perform the update using the Painless script try: es.update(index=index_name, id=document_id, body=update_script) print("Document updated successfully!") except Exception as e: print(f"Error updating document: {e}")
ব্যথাহীন স্ক্রিপ্টটি বোঝার জন্য বেশ স্বজ্ঞাত, এটি কেবল প্রতিটি নথির জন্য 1 দ্বারা ভিউ সংখ্যা বৃদ্ধি করছে।
ইলাস্টিকসার্চে নেস্টেড অবজেক্ট হল একটি ডাটা স্ট্রাকচার যা একটি একক প্যারেন্ট ডকুমেন্টের মধ্যে আলাদা নথি হিসেবে অবজেক্টের অ্যারেকে ইন্ডেক্স করার অনুমতি দেয়। নেস্টেড অবজেক্টগুলি কার্যকরী যখন জটিল ডেটা নিয়ে কাজ করে যা স্বাভাবিকভাবে একটি নেস্টেড কাঠামো তৈরি করে, যেমন অবজেক্টের মধ্যে থাকা বস্তুগুলি। একটি সাধারণ ইলাস্টিকসার্চ নথিতে, অবজেক্টের অ্যারেগুলিকে সমতল করা হয়, কিন্তু নেস্টেড ডেটা টাইপ ব্যবহার করে অ্যারের প্রতিটি বস্তুকে স্বাধীনভাবে সূচীকরণ এবং অনুসন্ধান করার অনুমতি দেয়।
ব্যথাহীন স্ক্রিপ্টগুলি ইলাস্টিকসার্চে নেস্টেড অবজেক্ট আপডেট করতেও ব্যবহার করা যেতে পারে।
from elasticsearch import Elasticsearch # Connect to your Elasticsearch instance es = Elasticsearch([{'host': 'localhost', 'port': 9200}]) # Index name and document ID for the example index_name = 'your_index' document_id = 'your_document_id' # Specify the nested field and the updated value nested_field = "nested_field_name" updated_value = "new_value" # Define the Painless script for the update update_script = { "script": { "lang": "painless", "source": "ctx._source.nested_field_name = params.updated_value", "params": { "updated_value": updated_value } } } # Perform the update using the Update API and the Painless script try: es.update(index=index_name, id=document_id, body=update_script) print("Nested object updated successfully!") except Exception as e: print(f"Error updating nested object: {e}")
ইলাস্টিকসার্চে একটি নথিতে একটি নতুন ক্ষেত্র যোগ করা একটি সূচক অপারেশনের মাধ্যমে সম্পন্ন করা যেতে পারে।
আপনি আপডেট API ব্যবহার করে নতুন ফিল্ডের সাথে একটি বিদ্যমান নথি আংশিকভাবে আপডেট করতে পারেন। যখন সূচকে গতিশীল ম্যাপিং সক্ষম করা হয়, তখন একটি নতুন ক্ষেত্র প্রবর্তন করা সহজ। কেবলমাত্র সেই ক্ষেত্রটি সম্বলিত একটি নথির সূচী করুন এবং ইলাস্টিকসার্চ স্বয়ংক্রিয়ভাবে উপযুক্ত ম্যাপিং বের করবে এবং ম্যাপিংয়ে নতুন ক্ষেত্র যোগ করবে।
ইনডেক্সে ডায়নামিক ম্যাপিং অক্ষম করে, আপনাকে আপডেট ম্যাপিং API ব্যবহার করতে হবে। আপনি সিনেমা সূচীতে একটি "বিভাগ" ক্ষেত্র যোগ করে কীভাবে সূচক ম্যাপিং আপডেট করবেন তার একটি উদাহরণ নীচে দেখতে পারেন।
PUT /movies/_mapping { "properties": { "category": { "type": "keyword" } } }
যদিও কোডটি সহজ, ইলাস্টিকসার্চ অভ্যন্তরীণভাবে এই আপডেটগুলি সম্পাদন করার জন্য অনেক ভারী উত্তোলন করছে কারণ ডেটা অপরিবর্তনীয় সেগমেন্টে সংরক্ষণ করা হয়। ফলস্বরূপ, ইলাস্টিকসার্চ কেবল একটি নথিতে একটি ইন-প্লেস আপডেট করতে পারে না। একটি আপডেট সম্পাদন করার একমাত্র উপায় হল সমগ্র নথিকে পুনঃসূচীকরণ করা, তা নির্বিশেষে যে API ব্যবহার করা হয়েছে।
ইলাস্টিকসার্চ ফণার নিচে Apache Lucene ব্যবহার করে। একটি লুসিন সূচক এক বা একাধিক অংশ নিয়ে গঠিত। একটি সেগমেন্ট হল একটি স্বয়ংসম্পূর্ণ, অপরিবর্তনীয় সূচক কাঠামো যা সামগ্রিক সূচকের একটি উপসেটকে প্রতিনিধিত্ব করে। যখন নথিগুলি যোগ করা হয় বা আপডেট করা হয়, তখন নতুন লুসিন সেগমেন্ট তৈরি করা হয় এবং পুরানো নথিগুলি নরম মুছে ফেলার জন্য চিহ্নিত করা হয়। সময়ের সাথে সাথে, নতুন নথি যোগ করা হলে বা বিদ্যমানগুলি আপডেট করা হলে, একাধিক সেগমেন্ট জমা হতে পারে। সূচক গঠন অপ্টিমাইজ করার জন্য, লুসিন পর্যায়ক্রমে ছোট অংশগুলিকে বৃহত্তরগুলিতে একত্রিত করে।
যেহেতু প্রতিটি আপডেট অপারেশন একটি রিইন্ডেক্স অপারেশন, সমস্ত আপডেটগুলি মূলত সফট ডিলিট সহ সন্নিবেশ করা হয়।
একটি সন্নিবেশ অপারেশন হিসাবে একটি আপডেট চিকিত্সার জন্য খরচ প্রভাব আছে. একদিকে, ডেটার নরম মুছে ফেলার অর্থ হল যে পুরানো ডেটা এখনও কিছু সময়ের জন্য ধরে রাখা হচ্ছে, সূচকের স্টোরেজ এবং মেমরিকে ফুলিয়ে দিচ্ছে। সফ্ট ডিলিট করা, রিইন্ডেক্সিং এবং আবর্জনা সংগ্রহের ক্রিয়াকলাপগুলিও CPU-তে একটি ভারী টোল নেয়, একটি টোল যা সমস্ত প্রতিলিপিতে এই ক্রিয়াকলাপগুলি পুনরাবৃত্তি করে আরও বাড়িয়ে তোলে।
আপনার পণ্যের বৃদ্ধি এবং সময়ের সাথে সাথে আপনার ডেটা পরিবর্তিত হওয়ার সাথে সাথে আপডেটগুলি আরও জটিল হতে পারে। ইলাস্টিকসার্চ পারফরম্যান্ট রাখতে, আপনাকে আপনার ক্লাস্টারে শার্ড, বিশ্লেষক এবং টোকেনাইজার আপডেট করতে হবে, যাতে পুরো ক্লাস্টারের পুনঃসূচীকরণের প্রয়োজন হয়। উৎপাদন অ্যাপ্লিকেশনের জন্য, এর জন্য একটি নতুন ক্লাস্টার সেট আপ করতে হবে এবং সমস্ত ডেটা স্থানান্তর করতে হবে। ক্লাস্টারগুলি স্থানান্তরিত করা সময়-নিবিড় এবং ত্রুটি প্রবণ উভয়ই তাই এটিকে হালকাভাবে নেওয়া একটি অপারেশন নয়।
ইলাস্টিকসার্চে আপডেট অপারেশনগুলির সরলতা সিস্টেমের হুডের অধীনে ঘটছে ভারী অপারেশনাল কাজগুলিকে মুখোশ করতে পারে। ইলাস্টিকসার্চ প্রতিটি আপডেটকে একটি সন্নিবেশ হিসাবে বিবেচনা করে, যার জন্য সম্পূর্ণ নথি পুনরায় তৈরি করা এবং পুনরায় তালিকাভুক্ত করা প্রয়োজন। ঘন ঘন আপডেট সহ অ্যাপ্লিকেশনগুলির জন্য, এটি দ্রুত ব্যয়বহুল হয়ে উঠতে পারে যেমনটি আমরা Netflix উদাহরণে দেখেছি যেখানে প্রতি মিনিটে লক্ষ লক্ষ আপডেট হয়৷ আমরা হয় বাল্ক API ব্যবহার করে আপডেটগুলি ব্যাচ করার সুপারিশ করি, যা আপনার কাজের চাপে বিলম্বিত করে, অথবা ইলাস্টিকসার্চে ঘন ঘন আপডেটের সম্মুখীন হলে বিকল্প সমাধানের দিকে তাকানো।
ক্লাউডে নির্মিত রকসেট, একটি অনুসন্ধান এবং বিশ্লেষণ ডেটাবেস, ইলাস্টিকসার্চের একটি পরিবর্তনযোগ্য বিকল্প। RocksDB- তে নির্মিত হচ্ছে, একটি মূল-মূল্যের দোকান যা এর পরিবর্তনশীলতার জন্য জনপ্রিয়, রকসেট নথিতে স্থানান্তর আপডেট করতে পারে। এর ফলে সম্পূর্ণ নথির পরিবর্তে শুধুমাত্র পৃথক ক্ষেত্রের মান আপডেট এবং পুনঃসূচীকরণ করা হয়।
আপনি যদি আপডেট-ভারী কাজের চাপের জন্য ইলাস্টিকসার্চ এবং রকসেটের কর্মক্ষমতা তুলনা করতে চান, তাহলে আপনি $300 ক্রেডিট সহ রকসেটের একটি বিনামূল্যের ট্রায়াল শুরু করতে পারেন।