এর মধ্যে রেলের মধ্যে একাধিক ডাটাবেস সংযোগ পুল থাকা কি সম্ভব?


12

একটু ব্যাকগ্রাউন্ড

আমি বহু বছর ধরে বহু-ভাড়াটে অ্যাপ চালানোর জন্য অ্যাপার্টমেন্টের রত্নটি ব্যবহার করে আসছি । এখন সম্প্রতি পৃথক হোস্টে ডাটাবেসটি স্কেল করার প্রয়োজনীয়তা এসে গেছে, ডিবি সার্ভারটি আর কিছু ধরে রাখতে পারে না (পড়তে এবং লেখাগুলি উভয়ই খুব বেশি হয়ে যায়) - এবং হ্যাঁ, আমি হার্ডওয়্যারটি সর্বোচ্চকে মাপা করেছি (উত্সর্গীকৃত হার্ডওয়্যার, c৪ টি কোর, ১২ টি এনভিএম-ই ড্রাইভ রেইড 10, 384 জিবি র‌্যাম ইত্যাদি)

আমি এই প্রতি-ভাড়াটে (1 ভাড়াটিয়া = 1 ডাটাবেস সংযোগ কনফিগারেশন / পুল) করার কথা বিবেচনা করছিলাম কারণ number-of-tenantsএটি অ্যাপ্লিকেশন কোড পরিবর্তনগুলি লোড না করে বার -বার আরও বেশি ক্ষমতা অর্জনের একটি "সহজ" এবং দক্ষ উপায় ।

এখন, আমি শীঘ্রই 5.2 এ উন্নীত করে রেলপথ চালাচ্ছি 4.2। আমি দেখতে পাচ্ছি যে রেল 6 প্রতি মডেল সংযোগ সংজ্ঞাগুলির জন্য সমর্থন যোগ করে, তবে এটি আমার যা প্রয়োজন তা সত্যিই নয়, কারণ আমার প্রতিটি 20 ভাড়াটে লোকের জন্য আমার পুরোপুরি মিররড ডাটাবেস স্কিমা রয়েছে। সাধারণত আমি অনুরোধ অনুযায়ী "ডাটাবেস" স্যুইচ করি (মিডওয়্যারের সাথে) বা ব্যাকগ্রাউন্ড জব (সাইডকিক মিডলওয়্যার), তবে এটি বর্তমানে তুচ্ছ এবং পরিচালিত অ্যাপার্টমেন্ট অ্যাপার্টমেন্ট রত্ন, কারণ এটি search_pathপোস্টগ্র্যাস্কল-এ কেবল সেট করে এবং প্রকৃত সংযোগটি পরিবর্তন করে না। প্রতি ভাড়াটে হোস্টিং কৌশলটিতে স্যুইচ করার সময় আমার অনুরোধ অনুযায়ী পুরো সংযোগটি স্যুইচ করা দরকার।

প্রশ্নাবলী:

  1. আমি বুঝতে পারি যে আমি ActiveRecord::Base.establish_connection(config)প্রতি অনুরোধ / পটভূমির কাজ করতে পারি - তবে, আমি যেমন বুঝতে পেরেছি, এটি সম্পূর্ণ নতুন ডাটাবেস সংযোগ হ্যান্ডশেক তৈরি করতে এবং একটি নতুন ডিবি পুলকে ট্রেনে ছড়িয়ে দেবে - ঠিক? আমার অনুমান যে আমার আবেদনের প্রতি একক অনুরোধে এই ধরণের ওভারহেড তৈরি করা একটি পারফরম্যান্স আত্মহত্যা।
  2. আমি তাই ভাবছি যে কেউ যদি প্রথম থেকেই একাধিক (মোট ২০ টি) ডাটাবেস সংযোগ / পুল (যেমন অ্যাপ্লিকেশন বুটে থাকে) এর রেল দিয়ে বিকল্প দেখতে পায় এবং কেবল অনুরোধ অনুসারে এই পুলগুলির মধ্যে স্যুইচ করে? যাতে তিনি ডিবি সংযোগগুলি ইতিমধ্যে তৈরি এবং ব্যবহারের জন্য প্রস্তুত।
  3. এগুলি কি কেবল একটি দরিদ্র ধারণা, এবং এর পরিবর্তে আমার কি আলাদা পদ্ধতির সন্ধান করা উচিত? উদাহরণস্বরূপ 1 অ্যাপ্লিকেশন উদাহরণ = একটি নির্দিষ্ট ভাড়াটেটির সাথে একটি নির্দিষ্ট সংযোগ। অথবা অন্য কিছু.


1
আপনার এই আরএলগুলিতে রইলগুলির গিটহাব সংগ্রহস্থলটিতে আগ্রহী হতে পারে যা আপনার বর্তমান রেল masterশাখায় সম্প্রতি প্রয়োজনীয় বৈশিষ্ট্যটি যুক্ত করেছে । রেলস ডিম চালানো কোনও বিকল্প হবে বা আপনার বর্তমান রেল সংস্করণে সেই বৈশিষ্ট্যটি ব্যাক-প্রাইটিং হবে?
চমত্কার

@ স্পিকারম্যান এর ActiveRecord::Base.connected_to(shard: :shard_one) do ... endঅর্থ হ'ল পুলটি পুনরায় ব্যবহার করা হবে, প্রতিবার পুরো নতুন সংযোগ তৈরির পরিবর্তে?
বেন

উত্তর:


4

আমি যেমন বুঝতে পেরেছি, বহু-প্রজাস্বত্ব অ্যাপের জন্য 4 টি প্যাটার্ন রয়েছে:

1. উত্সর্গীকৃত মডেল / একাধিক উত্পাদন পরিবেশ

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

এটি 1 ভাড়াটের জন্য 1 টি ইনস্ট্যান্স অ্যাপ্লিকেশন এবং 1 ডাটাবেস। উন্নয়নটি এমন সহজ হবে যেমন আপনি কেবল 1 ভাড়াটে পরিবেশন করেন। তবে আপনার যদি 100 জন ভাড়াটিয়া থাকে তবে ডিভোপের জন্য দুঃস্বপ্ন হবে।

২. ভাড়াটেদের দৈহিক বিভাজন

সমস্ত ভাড়াটে জন্য 1 উদাহরণ অ্যাপ্লিকেশন কিন্তু 1 ভাড়াটে জন্য 1 ডাটাবেস। এটিই আপনি অনুসন্ধান করছেন। আপনি ব্যবহার করতে পারেন ActiveRecord::Base.establish_connection(config), বা রত্ন ব্যবহার করে বা অন্যান্য পরামর্শ হিসাবে রেল 6 এ আপডেট করতে পারেন। নীচে (2) এর উত্তর দেখুন।

৩. বিচ্ছিন্ন স্কিমা মডেল / লজিকাল বিভাজন

বিচ্ছিন্ন স্কিমাতে, ভাড়াটে টেবিল বা ডাটাবেস উপাদানগুলি একটি লজিক্যাল স্কিমা বা নাম-স্থানের অধীনে গ্রুপ করা হয় এবং অন্যান্য ভাড়াটে স্কিমার থেকে পৃথক হয়, তবে স্কিমা একই ডাটাবেসের উদাহরণে হোস্ট করা হয়।

আপনি যেমন অ্যাপার্টমেন্ট মণির সাথে করেন তেমন সমস্ত ভাড়াটিয়ের জন্য 1 ইনস্ট্যান্স অ্যাপ্লিকেশন এবং 1 টি ডাটাবেস।

4. আংশিকভাবে বিচ্ছিন্ন উপাদান

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


(1) হিসাবে, ActiveRecord::Base.establish_connection(config)আপনি যদি সঠিকভাবে এটি ব্যবহার করেন তবে প্রতি অনুরোধের জন্য ডিবি হ্যান্ডশেকিং নয়। আপনি এখানে চেক করতে পারেন এবং সমস্ত মন্তব্য এখানে পড়তে পারেন ।

(২) হিসাবে, আপনি যদি ব্যবহার করতে না চান তবে আপনি establish_connectionরত্ন মাল্টিভার্স (এটি রেল ৪.২ এর জন্য কাজ করে) বা অন্যান্য রত্ন ব্যবহার করতে পারেন । অথবা, অন্যান্য পরামর্শ অনুসারে, আপনি রেল 6 এ আপডেট করতে পারেন।

সম্পাদনা করুন: মাল্টিভেসার রত্ন ব্যবহার করছে establish_connection। এটি সংযোজন করবে database.ymlএবং একটি বেস ক্লাস তৈরি করবে যাতে প্রতিটি সাবক্লাস একই সংযোগ / পুল ভাগ করে দেয়। মূলত, এটি আমাদের ব্যবহারের প্রচেষ্টা হ্রাস করে establish_connection

(3) হিসাবে, উত্তর:

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

তবে আপনার যদি অনেক ভাড়াটে থাকে তবে আমি পরামর্শ দিচ্ছি যে আপনি ভাড়াটে বা আংশিকভাবে বিচ্ছিন্ন উপাদানগুলির শারীরিক পৃথকীকরণটি আপনার ব্যবসায়িক প্রক্রিয়ার উপর নির্ভর করে।

যে কোনও উপায়েই, আপনাকে নতুন আর্কিটেকচারটি মেনে চলার জন্য আপনার অ্যাপ্লিকেশন আপডেট / পুনর্লিখন করতে হবে।


হাই, উত্তরের জন্য ধন্যবাদ. উত্তরগুলি উত্তম হিসাবে যদি সেগুলি ভাল সমাধান হয় তবে আমি পুরষ্কার দেওয়ার আগে আমার পরামর্শটি পরীক্ষা করার জন্য আমার একটু সময় প্রয়োজন।
নীলস ক্রিস্টিয়ান

1 এবং 2 এর সাথে আমার বেশ কয়েকটি প্রশ্ন রয়েছে। 1: আমি নিশ্চিত না যে আমি আপনার উল্লেখগুলি বুঝতে পেরেছি। আপনার বক্তব্য কি, যে আমি ডিবি হ্যান্ডশেক না করে / ডিবি পোল পুনরুদ্ধার না করে .establish_connication (কনফিগারেশন) কল করতে পারি? সেক্ষেত্রে আমি নিশ্চিত নই যে দুটি লিঙ্ক কীভাবে এটি ব্যাখ্যা করে? 2: মাল্টিভার্সের জন্য, পুরো অ্যাপ্লিকেশনের জন্য পুরো ডিবি সুইচের পরিবর্তে কোনও প্রতি-মডেল ডাটাবেসটি স্যুইচ করে না? আমি মনে করি তাদের ডকুমেন্টেশনগুলি খুব অস্পষ্ট
নীলস ক্রিস্টিয়ান

আমার মনে হয় আমার ভুল বোঝাবুঝি হয়েছে। আপনার এই বাক্যগুলিকে বিস্তারিতভাবে জানাতে আপত্তি আছে? আমি বুঝতে পারি যে আমি অনুরোধ / ব্যাকগ্রাউন্ড জব অনুসারে একটি অ্যাক্টিভেকর্ড :: বেস.স্টাবলিশ_কনেকশন (কনফিগারেশন) করতে পারি - তবে, আমি যেমন বুঝতে পেরেছি, এটি সম্পূর্ণ নতুন ডাটাবেস সংযোগ হ্যান্ডশেক তৈরি করতে এবং রেলগুলিতে স্প্যান করার জন্য একটি নতুন ডিবি পুলকে ট্রিগার করে It একটি অনুরোধ একটি ডিবি পুল তৈরির পরামর্শ দেয়?
কেএসডি পুত্র

আমার অর্থ: (১) প্রতিটি অনুরোধে অ্যাক্টিভেকর্ড :: বেস.এস্টাবলিশ_সংযোগ (কনফিগারেশন) কল করার পরে আমি পারফরম্যান্স / নেটওয়ার্ক ওভারহেড সম্পর্কে উদ্বিগ্ন, কেবল আলাদা ডাটাবেস / দেশের মধ্যে স্যুইচ করতে
নীল ক্রিশ্চিয়ান

আপনাকে ওভারহেড নিয়ে চিন্তা করতে হবে না। এখন, আপনি যদি সিঙ্গল ডিবি ব্যবহার করেন তবে আপনার একটি সংযোগ পুল রয়েছে (উপরের (1) এর উত্তরে সংযোগ সম্পর্কে লিঙ্কটি পরীক্ষা করতে পারেন)। আপনি যদি এটির establish_connectionমতো মডেলটিতে ব্যবহার করেন: class SecondTenantUser < ActiveRecord::Base; establish_connection(DB_SECOND_TENANT); endএবং আপনার কাছে 5 টি মডেল রয়েছে বলে আপনি DB_SECOND_TENANT তে 5 টি সংযোগ পুল তৈরি করেন। এবং প্রতিটি পুল সমানভাবে চিকিত্সা করা হয়। সুতরাং, আপনি প্রতি অনুরোধের জন্য পুল তৈরি করবেন না, তবে প্রতিটি establish_connection
কেএসডি পুত্র

3

আমি যা বুঝি সেগুলি থেকে, (2) রিয়েল 6-এ ম্যানুয়াল সংযোগ স্যুইচিংয়ের মাধ্যমে সম্ভব হওয়া উচিত ।


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

3

মাত্র দু'দিন আগে গিটহাবের রেলের অন ​​শাখায় রুবিতে আনুভূমিক শারডিং যুক্ত হয়েছিল master। বর্তমানে, এই বৈশিষ্ট্যটি আনুষ্ঠানিকভাবে প্রকাশিত হয়নি তবে আপনার অ্যাপ্লিকেশনটির রেল সংস্করণের উপর নির্ভর করে আপনি এটিতে masterযুক্ত করে রেলের ব্যবহার বিবেচনা করতে পারেন Gemfile:

gem "rails", github: "rails/rails", branch: "master"

এই নতুন বৈশিষ্ট্যটির সাহায্যে আপনি রেলের ডেটাবেস সংযোগ পুলের সুবিধা নিতে পারেন এবং শর্তের ভিত্তিতে ডাটাবেসটি স্যুইচ করতে পারেন।

আমি এই নতুন বৈশিষ্ট্যটি ব্যবহার করি নি, তবে এটি বেশ সোজা-এগিয়ে বলে মনে হচ্ছে:

# in your config/database.yml
production:
  primary:
    database: my_database
    # other config: user, password, etc
  primary_tenant_1:
    database: tenant_1_database
    # other config: user, password, etc

# in your controller for example when updating a tenant
ActiveRecord::Base.connected_to(shard: "primary_tenant_#{tenant.database_shard_number}") do
  tenant.save
end

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

around_filter :determine_database_connection

private

def determine_database_connection
  # assuming you have a method to determine the current_tenant and that tenant
  # has a method that returns the number of the shard to use or even the 
  # full shard identifier
  shard = current_tenant.database_shard # returns for example `:primary_tenant_1` 

  ActiveRecord::Base.connected_to(shard: shard) do
    yield
  end
end

সেই ক্ষেত্রেও কি ডিফল্ট সংযোগে ফিরে যেতে একই ধারণা তৈরি হবে? github.com/influitive/apartment#middleware-consideration
বেন

1
আপনি একবার ActiveRecord::Base.connected_to ... doব্লকটি ছেড়ে গেলে এটি আবার ডিফল্ট সংযোগটি ব্যবহার করবে।
চমত্কার

@ স্পিকারম্যান আমি এই রত্নটি পড়ছিলাম, কেবল রেলের জন্যই নয়?
7urkm3n

@ 7urkm3n এটি বর্তমান রেল masterশাখায় অন্তর্ভুক্ত রয়েছে ।
চমত্কার

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