1.1 শার্ডিং কি?

আপনি যদি ক্রমাগত গুগল করেন তবে দেখা যাচ্ছে যে তথাকথিত পার্টিশন এবং তথাকথিত শার্ডিংয়ের মধ্যে একটি বরং অস্পষ্ট সীমানা রয়েছে। সবাই যা খুশি ডাকে, যা খুশি ডাকে। কিছু লোক অনুভূমিক বিভাজন এবং শার্ডিংয়ের মধ্যে পার্থক্য করে। অন্যরা বলে যে শার্ডিং একটি নির্দিষ্ট ধরণের অনুভূমিক বিভাজন।

আমি একটি একক পরিভাষাগত মান খুঁজে পাইনি যা প্রতিষ্ঠাতা পিতাদের দ্বারা অনুমোদিত হবে এবং ISO দ্বারা প্রত্যয়িত হবে। ব্যক্তিগত অভ্যন্তরীণ প্রত্যয়টি এরকম কিছু: গড়পড়তা বিভাজন করা হল "বেসকে টুকরো টুকরো করা" একটি নির্বিচারে নেওয়া উপায়ে।

  • উল্লম্ব বিভাজন - কলাম দ্বারা। উদাহরণস্বরূপ, 60টি কলামে কয়েক বিলিয়ন রেকর্ড সহ একটি বিশাল টেবিল রয়েছে। এই ধরনের একটি দৈত্য টেবিল রাখার পরিবর্তে, আমরা প্রতিটি 2 বিলিয়ন রেকর্ডের কমপক্ষে 60টি দৈত্য টেবিল রাখি - এবং এটি একটি কলাম বেস নয়, উল্লম্ব বিভাজন (পরিভাষার উদাহরণ হিসাবে)।
  • অনুভূমিক বিভাজন - আমরা লাইন দ্বারা লাইন কাটা, হয়তো সার্ভারের ভিতরে।

এখানে বিশ্রী মুহূর্ত হল অনুভূমিক বিভাজন এবং শার্ডিংয়ের মধ্যে সূক্ষ্ম পার্থক্য। আমাকে টুকরো টুকরো করা যেতে পারে, কিন্তু এটা কী তা আমি নিশ্চিত করে বলতে পারব না। একটি অনুভূতি আছে যে শার্ডিং এবং অনুভূমিক বিভাজন একই জিনিস সম্পর্কে।

শার্ডিং হল, সাধারণভাবে, যখন ডাটাবেসের পরিপ্রেক্ষিতে একটি বড় টেবিল বা নথি, বস্তুর প্রো-সংগ্রহ, যদি আপনার কাছে একটি ডাটাবেস না থাকে, কিন্তু একটি নথির দোকান, বস্তু দ্বারা ঠিক কাটা হয়। অর্থাৎ, 2 বিলিয়ন অবজেক্ট থেকে, টুকরা নির্বাচন করা হয় তা যে আকারেই হোক না কেন। প্রতিটি বস্তুর ভিতরে থাকা বস্তুগুলিকে টুকরো টুকরো করা হয় না, আমরা সেগুলিকে আলাদা কলামে রাখি না, যথা, আমরা সেগুলিকে বিভিন্ন জায়গায় ব্যাচে করে রাখি।

সূক্ষ্ম পরিভাষাগত পার্থক্য আছে। উদাহরণস্বরূপ, তুলনামূলকভাবে বলতে গেলে, পোস্টগ্রেস ডেভেলপাররা বলতে পারেন যে অনুভূমিক বিভাজন হল যখন মূল টেবিলটি বিভক্ত করা সমস্ত টেবিল একই স্কিমাতে থাকে এবং যখন বিভিন্ন মেশিনে এটি ইতিমধ্যেই শার্ডিং হয়।

একটি সাধারণ অর্থে, একটি নির্দিষ্ট ডাটাবেস এবং একটি নির্দিষ্ট ডেটা ম্যানেজমেন্ট সিস্টেমের পরিভাষার সাথে আবদ্ধ না হয়ে, এমন একটি অনুভূতি রয়েছে যে শার্ডিংটি কেবল লাইন / ডকুমেন্ট দ্বারা ডকুমেন্টের লাইন স্লাইসিং, এবং তাই - এটিই সব।

আমি সাধারণত জোর দেওয়া. এই অর্থে যে আমরা 2 বিলিয়ন নথিকে 20টি টেবিলে কাটার জন্যই এই সব করছি না, যার প্রত্যেকটি আরও পরিচালনাযোগ্য হবে, তবে এটিকে অনেকগুলি কোর, অনেকগুলি ডিস্ক বা বিভিন্ন শারীরিক বা ভার্চুয়াল সার্ভারে বিতরণ করার জন্য।

1.2 অবিভাজ্যকে ভাগ করুন

এটি বোঝা যায় যে আমরা এটি করি যাতে প্রতিটি শার্ড - প্রতিটি ডেটার টুকরো - বহুবার প্রতিলিপি করা হয়। কিন্তু সত্যিই, না.

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

প্রকৃতপক্ষে, আপনি যদি ডেটার এমন একটি স্লাইসিং করেন, এবং আপনার সাহসী ল্যাপটপে MySQL-এর একটি বিশাল এসকিউএল টেবিল থেকে, আপনি একটি ল্যাপটপের বাইরে না গিয়ে 16টি ছোট টেবিল তৈরি করবেন, একটি একক স্কিমা নয়, একটি ডাটাবেস নয়, ইত্যাদি। . এবং তাই - এটা, আপনি ইতিমধ্যে শার্ডিং আছে.

এর ফলে নিম্নলিখিত হয়:

  • ব্যান্ডউইথ বাড়ে।
  • লেটেন্সি পরিবর্তিত হয় না, অর্থাৎ, প্রতিটি, তাই কথা বলতে, এই ক্ষেত্রে কর্মী বা ভোক্তা, তার নিজের পায়। বিভিন্ন অনুরোধ প্রায় একই সময়ে পরিসেবা করা হয়.
  • অথবা উভয়, এবং অন্য, এবং উচ্চ প্রাপ্যতা (প্রতিলিপি)।

কেন ব্যান্ডউইথ? আমাদের মাঝে মাঝে এমন তথ্যের পরিমাণ থাকতে পারে যেগুলি মাপসই হয় না - এটা পরিষ্কার নয় যে কোথায়, কিন্তু তারা মাপসই হয় না - 1 {কার্নেল | ডিস্ক | সার্ভার | ...} শুধু পর্যাপ্ত সম্পদ নেই, এই সব. এই বড় ডেটাসেটের সাথে কাজ করার জন্য, আপনাকে এটি কাটাতে হবে।

কেন বিলম্ব? একটি কোরে, 2 বিলিয়ন সারির একটি টেবিল স্ক্যান করা 20টি কোরে 20টি টেবিল স্ক্যান করার চেয়ে 20 গুণ ধীর, এটি সমান্তরালভাবে করা। ডেটা একটি একক সংস্থানে খুব ধীরে ধীরে প্রক্রিয়া করা হয়।

কেন উচ্চ প্রাপ্যতা? অথবা আমরা একই সময়ে উভয় করার জন্য ডেটা কেটে ফেলি, এবং একই সময়ে প্রতিটি শার্ডের বেশ কয়েকটি কপি - প্রতিলিপি উচ্চ প্রাপ্যতা নিশ্চিত করে।

1.3 একটি সহজ উদাহরণ "কিভাবে এটি হাত দিয়ে করা যায়"

32টি নথির জন্য টেস্ট টেবিল test.documents ব্যবহার করে শর্তসাপেক্ষ শার্ডিং কাটা যায় এবং এই টেবিল থেকে 16টি টেস্ট টেবিল তৈরি করা হয়, প্রতিটি test.docs00, 01, 02, ..., 15টি প্রায় 2টি নথি।

INSERT INTO docs00 
SELECT * FROM documents WHERE (id%16)=0 
... 
 
INSERT INTO docs15 
SELECT * FROM documents WHERE (id%16)=15 

কেন সম্পর্কে? কারণ একটি অগ্রাধিকার আমরা জানি না কিভাবে আইডি বিতরণ করা হয়, যদি 1 থেকে 32 পর্যন্ত অন্তর্ভুক্ত থাকে, তাহলে প্রতিটিতে ঠিক 2টি নথি থাকবে, অন্যথায় নয়।

আমরা এখানে এটা কেন. আমরা 16টি টেবিল তৈরি করার পরে, আমরা আমাদের যা প্রয়োজন তার 16টি "দখল" করতে পারি। আমরা যা আঘাত করি না কেন, আমরা এই সম্পদগুলিকে সমান্তরাল করতে পারি। উদাহরণস্বরূপ, যদি পর্যাপ্ত ডিস্কে স্থান না থাকে, তাহলে আলাদা ডিস্কে এই টেবিলগুলিকে পচন করাটা বোধগম্য হবে।

এই সব, দুর্ভাগ্যবশত, বিনামূল্যে নয়. আমি সন্দেহ করি যে ক্যানোনিকাল এসকিউএল স্ট্যান্ডার্ডের ক্ষেত্রে (আমি দীর্ঘদিন ধরে এসকিউএল স্ট্যান্ডার্ডটি পুনরায় পড়িনি, সম্ভবত এটি দীর্ঘ সময়ের জন্য আপডেট করা হয়নি), কোনও এসকিউএল সার্ভারে বলার জন্য কোনও সরকারী প্রমিত সিনট্যাক্স নেই : "প্রিয় এসকিউএল সার্ভার, আমাকে 32টি শার্ড তৈরি করুন এবং সেগুলিকে 4টি ডিস্কে ভাগ করুন৷ কিন্তু স্বতন্ত্র বাস্তবায়নে, প্রায়শই মূলত একই জিনিস করার জন্য একটি নির্দিষ্ট সিনট্যাক্স থাকে। PostgreSQL-এর পার্টিশন করার ব্যবস্থা আছে, MySQL-এ MariaDB আছে, ওরাকল সম্ভবত এই সব অনেক আগেই করেছিল।

তবুও, যদি আমরা এটি হাতে করে করি, ডাটাবেস সমর্থন ছাড়াই এবং স্ট্যান্ডার্ডের কাঠামোর মধ্যে, তবে আমরা ডেটা অ্যাক্সেসের জটিলতার সাথে শর্তসাপেক্ষে অর্থ প্রদান করি । যেখানে একটি সাধারণ SELECT * FROM নথি WHERE id=123 ছিল, এখন 16 x SELECT * FROM docsXX। এবং এটা ভাল যদি আমরা চাবি দ্বারা রেকর্ড পেতে চেষ্টা. অনেক বেশি আকর্ষণীয় যদি আমরা রেকর্ডের প্রাথমিক পরিসর পেতে চেষ্টা করছি। এখন (যদি আমরা, আমি জোর দিয়ে বলি, যেমনটি ছিল, বোকা, এবং স্ট্যান্ডার্ডের কাঠামোর মধ্যে থাকি), এই 16 SELECT * FROM-এর ফলাফলগুলিকে অ্যাপ্লিকেশনটিতে একত্রিত করতে হবে।

আপনি কি কর্মক্ষমতা পরিবর্তন আশা করতে পারেন?

  • স্বজ্ঞাতভাবে - রৈখিক।
  • তাত্ত্বিকভাবে - সাবলাইনার, কারণ Amdahl আইন.
  • কার্যত, হয়তো প্রায় রৈখিকভাবে, হয়তো না।

আসলে, সঠিক উত্তর অজানা। শার্ডিং কৌশলের একটি চতুর প্রয়োগের মাধ্যমে, আপনি আপনার অ্যাপ্লিকেশনের কার্যক্ষমতায় একটি উল্লেখযোগ্য সুপার-লিনিয়ার অবনতি অর্জন করতে পারেন, এবং এমনকি DBA একটি লাল-হট জুজু নিয়ে ছুটে আসবে।

দেখা যাক কিভাবে এটি অর্জন করা যায়। এটা স্পষ্ট যে PostgreSQL shards=16 তে সেটিংস সেট করা, এবং তারপরে এটি নিজেই বন্ধ হয়ে যায়, এটি আকর্ষণীয় নয়। আসুন আমরা কীভাবে নিশ্চিত করতে পারি যে আমরা 32 এর মধ্যে 16 বার শার্ডিং থেকে ধীর হয়ে যাই - এটি কীভাবে করবেন না তার দৃষ্টিকোণ থেকে এটি আকর্ষণীয়।

আমাদের গতি বাড়ানো বা ধীর করার প্রচেষ্টা সর্বদা ক্লাসিকের মধ্যে চলে যাবে - ভাল পুরানো আমদাহল আইন, যা বলে যে কোনও অনুরোধের কোনও নিখুঁত সমান্তরাল নেই, সবসময় কিছু সামঞ্জস্যপূর্ণ অংশ থাকে।

1.4 আমদহল আইন

সবসময় একটি ক্রমিক অংশ আছে.

ক্যোয়ারী এক্সিকিউশনের একটি অংশ সবসময়ই সমান্তরাল হয় এবং সবসময় একটি অংশ থাকে যা সমান্তরাল হয় না। এমনকি যদি আপনার কাছে এটি একটি সম্পূর্ণ সমান্তরাল প্রশ্ন বলে মনে হয়, অন্তত প্রতিটি শার্ড থেকে প্রাপ্ত সারিগুলি থেকে আপনি ক্লায়েন্টকে যে ফলাফল পাঠাতে যাচ্ছেন তার সংগ্রহ সর্বদা সেখানে থাকে এবং এটি সর্বদা অনুক্রমিক হয়।

সবসময় কিছু সামঞ্জস্যপূর্ণ অংশ আছে. এটি ক্ষুদ্র হতে পারে, সাধারণ পটভূমিতে সম্পূর্ণরূপে অদৃশ্য হতে পারে, এটি বিশাল হতে পারে এবং সেই অনুযায়ী, দৃঢ়ভাবে সমান্তরালকরণকে প্রভাবিত করে, তবে এটি সর্বদা বিদ্যমান।

উপরন্তু, এর প্রভাব পরিবর্তিত হচ্ছে এবং উল্লেখযোগ্যভাবে বৃদ্ধি পেতে পারে, উদাহরণস্বরূপ, যদি আমরা আমাদের টেবিলটি কেটে ফেলি - আসুন স্টেক বাড়াই - 64টি রেকর্ড থেকে 4টি রেকর্ডের 16টি টেবিলে, এই অংশটি পরিবর্তিত হবে। অবশ্যই, এত বিপুল পরিমাণ ডেটা দ্বারা বিচার করে, আমরা একটি মোবাইল ফোন এবং একটি 2 MHz 86 প্রসেসরে কাজ করছি এবং আমাদের কাছে পর্যাপ্ত ফাইল নেই যা একই সাথে খোলা রাখা যায়। দৃশ্যত, এই ধরনের ইনপুট দিয়ে, আমরা একবারে একটি ফাইল খুলি।

  • এটি ছিল মোট = সিরিয়াল + সমান্তরাল । যেখানে, উদাহরণস্বরূপ, সমান্তরাল ডিবির ভিতরে সমস্ত কাজ, এবং সিরিয়াল ক্লায়েন্টকে ফলাফল পাঠাচ্ছে।
  • হয়ে গেল Total2 = সিরিয়াল + সমান্তরাল/N + Xserial । উদাহরণস্বরূপ, যখন সামগ্রিকভাবে ORDER BY, Xserial>0.

এই সহজ উদাহরণ দিয়ে, আমি দেখানোর চেষ্টা করছি যে কিছু Xserial প্রদর্শিত হয়। সর্বদা একটি ক্রমিক অংশ থাকে এবং আমরা সমান্তরালভাবে ডেটা নিয়ে কাজ করার চেষ্টা করছি তা ছাড়াও, এই ডেটা স্লাইস করার জন্য একটি অতিরিক্ত অংশ রয়েছে। মোটামুটিভাবে বলতে গেলে, আমাদের প্রয়োজন হতে পারে:

  • ডাটাবেসের অভ্যন্তরীণ অভিধানে এই 16টি টেবিল খুঁজুন;
  • ফাইল খুলুন;
  • মেমরি বরাদ্দ;
  • মেমরি আনলোকেট;
  • একত্রিত ফলাফল;
  • কোরের মধ্যে সিঙ্ক্রোনাইজ করুন।

কিছু সিঙ্কের বাইরের প্রভাব এখনও প্রদর্শিত হয়৷ তারা তুচ্ছ হতে পারে এবং মোট সময়ের এক বিলিয়ন ভাগ দখল করতে পারে, কিন্তু তারা সর্বদা অ-শূন্য এবং সর্বদা সেখানে থাকে। তাদের সাহায্যে, আমরা শার্ডিংয়ের পরে নাটকীয়ভাবে কর্মক্ষমতা হারাতে পারি।

এটি আমদাহলের আইন সম্পর্কে একটি আদর্শ ছবি। এখানে গুরুত্বপূর্ণ বিষয় হল যে রেখাগুলি, যা আদর্শভাবে সোজা হওয়া উচিত এবং রৈখিকভাবে বৃদ্ধি করা উচিত, একটি অ্যাসিম্পটোটে চলে। কিন্তু যেহেতু ইন্টারনেট থেকে গ্রাফটি পড়া যায় না, তাই আমি আমার মতে সংখ্যা সহ আরও ভিজ্যুয়াল টেবিল তৈরি করেছি।

ধরা যাক আমাদের কাছে অনুরোধ প্রক্রিয়াকরণের কিছু ক্রমিক অংশ রয়েছে যা শুধুমাত্র 5% নেয়: সিরিয়াল = 0.05 = 1 / 20

স্বজ্ঞাতভাবে, মনে হবে যে একটি ক্রমিক অংশের সাথে যা অনুরোধ প্রক্রিয়াকরণের মাত্র 1/20 নেয়, যদি আমরা 20 কোরের জন্য অনুরোধ প্রক্রিয়াকরণকে সমান্তরাল করি, তাহলে এটি প্রায় 20 হয়ে যাবে, সবচেয়ে খারাপ ক্ষেত্রে 18 গুণ দ্রুত।

আসলে, গণিত একটি হৃদয়হীন জিনিস :

ওয়াল = 0.05 + 0.95/সংখ্যা_কোর, গতি = 1 / (0.05 + 0.95/সংখ্যা_কোর)

এটি দেখা যাচ্ছে যে আপনি যদি সাবধানে গণনা করেন, 5% এর ক্রমিক অংশ সহ, গতি হবে 10 গুণ (10.3), যা তাত্ত্বিক আদর্শের তুলনায় 51%।

8 কোর = 5.9 = 74%
10 কোর = 6.9 = 69%
20 কোর = 10.3 = 51%
40 কোর = 13.6 = 34%
128 কোর = 17.4 = 14%

যে কাজটিতে একজন কাজ করত তার জন্য 20টি কোর (20টি ডিস্ক, যদি আপনি চান) ব্যবহার করে, আমরা তাত্ত্বিকভাবে 20 বারের বেশি ত্বরণও পাব না, তবে অনুশীলনে - অনেক কম। অধিকন্তু, সমান্তরাল সংখ্যা বৃদ্ধির সাথে, অদক্ষতা ব্যাপকভাবে বৃদ্ধি পায়।

যখন মাত্র 1% ক্রমিক কাজ অবশিষ্ট থাকে এবং 99% সমান্তরাল হয়, তখন গতির মানগুলি কিছুটা উন্নত হয়:

8 কোর = 7.5 = 93%
16 কোর = 13.9 = 87%
32 কোর = 24.4 = 76%
64 কোর = 39.3 = 61%

একটি নিখুঁতভাবে থার্মোনিউক্লিয়ার কোয়েরির জন্য, যা স্বাভাবিকভাবেই সম্পূর্ণ হতে ঘন্টা খানেক সময় লাগে এবং প্রস্তুতিমূলক কাজ এবং ফলাফলের সমাবেশে খুব কম সময় লাগে (ক্রমিক = 0.001), আমরা ইতিমধ্যেই ভাল দক্ষতা দেখতে পাব:

8 কোর = 7.94 = 99%
16 কোর = 15.76 = 99%
32 কোর = 31.04 = 97%
64 কোর = 60.20 = 94%

দয়া করে মনে রাখবেন যে আমরা কখনই 100% দেখতে পাব না । বিশেষ করে ভাল ক্ষেত্রে, আপনি দেখতে পারেন, উদাহরণস্বরূপ, 99.999%, কিন্তু ঠিক 100% নয়।