চ্যাটি ইন্টারফেস কীভাবে এড়ানো যায়


10

পটভূমি: আমি একটি সার্ভার অ্যাপ্লিকেশন ডিজাইন করছি এবং বিভিন্ন সাবসিস্টেমের জন্য পৃথক dll গুলি তৈরি করছি। জিনিসগুলিকে সরল করার জন্য, আমার বলি যে আমার দুটি সাবসিস্টেম রয়েছে: 1) Users2)Projects

ব্যবহারকারীর সার্বজনীন ইন্টারফেসের মতো পদ্ধতি রয়েছে:

IEnumerable<User> GetUser(int id);

এবং প্রকল্পগুলির পাবলিক ইন্টারফেসের মতো একটি পদ্ধতি রয়েছে:

IEnumerable<User> GetProjectUsers(int projectId);

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

সমস্যা: আদর্শভাবে, Projectsসাবসিস্টেমটি ব্যবহারকারীর তথ্যও সংরক্ষণ করা উচিত নয় এবং এটি কোনও প্রকল্পে অংশ নেওয়া ব্যবহারকারীদের আইডি সংরক্ষণ করা উচিত। পরিবেশন করার জন্য GetProjectUsers, সেটিতে কল করতে হবে GetUserএর Usersপ্রত্যেক ব্যবহারকারীর আইডি নিজস্ব ডাটাবেসের মধ্যে সংরক্ষিত জন্য সিস্টেম। তবে এটির জন্য প্রচুর পৃথক GetUserকল প্রয়োজন যা Userসাবসিস্টেমের অভ্যন্তরে পৃথক পৃথক স্কেল কোয়েরি তৈরি করে । আমি সত্যিই এটি পরীক্ষা করে দেখিনি তবে এই চ্যাটি ডিজাইনটি সিস্টেমের স্কেলাবিলিটিটিকে প্রভাবিত করবে।

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

প্রশ্ন: কেউ এই সমস্ত ব্যক্তিগত GetUserকল চলাকালীন এড়িয়ে চলার সময় পৃথকীকরণের কোনও উপায়ের পরামর্শ দিতে পারেন GetProjectUsers?


উদাহরণস্বরূপ, আমার কাছে যে ধারণাটি ছিল তা হ'ল ব্যবহারকারীরা বাহ্যিক সিস্টেমগুলিকে একটি লেবেল-মান জুটির সাহায্যে ব্যবহারকারীদের "ট্যাগ" করতে এবং নির্দিষ্ট মান সহ ব্যবহারকারীদের অনুরোধ করার জন্য যেমন:

void AddUserTag(int userId, string tag, string value);
IEnumerable<User> GetUsersByTag(string tag, string value);

তারপরে প্রকল্পগুলি প্রকল্পে যুক্ত হওয়ার সাথে সাথে প্রতিটি ব্যবহারকারীকে ট্যাগ করতে পারে:

AddUserTag(userId,"project id", myProjectId.ToString());

এবং গেটপ্রজেক্ট ব্যবহারকারীদের সময়, এটি সমস্ত প্রকল্প ব্যবহারকারীদের একক কলে অনুরোধ করতে পারে:

var projectUsers = usersService.GetUsersByTag("project id", myProjectId.ToString());

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

উত্তর:


10

আপনার সিস্টেমে যা অনুপস্থিত তা হ'ল ক্যাশে।

তুমি বলো:

তবে এটির জন্য প্রচুর পৃথক GetUserকল প্রয়োজন যা Userসাবসিস্টেমের অভ্যন্তরে পৃথক পৃথক স্কেল কোয়েরি তৈরি করে ।

কোনও পদ্ধতিতে কলগুলির সংখ্যা এসকিউএল কোয়েরির সংখ্যার মতো হতে হবে না। আপনি একবার ব্যবহারকারীর সম্পর্কে তথ্য পাবেন, আপনি যদি একই তথ্য পরিবর্তন না করেন তবে কেন আবার জিজ্ঞাসা করবেন? খুব সম্ভবত, আপনি এমনকি মেমরির সমস্ত ব্যবহারকারীকেও ক্যাশে করতে পারেন, যার ফলস্বরূপ শূন্য এসকিউএল কোয়েরি হবে (কোনও ব্যবহারকারী পরিবর্তন না হলে)।

অন্যদিকে, Projectsপ্রকল্পগুলি এবং ব্যবহারকারীদের উভয়কে সাবসিস্টেমের ক্যোয়ারী তৈরি করে INNER JOINআপনি একটি অতিরিক্ত সমস্যা প্রবর্তন করেছেন: আপনি আপনার কোডে দুটি পৃথক স্থানে একই টুকরো প্রশ্নের সন্ধান করছেন, ক্যাশে অবৈধকরণকে অত্যন্ত কঠিন করে তুলছেন। এর ফলে:

  • হয় আপনি পরে কোনও সময় ক্যাশে প্রবর্তন করবেন না,

  • অথবা আপনি সপ্তাহে বা মাস ব্যয় করবেন অধ্যয়ন করতে হবে কি যখন তথ্য একটি অংশ পরিবর্তন,

  • অথবা আপনি সরল অবস্থানগুলিতে ক্যাশে অবৈধকরণ যুক্ত করবেন, অন্যগুলি ভুলে যাবেন এবং ফলস্বরূপ বাগগুলি খুঁজে পেতে অসুবিধা হবে।


আপনার প্রশ্নটি পুনরায় পড়াতে আমি একটি কীওয়ার্ডটি লক্ষ্য করেছি যা আমি প্রথমবারের মতো মিস করেছি: স্কেলাবিলিটি । থাম্বের নিয়ম হিসাবে, আপনি পরবর্তী প্যাটার্নটি অনুসরণ করতে পারেন:

  1. আপনার সিস্টেমটি ধীরগতির কিনা তা জিজ্ঞাসা করুন (যেমন এটি কার্য সম্পাদনের অ-কার্যকরী প্রয়োজনকে লঙ্ঘন করে, বা কেবল ব্যবহারের জন্য একটি দুঃস্বপ্ন)।

    সিস্টেম যদি না ধীর কর্মক্ষমতা সম্পর্কে বিরক্ত করবেন না। পরিষ্কার কোড, পঠনযোগ্যতা, রক্ষণাবেক্ষণযোগ্যতা, পরীক্ষা, শাখা কভারেজ, পরিষ্কার নকশা, বিশদ এবং ডকুমেন্টেশন বোঝার জন্য সহজ, ভাল কোড মন্তব্য সম্পর্কে বিরক্ত করুন।

  2. যদি হ্যাঁ, বাধাটি অনুসন্ধান করুন। আপনি অনুমান করে নয়, প্রোফাইলিংয়ের মাধ্যমে তা করেন । প্রোফাইলিংয়ের মাধ্যমে, আপনি বাধাটির সঠিক অবস্থানটি নির্ধারণ করুন (যখন আপনি অনুমান করেন , আপনি প্রায় প্রতিবারই এটি ভুল হয়ে যেতে পারেন), এবং এখন কোডের সেই অংশটিতে ফোকাস করতে পারেন।

  3. বাধা পাওয়া গেলে সমাধানগুলি অনুসন্ধান করুন। আপনি অনুমান করা, বেঞ্চমার্কিং, প্রোফাইলিং, বিকল্পগুলি লেখার সংকলন অপ্টিমাইজেশানগুলি বোঝার, আপনার উপর নির্ভরযোগ্য অপটিমাইজেশনগুলি বোঝার, স্ট্যাক ওভারফ্লো সম্পর্কিত প্রশ্ন জিজ্ঞাসা করে এবং নিম্ন স্তরের ভাষাগুলিতে স্থানান্তর (প্রয়োজনীয় হলে এসেমব্লার সহ) দ্বারা এটি করেন।

Projectsসাবসিস্টেমের কাছে সাবসিস্টেমের কাছে তথ্য চাওয়ার আসল সমস্যাটি কী Users?

ভবিষ্যতের স্কেলিবিলিটি সমস্যাটি কী? এটি কোনও সমস্যা নয়। স্কেল্যাবিলিটি একটি দুঃস্বপ্নে পরিণত হতে পারে যদি আপনি একত্রীকরণ সমাধানে সমস্ত কিছু একত্রীকরণ করতে বা একাধিক অবস্থান থেকে একই ডেটা অনুসন্ধান করতে শুরু করেন (ক্যাশে প্রবর্তন করতে অসুবিধার কারণে নীচে ব্যাখ্যা করা হয়েছে)।

যদি ইতিমধ্যে লক্ষণীয় পারফরম্যান্সের সমস্যা থাকে তবে, পদক্ষেপ 2, বাধাটি অনুসন্ধান করুন।

যদি এটি উপস্থিত হয় তবে প্রকৃতপক্ষে, বাধাটি উপস্থিত রয়েছে এবং এটি সাবসিস্টেমের Projectsমাধ্যমে ব্যবহারকারীদের জন্য অনুরোধ করার Users(এবং ডাটাবেস অনুসন্ধানের স্তরে অবস্থিত) কারণে রয়েছে, তবেই আপনাকে বিকল্প অনুসন্ধান করতে হবে।

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


আমি আপনাকে ভুল বোঝাবুঝি না করে আপনি "স্বতন্ত্র গেটউজার কল রাখুন, তবে ডিবি রাউন্ডট্রিপগুলি এড়ানোর জন্য ক্যাচিং ব্যবহার করুন" saying
এরেন এরনেজমেজ

@ এরেনারসনেমেজ: GetUserডাটাবেস অনুসন্ধানের পরিবর্তে ক্যাশে সন্ধান করবেন। এর অর্থ হ'ল আপনি কতবার কল করবেন তা আসলে কোনও ব্যাপার নয় GetUser, যেহেতু এটি ডাটাবেসের পরিবর্তে মেমরি থেকে ডেটা লোড করবে (যদি না ক্যাশেটি অবৈধ করা না থাকে)।
আর্সেনি মোরজেঙ্কো

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

@ ইরেনআর্সনেমেজ: আপনার যত বেশি ডেটা থাকবে ততই সমালোচনামূলক ক্যাশে উপস্থিত হবে। থাম্বের নিয়ম হিসাবে, পঠনের সংখ্যাটিকে লেখকের সংখ্যার সাথে তুলনা করুন। যদি প্রতিদিন "হাজার" ডকুমেন্ট যুক্ত হয় এবং এখানে প্রতিদিন কয়েক মিলিয়ন selectকোয়েরি থাকে তবে আপনি ক্যাচিং ব্যবহার করে আরও ভাল। অন্যদিকে, আপনি যদি একটি ডাটাবেসে কোটি কোটি সত্ত্বা যুক্ত করে থাকেন তবে selectখুব বেছে বেছে কয়েকটি সহ কয়েক হাজার পেতে থাকেন তবে whereক্যাচিং এটি কার্যকর নাও হতে পারে।
আর্সেনি মোরজেঙ্কো

আপনি সম্ভবত সঠিক - আমি সম্ভবত আমার এখনও নেই এমন একটি সমস্যা সমাধানের চেষ্টা করছি। আমি সম্ভবত হিসাবে বাস্তবায়ন করব এবং প্রয়োজনে পরে উন্নতি করার চেষ্টা করব। যদি ক্যাচিং যথাযথ না হয় কারণ, যেমন, সত্তাগুলি যুক্ত হওয়ার পরে কেবল 1-2 বার পড়ার সম্ভাবনা রয়েছে, আপনি কি মনে করেন যে আমি যে সমাধান করেছি তাতে আমি যে প্রশ্নটি যুক্ত করেছি তা কাজ করতে পারে? আপনি কি একটি বিশাল সমস্যা দেখতে পাচ্ছেন?
এরেন এরনেসমেজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.