যখন আপনার একটি বড় কোডবেস থাকে, তখন নির্ভরতার চেইনগুলি খুব গভীর হতে পারে। এমনকি সাধারণ বাইনারিগুলি প্রায়শই হাজার হাজার বিল্ড লক্ষ্যের উপর নির্ভর করতে পারে। এই স্কেলে, একটি একক মেশিনে যুক্তিসঙ্গত সময়ের মধ্যে একটি বিল্ড সম্পূর্ণ করা অসম্ভব: কোনও বিল্ড সিস্টেম একটি মেশিনের হার্ডওয়্যারে আরোপিত পদার্থবিজ্ঞানের মৌলিক আইনের কাছাকাছি যেতে পারে না। এই কাজটি করার একমাত্র উপায় হল একটি বিল্ড সিস্টেম যা ডিস্ট্রিবিউটেড বিল্ডগুলিকে সমর্থন করে যেখানে সিস্টেমের দ্বারা কাজ করার ইউনিটগুলি নির্বিচারে এবং মাপযোগ্য সংখ্যক মেশিনে ছড়িয়ে পড়ে। ধরে নিই যে আমরা সিস্টেমের কাজটিকে যথেষ্ট ছোট ছোট ইউনিটে (পরবর্তীতে আরও বেশি) বিভক্ত করেছি, এটি আমাদের যে কোনও আকারের যে কোনও বিল্ডকে যত তাড়াতাড়ি আমরা অর্থ প্রদান করতে ইচ্ছুক তা সম্পূর্ণ করতে অনুমতি দেবে। এই স্কেলেবিলিটি হল পবিত্র গ্রেইল যা আমরা একটি আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেমকে সংজ্ঞায়িত করার মাধ্যমে কাজ করছি।
রিমোট ক্যাশিং
বিতরণ করা বিল্ডের সবচেয়ে সহজ ধরন হল এমন একটি যা শুধুমাত্র দূরবর্তী ক্যাশিং ব্যবহার করে, যা চিত্র 1 এ দেখানো হয়েছে।
চিত্র 1 । একটি বিতরণ করা বিল্ড রিমোট ক্যাশিং দেখাচ্ছে
বিকাশকারী ওয়ার্কস্টেশন এবং ক্রমাগত ইন্টিগ্রেশন সিস্টেম উভয় সহ বিল্ডগুলি সম্পাদন করে এমন প্রতিটি সিস্টেম একটি সাধারণ রিমোট ক্যাশে পরিষেবার একটি রেফারেন্স শেয়ার করে। এই পরিষেবাটি হতে পারে একটি দ্রুত এবং স্থানীয় স্বল্প-মেয়াদী স্টোরেজ সিস্টেম যেমন Redis বা Google ক্লাউড স্টোরেজের মতো একটি ক্লাউড পরিষেবা৷ যখনই কোনো ব্যবহারকারীর কোনো আর্টিফ্যাক্ট তৈরি করার প্রয়োজন হয়, সরাসরি হোক বা নির্ভরতা হিসেবে, সিস্টেমটি প্রথমে রিমোট ক্যাশে দিয়ে চেক করে যে সেই আর্টিফ্যাক্টটি সেখানে আগে থেকেই আছে কিনা। যদি তাই হয়, তবে এটি নির্মাণের পরিবর্তে আর্টিফ্যাক্ট ডাউনলোড করতে পারে। যদি না হয়, সিস্টেমটি নিজেই আর্টিফ্যাক্ট তৈরি করে এবং ফলাফলটি ক্যাশে আবার আপলোড করে। এর মানে হল যে নিম্ন-স্তরের নির্ভরতাগুলি যেগুলি প্রায়শই পরিবর্তিত হয় না সেগুলি একবার তৈরি করা যেতে পারে এবং প্রতিটি ব্যবহারকারীর দ্বারা পুনর্নির্মিত হওয়ার পরিবর্তে ব্যবহারকারীদের মধ্যে ভাগ করা যেতে পারে। Google-এ, অনেক আর্টিফ্যাক্ট স্ক্র্যাচ থেকে তৈরি করার পরিবর্তে একটি ক্যাশে থেকে পরিবেশন করা হয়, যা আমাদের বিল্ড সিস্টেম চালানোর খরচকে ব্যাপকভাবে হ্রাস করে।
একটি দূরবর্তী ক্যাশিং সিস্টেম কাজ করার জন্য, বিল্ড সিস্টেমকে অবশ্যই গ্যারান্টি দিতে হবে যে বিল্ডগুলি সম্পূর্ণরূপে পুনরুত্পাদনযোগ্য। অর্থাৎ, যেকোন বিল্ড টার্গেটের জন্য, সেই টার্গেটে ইনপুটের সেট নির্ধারণ করা অবশ্যই সম্ভব হবে যাতে একই সেট ইনপুট যেকোন মেশিনে ঠিক একই আউটপুট তৈরি করে। এটি নিশ্চিত করার একমাত্র উপায় যে একটি আর্টিফ্যাক্ট ডাউনলোড করার ফলাফলগুলি এটিকে তৈরি করার ফলাফলের মতোই। মনে রাখবেন যে এটির জন্য ক্যাশে প্রতিটি আর্টিফ্যাক্টকে তার লক্ষ্য এবং তার ইনপুটগুলির একটি হ্যাশ উভয়ের উপর চাবিকাঠি করা প্রয়োজন - এইভাবে, বিভিন্ন প্রকৌশলী একই সময়ে একই লক্ষ্যে বিভিন্ন পরিবর্তন করতে পারে এবং দূরবর্তী ক্যাশে সমস্ত কিছু সংরক্ষণ করবে। ফলে শিল্পকর্ম এবং বিরোধ ছাড়াই যথাযথভাবে তাদের পরিবেশন করুন।
অবশ্যই, একটি দূরবর্তী ক্যাশে থেকে কোনও সুবিধা পাওয়ার জন্য, একটি আর্টিফ্যাক্ট ডাউনলোড করা এটি তৈরির চেয়ে দ্রুত হওয়া দরকার। এটি সর্বদা হয় না, বিশেষ করে যদি ক্যাশে সার্ভারটি মেশিন তৈরি করা থেকে দূরে থাকে। Google-এর নেটওয়ার্ক এবং বিল্ড সিস্টেমটি সতর্কতার সাথে টিউন করা হয়েছে যাতে দ্রুত বিল্ড ফলাফল শেয়ার করা যায়।
দূরবর্তী মৃত্যুদন্ড
রিমোট ক্যাশিং একটি সত্য বিতরণ করা বিল্ড নয়। যদি ক্যাশে হারিয়ে যায় বা আপনি যদি একটি নিম্ন-স্তরের পরিবর্তন করেন যার জন্য সবকিছু পুনর্নির্মাণের প্রয়োজন হয়, তবে আপনাকে এখনও আপনার মেশিনে স্থানীয়ভাবে সম্পূর্ণ বিল্ডটি সম্পাদন করতে হবে। প্রকৃত লক্ষ্য হল দূরবর্তী কার্য সম্পাদনকে সমর্থন করা, যেখানে বিল্ড করার প্রকৃত কাজ যেকোন সংখ্যক কর্মীদের মধ্যে ছড়িয়ে দেওয়া যেতে পারে। চিত্র 2 একটি দূরবর্তী এক্সিকিউশন সিস্টেমকে চিত্রিত করে।
চিত্র 2 । একটি দূরবর্তী মৃত্যুদন্ড কার্যকর করার সিস্টেম
প্রতিটি ব্যবহারকারীর মেশিনে চলমান বিল্ড টুল (যেখানে ব্যবহারকারীরা হয় মানব প্রকৌশলী বা স্বয়ংক্রিয় বিল্ড সিস্টেম) একটি কেন্দ্রীয় বিল্ড মাস্টারকে অনুরোধ পাঠায়। বিল্ড মাস্টার অনুরোধগুলিকে তাদের কম্পোনেন্ট অ্যাকশনে ভেঙ্গে দেয় এবং কর্মীদের একটি স্কেলযোগ্য পুলের উপর সেই অ্যাকশনগুলির সম্পাদনের সময়সূচী করে। প্রতিটি কর্মী ব্যবহারকারীর দ্বারা নির্দিষ্ট করা ইনপুটগুলির সাথে এটির জিজ্ঞাসা করা ক্রিয়াগুলি সম্পাদন করে এবং ফলস্বরূপ শিল্পকর্মগুলি লেখে। চূড়ান্ত আউটপুট তৈরি এবং ব্যবহারকারীর কাছে পাঠানো না হওয়া পর্যন্ত এই নিদর্শনগুলি অন্যান্য মেশিনে ক্রিয়া সম্পাদনের জন্য ভাগ করা হয় যা তাদের প্রয়োজন।
এই ধরনের সিস্টেম বাস্তবায়নের সবচেয়ে জটিল অংশ হল শ্রমিক, মাস্টার এবং ব্যবহারকারীর স্থানীয় মেশিনের মধ্যে যোগাযোগ পরিচালনা করা। শ্রমিকরা অন্যান্য কর্মীদের দ্বারা উত্পাদিত মধ্যবর্তী শিল্পকর্মের উপর নির্ভর করতে পারে এবং চূড়ান্ত আউটপুট ব্যবহারকারীর স্থানীয় মেশিনে ফেরত পাঠানো দরকার। এটি করার জন্য, আমরা প্রতিটি কর্মীকে তার ফলাফলগুলি লিখতে এবং ক্যাশে থেকে তার নির্ভরতা পড়তে দিয়ে পূর্বে বর্ণিত বিতরণ করা ক্যাশের উপরে তৈরি করতে পারি। মাস্টার তাদের উপর নির্ভরশীল সবকিছু শেষ না হওয়া পর্যন্ত কর্মীদের এগিয়ে যেতে বাধা দেয়, এই ক্ষেত্রে তারা ক্যাশে থেকে তাদের ইনপুট পড়তে সক্ষম হবে। চূড়ান্ত পণ্যটিও ক্যাশে করা হয়, স্থানীয় মেশিনকে এটি ডাউনলোড করার অনুমতি দেয়। নোট করুন যে ব্যবহারকারীর উত্স গাছে স্থানীয় পরিবর্তনগুলি রপ্তানি করার জন্য আমাদের একটি পৃথক উপায়ও প্রয়োজন যাতে শ্রমিকরা নির্মাণের আগে সেই পরিবর্তনগুলি প্রয়োগ করতে পারে৷
এটি কাজ করার জন্য, পূর্বে বর্ণিত আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেমের সমস্ত অংশ একত্রিত হওয়া প্রয়োজন। পরিবেশ তৈরি করতে হবে সম্পূর্ণ স্ব-বর্ণনামূলক যাতে আমরা মানুষের হস্তক্ষেপ ছাড়াই শ্রমিকদের স্পিন করতে পারি। বিল্ড প্রসেসগুলি অবশ্যই সম্পূর্ণরূপে স্বয়ংসম্পূর্ণ হতে হবে কারণ প্রতিটি পদক্ষেপ একটি ভিন্ন মেশিনে কার্যকর করা যেতে পারে। আউটপুট সম্পূর্ণরূপে নির্ধারক হতে হবে যাতে প্রতিটি কর্মী অন্য কর্মীদের কাছ থেকে প্রাপ্ত ফলাফলগুলিতে বিশ্বাস করতে পারে। একটি টাস্ক-ভিত্তিক সিস্টেমের জন্য এই ধরনের গ্যারান্টিগুলি প্রদান করা অত্যন্ত কঠিন, যা একটির উপরে একটি নির্ভরযোগ্য রিমোট এক্সিকিউশন সিস্টেম তৈরি করা প্রায় অসম্ভব করে তোলে।
Google এ বিতরণ করা বিল্ড
2008 সাল থেকে, Google একটি ডিস্ট্রিবিউটেড বিল্ড সিস্টেম ব্যবহার করছে যা রিমোট ক্যাশিং এবং রিমোট এক্সিকিউশন উভয়কেই নিয়োগ করে, যা চিত্র 3-এ দেখানো হয়েছে।
চিত্র 3 । Google এর বিতরণ করা বিল্ড সিস্টেম
গুগলের রিমোট ক্যাশেকে বলা হয় ObjFS। এটি একটি ব্যাকএন্ড নিয়ে গঠিত যা স্টোরগুলি আমাদের প্রোডাকশন মেশিনের বহরে বিতরণ করা Bigtables-এ আউটপুট তৈরি করে এবং objfsd নামে একটি ফ্রন্টএন্ড FUSE ডেমন যা প্রতিটি ডেভেলপারের মেশিনে চলে। FUSE ডেমন ইঞ্জিনিয়ারদের বিল্ড আউটপুট ব্রাউজ করার অনুমতি দেয় যেন তারা ওয়ার্কস্টেশনে সংরক্ষিত সাধারণ ফাইল, কিন্তু ফাইল সামগ্রী শুধুমাত্র ব্যবহারকারীর দ্বারা সরাসরি অনুরোধ করা কয়েকটি ফাইলের জন্য চাহিদা অনুযায়ী ডাউনলোড করা হয়। চাহিদা অনুযায়ী ফাইলের বিষয়বস্তু পরিবেশন করা নেটওয়ার্ক এবং ডিস্ক উভয়ের ব্যবহারকে ব্যাপকভাবে হ্রাস করে এবং আমরা যখন বিকাশকারীর স্থানীয় ডিস্কে সমস্ত বিল্ড আউটপুট সংরক্ষণ করি তখন সিস্টেমটি দ্বিগুণ দ্রুত তৈরি করতে সক্ষম হয়৷
গুগলের রিমোট এক্সিকিউশন সিস্টেমকে ফোরজ বলা হয়। ব্লেজের একজন ফোর্জ ক্লায়েন্ট (বাজেলের অভ্যন্তরীণ সমতুল্য) ডিস্ট্রিবিউটর নামক আমাদের ডেটাসেন্টারে চলমান একটি কাজের জন্য প্রতিটি কাজের জন্য অনুরোধ পাঠায় যাকে শিডিউলার বলা হয়। সময়সূচী কর্মের ফলাফলের একটি ক্যাশ বজায় রাখে, এটিকে সিস্টেমের অন্য কোনো ব্যবহারকারীর দ্বারা ক্রিয়াটি তৈরি করা হলে অবিলম্বে একটি প্রতিক্রিয়া ফেরত দেওয়ার অনুমতি দেয়। যদি তা না হয়, তবে এটি একটি সারিতে কাজ করে। এক্সিকিউটর কাজের একটি বড় পুল এই সারি থেকে ক্রমাগত ক্রিয়াগুলি পড়ে, সেগুলি সম্পাদন করে এবং ফলাফলগুলি সরাসরি ObjFS Bigtables-এ সংরক্ষণ করে। এই ফলাফলগুলি ভবিষ্যতের ক্রিয়াকলাপের জন্য নির্বাহকদের কাছে উপলব্ধ, অথবা শেষ ব্যবহারকারীর দ্বারা objfsd-এর মাধ্যমে ডাউনলোড করার জন্য।
শেষ ফলাফল হল এমন একটি সিস্টেম যা Google-এ সম্পাদিত সমস্ত বিল্ডকে দক্ষতার সাথে সমর্থন করার জন্য স্কেল করে। এবং Google-এর বিল্ডগুলির স্কেল সত্যিই বিশাল: Google লক্ষ লক্ষ বিল্ড চালায় লক্ষ লক্ষ টেস্ট কেস নির্বাহ করে এবং প্রতিদিন বিলিয়ন লাইনের সোর্স কোড থেকে পেটাবাইট বিল্ড আউটপুট তৈরি করে। এই ধরনের একটি সিস্টেম শুধুমাত্র আমাদের প্রকৌশলীদের দ্রুত জটিল কোডবেস তৈরি করতে দেয় না, এটি আমাদের বিল্ডের উপর নির্ভর করে এমন বিপুল সংখ্যক স্বয়ংক্রিয় সরঞ্জাম এবং সিস্টেম বাস্তবায়ন করতে দেয়।