3.14 تعدد المستأجرين وعمارة SaaS
نظرة عامة والدافع
تعدد المستأجرين هو ممارسة تشغيل نسخة واحدة من برمجيتك بحيث تخدم عملاء منفصلين كثيرين في آن، مبقية بيانات وتهيئة كل عميل منطقيًا منفصلة بينما يشتركون في الشيفرة نفسها، وغالبًا البنية التحتية نفسها. كل عميل مستأجر. هذه الفكرة الواحدة هي المحرك الاقتصادي لـالبرمجيات كخدمة (SaaS)، النموذج الذي تبيع فيه وصولًا إلى تطبيق عامل بدل نسخة للتثبيت. عندما يتشارك ألف مستأجر النشرة نفسها، ترقّع مرة واحدة، وتوسّع نظامًا واحدًا، وتقترب التكلفة الهامشية للعميل التالي من الصفر. هذا لماذا يستطيع منتج متعدد المستأجرين جيد البناء خدمة شركة ناشئة من شخصين ومؤسسة بمئة ألف مقعد من قاعدة الشيفرة نفسها، ولماذا يشكّل نموذج التأجير الذي تختاره هوامشك ووضعية أمانك وعبئك التشغيلي لسنوات.
بالنسبة للفرق الكبيرة، المخاطر أعمق من التكلفة. يضع تعدد المستأجرين متطلبًا صارمًا في مركز عمارتك: يجب ألا يرى المستأجر A بيانات المستأجر B أبدًا، تحت أي خطأ، أو سباق، أو سوء تهيئة. تسريب واحد عبر المستأجرين يمكن أن ينهي شركة. في الوقت نفسه، الهدف الكامل للمشاركة هو الكفاءة، لذا يجلس كل قرار تصميم على طيف بين عزل قوي (أكثر أمانًا، أكثر تكلفة) ومشاركة كثيفة (أرخص، أخطر). إصابة هذا هي الفرق بين منتج يتوسع بسلاسة وآخر إما يفلسك في البنية التحتية أو يضعك في العناوين الرئيسية. يبني هذا الفصل على عمارة السحابة (الفصل 3.11)، ويعتمد بشدة على عمارة البيانات (الفصل 3.4) وأمان السحابة (الفصل 4.3)، ويرتبط بقابلية التوسع والمرونة (الفصل 3.5) ونسب التكلفة (الفصل 9.4).
ترفع المؤسسات والحكومات السقف أكثر. يتفاوض مشترو المؤسسات على ضمانات بيانات تعاقدية، ويطلبون عزلًا مخصصًا لطبقتهم، ويتوقعون منك ترحيلهم بين البيئات بلا وقت تعطل. تضيف الحكومات قوانين إقامة بيانات، وفصلًا مدفوعًا بالتصنيف، ومتطلبًا متكررًا بأن تكون كل وكالة مستأجرها الخاص بحد تدقيق خاص بها. قرارات التأجير هنا ليست تفاصيل تنفيذ؛ إنها التزامات تتخذها لكل عميل يثق بك ببياناته.
المبادئ الأساسية
- العزل طيف، لا مفتاح. تبادل نماذج الصومعة، والتجمّع، والجسر الكفاءة مقابل الفصل؛ اختر لكل طبقة ومورد، لا مرة واحدة لكل شيء.
- سياق المستأجر مقدس. يجب أن يحمل كل طلب، واستعلام، وسطر سجل، ومهمة خلفية معرّف مستأجر، ويجب أن يُحدَّد نطاق كل وصول بيانات به.
- التسريب عبر المستأجرين هو الفشل الأكثر أهمية. صمم بحيث لا يستطيع فلتر مفقود واحد كشف بيانات مستأجر آخر؛ دفاع متعدد الطبقات، لا شرط WHERE واحد.
- الجيران المزعجون مشكلة عمارة. بلا حصص وعدالة، يدهور مستأجر ثقيل الجميع؛ خطط لذلك قبل حدوثه.
- تهيئة لكل مستأجر تتوسع؛ شيفرة لكل مستأجر لا تتوسع. ثنِ المنتج بالبيانات والأعلام، لا التفريعات.
- دورة حياة المستأجر ميزة منتج. يجب أن يكون الإلحاق والتجهيز والإنهاء وتصدير البيانات من الدرجة الأولى وآليًا وقابلًا للتدقيق.
- لا تستطيع إدارة ما لا تستطيع نسبته. يجب تقسيم المراقبة والتكلفة حسب المستأجر، وإلا تطير أعمى في الموثوقية والهامش معًا.
التوصيات
اختر نموذج تأجير لكل طبقة، على طيف العزل مقابل الكفاءة
يثبّت الطيف ثلاثة نماذج. في نموذج الصومعة (المخصص)، يحصل كل مستأجر على مكدسه المعزول الخاص: حوسبة منفصلة، قاعدة بيانات منفصلة، أحيانًا حساب أو شبكة منفصلة. العزل الأقوى ونطاق انفجار خطأ مستأجر واحد، لكنك تدفع مقابل سعة خاملة لكل عميل وتشغّل نسخًا كثيرة. في نموذج التجمّع (المشترك)، يتشارك كل المستأجرين الحوسبة وقاعدة البيانات نفسها، منفصلين فقط بالمنطق ومعرّف مستأجر. الكفاءة الأعلى والتكلفة الهامشية لمستأجر تقترب من الصفر، لكن العزل الآن يعتمد كليًا على صحة شيفرتك. يمزج نموذج الجسر (الهجين) الاثنين: حوسبة مشتركة بقواعد بيانات لكل مستأجر، أو تجمّع مشترك لمستأجرين صغار وصوامع مخصصة لكبار أو منظمين.
لا تختر نموذجًا واحدًا للمنتج بأكمله. الإجابة الصحيحة عادة جسر يخطّط إلى طبقات تسعيرك. ضع الذيل الطويل من المستأجرين الصغار في تجمّع مشترك كفؤ حيث تعمل اقتصادياتهم. قدّم نشرة مخصصة أو أحادية المستأجر كطبقة ممتازة لعملاء المؤسسات الذين سيدفعون مقابل العزل والضمانات التعاقدية. دوّن التخطيط كسجل قرار عمارة (الفصل 3.11)، لأن “أي المستأجرين يتشاركون ماذا” ادعاء يعتمد عليه فريقا أمانك ومبيعاتك وماليتك كلهم.
قسّم البيانات عمدًا، واجعل نسيان تحديد نطاق المستأجر مستحيلًا
البيانات حيث يحيا تعدد المستأجرين أو يموت، لذا عامل اختيار التقسيم كقرار عمارة بيانات أساسي (الفصل 3.4). ثلاث استراتيجيات توازي نماذج التأجير. قاعدة بيانات منفصلة لكل مستأجر تمنح أقوى عزل، ونسخًا احتياطيًا واستعادة سهلَين لكل مستأجر، وتصديرًا بسيطًا للبيانات، بتكلفة قواعد بيانات كثيرة للتشغيل وترحيلات مخطط تنتشر. مخطط منفصل لكل مستأجر داخل قاعدة بيانات مشتركة مسار وسط: خادم واحد، فصل منطقي، لا يزال هناك كائنات كثيرة للترحيل. جداول مشتركة مفتَّحة بعمود مستأجر، حيث يحمل كل صف tenant_id، هو الأكثف والأرخص، والأخطر، لأن استعلامًا واحدًا يفتقد فلتر مستأجره يسرّب بيانات عبر العملاء الآن.
إن شاركت الجداول، لا تعتمد على تذكر المطورين الفلتر. افرض تحديد نطاق المستأجر في طبقة لا يمكن تجاوزها: أمان على مستوى الصف في قاعدة البيانات يرفق مسندًا إلزاميًا بكل استعلام وفق مستأجر الجلسة، أو ORM أو طبقة وصول بيانات تحقن شرط المستأجر آليًا، أو كليهما. الحزام والحمالة صحيح هنا. مع نمو المستأجرين، يصبح التجزيء وفق المستأجر طبيعيًا: ضع مجموعات مستأجرين على تجزيئات قاعدة بيانات مختلفة بحيث لا تحمل نسخة واحدة الجميع، مما يحد أيضًا نطاق انفجار فشل تجزيء واحد ويتيح لك نقل مستأجر كبير إلى تجزيئه الخاص دون تغيير النموذج.
انشر سياق المستأجر في كل مكان، وادفع ضد تسريبات عبر المستأجرين بعمق
يجب أن يرافق معرّف المستأجر كل وحدة عمل. أنشئه عند الحافة، عادة من الجلسة المصادَق عليها أو نطاق فرعي، تحقق منه، ومرّره عبر سياق الطلب، وكل نداء خدمة لاحق، وكل جلسة قاعدة بيانات، وكل مهمة في طابور، وكل سطر سجل ومقياس. الفجوات الخطرة هي غير المتزامنة: عامل خلفي يعالج مهمة دون إعادة إنشاء سياق مستأجر، ذاكرة مخبأة مفتَّحة بلا مستأجر، معالج webhook يثق بمعرّف مستأجر من المستدعي. كل واحدة مسار لخدمة بيانات مستأجر لآخر.
عامل العزل عبر المستأجرين كخاصية أمان بدفاع متعدد الطبقات، وسلّم التفاصيل للفصل 4.3. طبّق مبدأ أقل امتياز بحيث يستطيع حتى مكون مخترَق الوصول فقط إلى المستأجر الذي يعمل من أجله. لا تقبل أبدًا معرّف مستأجر من إدخال يتحكم به العميل لقرارات التفويض؛ اشتقه من الهوية المصادَق عليها. حدد فضاء أسماء الذاكرات المخبأة، وبادئات تخزين الكائنات، وفهارس البحث وفق المستأجر بحيث لا يستطيع تصادم مفتاح عبور الحد. ثم اختبر الحد عمدًا: اختبارات آلية تؤكد أن بيانات اعتماد المستأجر A لا تستطيع قراءة سجلات المستأجر B، وتمارين فريق أحمر دورية تحاول الهروب من مستأجر. تسريب تجده مجموعة اختباراتك خطأ؛ تسريب يجده عميل أزمة.
احتوِ الجيران المزعجين بحصص وحدود معدل وعدالة
عندما يتشارك المستأجرون الموارد، يصبح ارتفاع مستأجر واحد انقطاع الجميع. مشكلة الجار المزعج هذه ليست حالة حدية؛ إنها السلوك الافتراضي لتجمّع مشترك تحت الحمل. صمم ضدها منذ البداية. ضع حصصًا لكل مستأجر على الموارد المهمة (طلبات في الثانية، مهام متزامنة، تخزين، تكلفة استعلام) وافرضها بـتحديد معدل عند الحافة وعند الحدود الداخلية المكلفة. فضّل جدولة عادلة تمنح كل مستأجر حصة بدل طوابير الأول-يصل-أولًا-يُخدَم التي تدع مستأجرًا واحدًا يجوّع الباقي.
طابق الفرض مع نموذج تأجيرك. في تجمّع مشترك، الحصص والعدالة الدفاع الأساسي، لذا استثمر فيها. لمستأجر يتجاوز حمله فعليًا ما تستطيع المشاركة العادلة امتصاصه، الإجابة غالبًا ترقيته خارج التجمّع إلى نشرة جسر أو صومعة، وهي ميزة تستطيع بيعها لا فشلًا. اربط هذا بعمل قابليتك للتوسع والمرونة (الفصل 3.5): يجب أن يكون تفريغ الحمل، وقواطع الدائرة، والضغط الخلفي كلها واعية بالمستأجر بحيث يحمي تفريغ حمل مستأجر واحد الزائد الآخرين بدل تدهور النظام بأكمله.
هيّئ المستأجرين بالبيانات، لا تفريعات شيفرتك
سيريد كل عميل شيئًا مختلفًا قليلًا: شعاره، قواعد تدفقه، تكاملاته، حقلًا لا تملكه. الطريقة القابلة للتوسع للقول نعم هي تهيئة لكل مستأجر: أعلام ميزات، إعدادات، استحقاقات، ونقاط قابلية توسع تكون بيانات، تُقيَّم وقت التشغيل، ويشاركها قاعدة شيفرة واحدة. المسار الذي يدمر عمل SaaS هو شيفرة مخصصة لكل مستأجر: فرع أو تفريع أو حالة خاصة في مسار الشيفرة لعميل كبير. عشرة من هذه ولم يعد لديك منتج، لديك عشرة منتجات ترتدي معطف خندق، ويجب اختبار كل تغيير عشر مرات.
ارسم خطًا صارمًا. انمذج محاور التباين التي أنت مستعد لدعمها كتهيئة من الدرجة الأولى، وعامل الطلبات خارج تلك المحاور إما كخارطة طريق منتج أو رفضًا صارمًا. عندما يحتاج عميل تخصيصًا حقيقيًا، امنحه نقاط توسيع (webhooks، واجهة برمجة، إضافات، حقول مخصصة) تشغّل منطقه دون تفريع منطقك. احجز النشرات المخصصة فعليًا للطبقة الممتازة أحادية المستأجر، حيث العزل هو الهدف والسعر الأعلى يغطي التكلفة التشغيلية.
اجعل دورة حياة المستأجر آلية وقابلة للمراقبة وموسومة بالتكلفة
ينبغي أن يكون إلحاق مستأجر تدفقًا آليًا وخدمة ذاتية: جهّز تقسيم بيانات المستأجر، ابذر افتراضات، ضع استحقاقات، وكن جاهزًا خلال ثوانٍ، لا تذكرة إلى فريق عمليات. الإنهاء يهم بالقدر نفسه وأسهل إهمالًا. عندما يغادر مستأجر، يجب أن تستطيع تصدير بياناته بصيغة قابلة للاستخدام، ثم حذفها بشكل قابل للإثبات، لأن العقود وقانون الخصوصية سيتطلبان كليهما. صمم تصدير البيانات وحذفها منذ اليوم الأول؛ تعديلهما لاحقًا في مخطط جدول مشترك مؤلم.
أدرج كل شيء لكل مستأجر. سمِّ السجلات، والتتبعات، والمقاييس بمعرّف المستأجر بحيث تستطيع الإجابة عن “هل هذا الانقطاع لكل المستأجرين أم واحد؟” و”أي مستأجر يقود هذه التكلفة؟” خلال ثوانٍ. انسب تكلفة البنية التحتية للمستأجرين بحيث تعرف هامشك الحقيقي لكل عميل وتستطيع اكتشاف المستأجر الذي يجعل استخدامه غير مربح بسعره الحالي (الفصل 9.4). المراقبة الواعية بالمستأجر ونسبة التكلفة تحوّلان تعدد المستأجرين من صندوق أسود إلى نظام تستطيع تشغيله وتسعيره فعليًا.
المفاضلات: الإيجابيات والسلبيات
| نموذج التأجير | الإيجابيات | السلبيات |
|---|---|---|
| الصومعة (مكدس مخصص لكل مستأجر) | أقوى عزل، أصغر نطاق انفجار، امتثال وتصدير سهلان لكل مستأجر، قصة جار مزعج بسيطة | أعلى تكلفة، سعة خاملة لكل مستأجر، نسخ كثيرة للتشغيل والترقيع |
| التجمّع (مشترك كليًا) | أدنى تكلفة هامشية، أكثف تعبئة، نظام واحد للتوسع والترقية | يعتمد العزل كليًا على صحة الشيفرة، أسوأ مخاطرة جار مزعج، أصعب تصدير وحذف لكل مستأجر |
| الجسر (هجين، طبقي) | كفؤ للمستأجرين الصغار، عزل مخصص للكبار، يخطّط للتسعير | نماذج أكثر للبناء والتشغيل، مسار ترقية بين الطبقات للصيانة |
| قاعدة بيانات مشتركة، مخطط مشترك (عمود مستأجر) | أرخص تخزين، ترحيل واحد، أبسط عمليات | فلتر واحد مفقود يسرّب بيانات؛ يحتاج أمانًا على مستوى الصف كخط دفاع |
| قاعدة بيانات مشتركة، مخطط لكل مستأجر | عزل منطقي، خادم واحد، تصدير لائق | كائنات مخطط كثيرة، ترحيلات تنتشر، حدود توسع لكل خادم |
| قاعدة بيانات لكل مستأجر | عزل بيانات قوي، نسخ احتياطي وتصدير لكل مستأجر | قواعد بيانات كثيرة، انتشار ترحيل، تكلفة أعلى |
التوتر المركزي هو العزل مقابل الكفاءة، ويجري عبر كل صف. المشاركة الأكثف تضاعف هوامشك وتضاعف مخاطرتك في الحركة نفسها؛ العزل الأقوى يشتري أمانًا وبساطة بتكلفة حقيقية لكل مستأجر. الحل ليس اختيار قطب واحد بل وضع كل مستأجر عمدًا على الطيف، عادة وفق الطبقة: عبّئ المستأجرين الصغار كثيفًا حيث تتطلب الاقتصاديات ذلك والمخاطرة محدودة، اعزل المستأجرين الكبار والمنظمين حيث سيدفعون ثمن ذلك ويجب أن يكون نطاق الانفجار صغيرًا. ثم اجعل الطرف الكثيف آمنًا بتحديد نطاق مستأجر مفروض، واجعل الطرف المعزول رخيصًا بالأتمتة، بحيث لا يؤذي أي قطب بقدر ما تؤذي النسخة الساذجة.
أسئلة للنقاش مع فريقك
لو فُقِد فلتر تحديد نطاق مستأجر واحد غدًا، هل سيرى عميل بيانات عميل آخر؟ هذا السؤال الذي يفصل منتجًا متعدد المستأجرين مدافَعًا عنه عن حادث ينتظر الحدوث. الاختبار الصادق هو تتبع مسار قراءة حقيقي والسؤال ما يفرض حد المستأجر: هل هو شرط WHERE واحد كتبه مطور، أم يوجد خط دفاع مثل أمان على مستوى الصف في قاعدة البيانات أو طبقة وصول بيانات تحقن النطاق بصرف النظر؟ أحضر مسارات استعلامك الفعلية، ومهامك الخلفية، وذاكراتك المخبأة، لأن التسريب يختبئ دائمًا تقريبًا في الزاوية غير المتزامنة التي لم يحدد أحد نطاقها. ينبغي أن تحضر أيضًا نتائج اختبار يستخدم عمدًا جلسة المستأجر A لطلب سجلات المستأجر B ويؤكد رفضًا. إن استند الحد على اليقظة البشرية وحدها، لديك خرق كامن، وينبغي أن يقفز الإصلاح (دفاع متعدد الطبقات) إلى أعلى المتراكم.
أي نموذج تأجير وتقسيم بيانات تستخدمه كل طبقة عميل فعليًا، وهل يطابق ما بعناه لهم؟ تنجرف فرق كثيرة إلى نموذج واحد افتراضيًا، ثم تكتشف أن تسعيرها وعمارتها يختلفان: وُعِد عملاء مؤسسة بعزل لا يوفره التجمّع المشترك، أو يجلس عملاء صغار في مكدسات مخصصة مكلفة تدمر الهامش. خطّط كل طبقة إلى نموذجها الحقيقي (صومعة، تجمّع، أو جسر؛ قاعدة بيانات لكل مستأجر، مخطط، أو جدول مشترك) وضعه بجانب ضمانات البيانات التعاقدية التي يقدمها فريق مبيعاتك. حيث تتباعد، لديك إما مخاطرة امتثال أو مشكلة تكلفة، وكلاهما يستحق الإظهار قبل أن يجده عميل أو مدقق. الدليل الذي ينبغي إحضاره هو تخطيط الطبقة إلى النموذج، والتكلفة لكل مستأجر، واللغة الفعلية في عقود مؤسستك.
عندما يرتفع حمل مستأجر كبير، من آخر يشعر به، وما خطتنا؟ في تجمّع مشترك، الإجابة غالبًا “الجميع”، ولا تعرف الفرق هذا غالبًا حتى تجعله حادثة واضحة. استعرض ماذا يحدث عندما يجري أكبر مستأجريك استيرادًا جماعيًا أو يحصل على ارتفاع حركة مرور: هل تحتويه الحصص لكل مستأجر والجدولة العادلة، هل يحمي تفريغ الحمل الجيران، أم يتدهور النظام بأكمله معًا؟ أحضر بيانات الحمل وقصة آخر حادثة جار مزعج لديك، لأن المستأجر الذي يؤذيك عادة أحد تستطيع تسميته. ينبغي أن تشكّل الإجابة كلًا من استثمارك في تحديد المعدل واستراتيجية طبقتك، لأن الإصلاح الأنظف لمستأجر يتجاوز المشاركة العادلة هو ترقيته إلى نشرة جسر أو مخصصة تستطيع محاسبته عليها.
عندما ينهي مستأجر غدًا، هل نستطيع تسليمه تصديرًا نظيفًا وإثبات حذفنا كل أثر، أم سنكون في هرولة؟ الإنهاء هو الجزء من دورة حياة المستأجر الذي تهمله الفرق حتى يفرض بند خروج عقد أو طلب قانون خصوصية المسألة، وبحلول ذلك الوقت يجعل المخطط المشترك الاستخراج والحذف مؤلمًا. لفريق كبير تتراكم المخاطرة، لأن بيانات مستأجر مبعثرة عبر قاعدة البيانات الأساسية، والذاكرات المخبأة، وتخزين الكائنات، وفهارس البحث، والنسخ الاحتياطية، وخطوط أنابيب التحليلات، ويجب تصدير كل واحدة بصيغة قابلة للاستخدام ثم تطهيرها بشكل قابل للإثبات. الاعتبارات المنافسة حقيقية: الجداول المشتركة الكثيفة التي تمنحك تخزينًا رخيصًا هي تحديدًا ما يجعل الاستخراج والحذف لكل مستأجر الأصعب، لذا فإن الكفاءة التي اشتريتها في طبقة التخزين قد تدفعها ثانية عند الخروج. أحضر استعراضًا حيًا لإنهاء على مستأجر حقيقي، وقائمة كل مخزن يحمل بيانات المستأجر، والدليل الذي ستُظهره على حدوث الحذف فعليًا. لمستأجري المؤسسات والحكومة، يجب أن يكون التصدير معتمَدًا والحذف قابلًا للإثبات لإرضاء قوانين السجلات العامة والخصوصية، لذا عامل مسار حذف مفقود كعيب امتثال يجب إغلاقه الآن، لا ميزة تُضاف عندما يغادر عميل.
كم حالة خاصة لعملاء فرديين تعيش بالفعل في مسار شيفرتنا، وأين الخط الذي نرفض عبوره؟ تفريعات الشيفرة لكل مستأجر هي الطريقة الهادئة التي يتوقف بها عمل SaaS عن كونه منتجًا واحدًا ويصبح منتجات كثيرة ترتدي اسمًا واحدًا، حيث يجب اختبار كل تغيير مقابل كل حالة خاصة وتتدهور السرعة مع إضافة عملاء. التوتر هو أن عميلًا كبيرًا بحاجة حقيقية صعب رفضه، وفرع في مسار الشيفرة يشعر بأنه أسرع من بناء سطح تهيئة، لذا تتراكم الحالات الخاصة استثناء معقولًا واحدًا في كل مرة. أحضر جردًا صادقًا: ابحث في قاعدة الشيفرة عن أسماء عملاء وتفريعات خاصة بالطبقة، عُدها، وقدّر تكلفة الاختبار والمراجعة الإضافية التي يفرضها كل واحد على تغيير غير ذي صلة. ينبغي أن يرسم النقاش خطًا صارمًا بين التباين الذي تنمذجه كتهيئة من الدرجة الأولى (أعلام، استحقاقات، نقاط توسيع) والعمل المخصص الحقيقي الذي تحجزه لطبقة ممتازة أحادية المستأجر حيث يغطي السعر الأعلى التكلفة التشغيلية. لمشتري المؤسسات الذين يطلبون تخصيصًا عميقًا، الإجابة الدائمة نقاط توسيع تشغّل منطقهم دون تفريع منطقك، بحيث تبقى الحوكمة والتدقيق قابلة للإدارة عبر الأسطول.
هل نستطيع القول، لكل مستأجر، ماذا تكلف حادثة من، وأي العملاء غير مربحين بسعرهم الحالي؟ يتحول تعدد المستأجرين إلى صندوق أسود لحظة ألا تحمل سجلاتك، وتتبعاتك، ومقاييسك، وتكلفة بنيتك التحتية بُعد مستأجر، لأنك حينها لا تستطيع الإجابة هل انقطاع مستأجر واحد أم الأسطول بأكمله، ولا تستطيع تسمية المستأجر الذي يجعل استخدامه خسارة بسعر عقده. لفريق كبير هذه النسبة هي ما يفصل تشغيل المنصة عن التخمين بشأنها، وتشكّل مباشرة استجابة الموثوقية والتسعير معًا. تسحب الاعتبارات ضد تكلفة الإدراج والتفرد: وسم كل شيء بالمستأجر ليس مجانيًا، والمقاييس عالية التفرد تجهد ميزانية مراقبتك، لذا تختار عمدًا ماذا تقسّم لكل مستأجر وماذا تُعايَن. أحضر تغطية وسم مستأجرك الحالية، واستعلامًا حقيقيًا ينسب الإنفاق السحابي لمستأجر واحد، وجدول الهامش الذي سيتيح لك تسمية عميلك الأقل ربحية. في إعدادات المؤسسات والحكومة، تغذي التكلفة لكل مستأجر والمراقبة المحددة نطاق التدقيق أيضًا الفوترة العكسية وتخطيط السعة وحد التدقيق الذي تستحقه كل وكالة أو وحدة عمل، لذا فإن بُعد المستأجر متطلب حوكمي بقدر ما هو تشغيلي.
المنظور القطاعي
الشركة الناشئة. اشحن تجمّعًا مشتركًا واحدًا منذ اليوم الأول وضع انتباه هندستك النادر في الشيء الوحيد الذي لا يمكن تعديله لاحقًا: تحديد نطاق مستأجر مفروض. Postgres مُدار بأمان على مستوى الصف، وtenant_id على كل جدول، وسياق مستأجر يُحَل عند الحافة يشتري لك كثافة آمنة بلا فريق عمليات. لا تبنِ طبقات صومعة أو بنية تحتية لكل مستأجر تخمينًا؛ أضف طبقة جسر فقط عندما يجعل احتمال مؤسسة دافعة العزل يستحق تكلفته.
الشركة الصغيرة. بدون أخصائي منصة وميزانية محدودة، اتكئ على ما تمنحك إياه سحابتك وإطارك بالفعل بدل بناء آلية عزل بنفسك. قواعد بيانات مُدارة بأمان على مستوى الصف، ومنصة كخدمة تحدد نطاق المستأجرين عنك، ومزود مصادقة يحمل هوية المستأجر عادة أرخص وأكثر أمانًا من مكافئات مصنوعة يدويًا. عامل تعدد المستأجرين كقرار شراء مقابل بناء في كل طبقة، واحجز العمل المخصص لاختبارات حد المستأجر التي أنت فقط تستطيع كتابتها.
المؤسسة الكبرى. المشكلة هي حوكمة المحفظة عبر فرق كثيرة: عمارة جسر طبقية، وسجل قرار عمارة يخطّط كل طبقة إلى نموذج تأجيرها وتقسيم بياناتها، ونسبة تكلفة لكل مستأجر بحيث تعرف المالية الهامش الحقيقي على كل حساب. وحّد نشر سياق المستأجر وخط دفاع تحديد النطاق بحيث لا يعيد فريق اختراعهما، خصص ميزانية للعزل وأتمتة دورة الحياة صراحة، واحتفظ بمسار مدعوم ومسعَّر لترحيل مستأجر بين الطبقات بلا وقت تعطل مع نموه أو تغير احتياجات امتثاله.
الحكومة. الشراء وإقامة البيانات والمساءلة العامة تقود النموذج. ثبّت بيانات كل وكالة إلى مناطق داخل البلد بسياسة-كشيفرة، اعزل أحمال العمل الحساسة أو عالية التصنيف في حسابات منفصلة بحد تدقيق خاص بها، وامنح كل وكالة تكامل هوية وقواعد احتفاظ ومسار تدقيق خاصًا بها بحيث لا يرى مدققو وكالة أبدًا نشاط أخرى. يجب أن ينتج الإنهاء تصديرًا معتمَدًا وحذفًا قابلًا للإثبات لإرضاء قوانين السجلات العامة والخصوصية، ويجب أن تكون ضمانات التأجير التي توقّعها ضمانات تستطيع عمارتك الوفاء بها فعليًا.
أمثلة
الشركة الناشئة. تبني شركة ناشئة من خمسة عشر شخصًا منتجها كتجمّع مشترك واحد منذ اليوم الأول وتصيب في ذلك. يتشارك كل المستأجرين قاعدة بيانات Postgres مُدارة واحدة بـtenant_id على كل جدول، يفرض أمان على مستوى الصف مسند المستأجر في قاعدة البيانات بحيث لا يستطيع فلتر منسي التسريب، ويحل التطبيق المستأجر من نطاق فرعي عند الحافة ويمرره عبر كل طلب ومهمة خلفية. الإلحاق خدمة ذاتية: تسجيل جديد يجهّز صف مستأجره، يبذر افتراضات، ويصبح حيًا خلال ثوانٍ. يشغّل مهندسان المنصة بأكملها لأنه يوجد نظام واحد للتشغيل. عندما يطلب احتمال مؤسستهم الحقيقي الأول قاعدة بيانات مخصصة وضمان عزل تعاقدي، يضيفون طبقة جسر: قاعدة الشيفرة نفسها، لكن يحصل هذا المستأجر على قاعدة بياناته الخاصة على تجزيئه الخاص، مباعًا بسعر يغطي التكلفة.
المؤسسة الكبرى. يشغّل مورّد SaaS يخدم مؤسسات مالية كبيرة عمارة جسر طبقية. يعيش آلاف العملاء الصغار والمتوسطين في تجمعات مشتركة إقليمية، مجزَّأة وفق المستأجر، بحصص وجدولة عادلة تحتفظ بالجيران المزعجين تحت السيطرة. يحصل عملاء البنوك من الطبقة العليا على نشرات أحادية المستأجر في حسابات سحابية معزولة، بقواعد بيانات مخصصة، ومفاتيح تشفير لكل مستأجر، وضمانات إقامة بيانات وعزل تعاقدية مكتوبة في الاتفاقية الرئيسية. تُرحِّل قدرة منصة مستأجرًا بين الطبقات بلا وقت تعطل عندما ينمو أو تتغير احتياجات امتثاله. تُنسَب تكلفة كل مستأجر عبر الوسم بحيث تعرف المالية الهامش الحقيقي على كل حساب، وتتيح المراقبة الموسومة بالمستأجر لمهندس المناوبة القول خلال ثوانٍ هل إنذار لمستأجر واحد أم الأسطول بأكمله.
الحكومة. يستضيف مزود منصة وطني وكالات حكومية كثيرة كمستأجرين منفصلين ويعامل العزل كمتطلب قانوني، لا تفضيل. يثبّت قانون إقامة البيانات بيانات كل وكالة إلى مناطق داخل البلد، مفروضة بسياسة-كشيفرة تحجب أي مورد في منطقة غير مسموحة (الفصل 3.11). يقود التصنيف النموذج: تحصل الوكالات التي تتعامل مع مواد حساسة على نشرات معزولة كليًا في حسابات منفصلة بحد تدقيق خاص بها، بينما تشترك أحمال العمل الأقل تصنيفًا في تجمّع محكوم. كل وكالة مستأجرها الخاص بتكامل هوية خاص بها، وقواعد احتفاظ وتصدير خاصة بها، ومسار تدقيق محدد نطاقه بحدها، بحيث لا يرى مدققو وكالة أبدًا نشاط أخرى. ينتج الإنهاء تصديرًا معتمَدًا للبيانات وحذفًا قابلًا للإثبات، لأن السجلات خاضعة لقوانين السجلات العامة والخصوصية.
حالة العمل: الدوافع والعائد على الاستثمار وتكلفة الملكية الإجمالية
الحالة التجارية الجوهرية لتعدد المستأجرين هي الهامش. نموذج أحادي المستأجر، حيث تنشر نسخة جديدة لكل عميل، يعني أن تكلفة البنية التحتية والعمليات تنمو تقريبًا خطيًا مع عدد العملاء، وينفق مهندسوك أيامهم في ترقيع نسخ كثيرة. يكسر نموذج متعدد المستأجرين مشترك ذلك الرابط: ترقّع مرة، توسّع نظامًا واحدًا، وتعبئ العملاء بكثافة كافية بحيث تقترب التكلفة الهامشية للمستأجر التالي من الصفر. هذا ما يتيح لعمل SaaS نمو الإيراد أسرع بكثير من التكلفة، ولماذا يعامل المستثمرون والمجالس عمارة متعددة المستأجرين نظيفة كوكيل لشركة قابلة للتوسع.
يظهر العائد في ثلاثة أماكن: النفوذ التشغيلي (فريق واحد يشغّل الأسطول بأكمله)، والتسليم الأسرع (يُشحَن إصلاح لكل مستأجر دفعة واحدة، بحيث لا تتدهور السرعة مع إضافة عملاء)، وقابلية اختيار التسعير (خطة مشتركة للذيل الطويل وخطة معزولة ممتازة للمؤسسات، كلاهما من قاعدة شيفرة واحدة). زِن هذه مقابل التكاليف التي يجب عليك تمويلها بصدق: الهندسة لبناء عزل مستأجر مفروض، وحصص، وأتمتة دورة حياة، ومراقبة لكل مستأجر، بالإضافة إلى الانضباط لإبقاء الحد سليمًا. تكلفة الخطأ فيه غير متماثلة وحادة، لأن خرق بيانات واحد عبر المستأجرين يمكن أن يطلق عقوبات تنظيمية، وتسربًا جماعيًا، وضررًا سمعيًا يفوق البنية التحتية التي وفرتها بالمشاركة. أطّر الحالة للقيادة كهامش وقابلية توسع على الجانب الإيجابي ومخاطرة وجودية على السلبي. ثبّت اتفاقية مستوى الخدمة وضمانات البيانات التعاقدية إلى نموذج التأجير الذي تستطيع عمارتك تسليمه فعليًا، لأن وعدًا لا تستطيع عمارتك الوفاء به التزام، لا بيعة.
الأنماط المضادة والمزالق
- تحديد نطاق المستأجر بالاصطلاح. الاعتماد على تذكر المطورين فلتر المستأجر على كل استعلام، بلا خط دفاع على مستوى قاعدة البيانات أو طبقة وصول بيانات؛ إغفال واحد خرق.
- الثقة بمعرّف مستأجر مُقدَّم من العميل. قبول المستأجر من إدخال الطلب للتفويض بدل اشتقاقه من الهوية المصادَق عليها، مما يتيح لمستدعٍ طلب بيانات شخص آخر.
- عمل خلفي بلا نطاق. مهام، وذاكرات مخبأة، وwebhooks، وتصديرات تفقد سياق المستأجر لأن أحدهم حدد نطاق مسار الطلب المتزامن فقط.
- تفريعات شيفرة لكل مستأجر. معالجة حالة خاصة لعميل كبير في مسار الشيفرة حتى تصون منتجات متباينة كثيرة تحت اسم واحد ويكلف كل تغيير عشرة أضعاف.
- بلا دفاع جار مزعج. تشغيل تجمّع مشترك بلا حصص لكل مستأجر أو عدالة، بحيث يُسقِط أول مستأجر يرتفع الجميع.
- الإنهاء كفكرة لاحقة. البناء بلا تصدير بيانات وحذف قابل للإثبات، ثم الفشل في بند خروج عميل أو طلب قانون خصوصية لأن المخطط المشترك يجعل الاستخراج مؤلمًا.
- الطيران أعمى لكل مستأجر. سجلات ومقاييس وتكلفة بلا بُعد مستأجر، بحيث لا تستطيع القول لمن الحادثة أو أي مستأجر غير مربح.
نموذج النضج
- المستوى 1، الشروع: تعدد المستأجرين مرتجل وتفاعلي. يستند فصل المستأجرين إلى فلاتر مكتوبة يدويًا بلا خط دفاع، النموذج مقاس واحد يناسب الجميع، لا حصص، الإلحاق يدوي، والسجلات والتكلفة بلا بُعد مستأجر. يتعلم الفريق عن الجار المزعج والتسريب شبه الفائت من الحوادث.
- المستوى 2، التطوير: تظهر ممارسات أساسية لكنها غير متسقة عبر الفرق. يُختار نموذج تأجير ويُنشَر سياق المستأجر عبر مسار الطلب الرئيسي، يفرض خط دفاع على مستوى قاعدة البيانات أو الوصول للبيانات تحديد النطاق على الجداول الأساسية، وتوجد حصص أساسية لكل مستأجر. الإلحاق آلي جزئيًا وتحمل السجلات معرّف مستأجر، لكن المسارات الخلفية والتصدير ونسبة التكلفة تتفاوت من خدمة لأخرى ولا تُدوَّن في أي مكان.
- المستوى 3، التوحيد القياسي: نهج التأجير موثق ومفروض عبر المؤسسة. يخطّط تأجير طبقي إلى التسعير، بتجمّع مشترك للمستأجرين الصغار ونشرات معزولة للمؤسسات والمنظمين، يُفرَض تحديد نطاق المستأجر بعمق ويُختبَر عمدًا، تحتوي الحصص والجدولة العادلة الجيران المزعجين، تُؤتمَت دورة حياة المستأجر بما يشمل التصدير والحذف القابل للإثبات، وتُقسَّم المراقبة والتكلفة لكل مستأجر. يتبع كل فريق معيار التأجير نفسه لا معياره الخاص.
- المستوى 4، الإدارة: تُقاس ممتلكات التأجير وتُضبط مقابل خطوط أساس. يُتتبَّع العزل والعدالة وزمن الاستجابة والتكلفة لكل مستأجر كمقاييس بأهداف متفق عليها: تغطية اختبار عبر المستأجرين، ومعدلات حوادث خرق الحصة والجار المزعج، ووقت الإلحاق والإنهاء، والهامش لكل مستأجر مُبلَّغ عنها مقابل خطوط أساس، وتُتخذ قرارات ترقية مستأجر بين الطبقات أو إعادة تسعير واحد غير مربح على تلك الأدلة لا الحكاية. تُراقَب مطابقة الإقامة والتصنيف باستمرار، ويطلق الانحراف عن المعيار استجابة موثقة.
- المستوى 5، التنسيق الشامل: يُحسَّن التأجير باستمرار ويُدمَج عبر المؤسسة. تُمارَس حدود عبر المستأجرين بتمارين فريق أحمر روتينية، ينتقل المستأجرون بين الطبقات بلا وقت تعطل مع نموهم أو تغير احتياجات امتثالهم، يغذي الهامش لكل مستأجر التسعير وتخطيط السعة، وتُفرَض قواعد الإقامة والتصنيف بالسياسة لا المراجعة. يتكيف النموذج مع تحول مزيج العملاء والصورة التنظيمية، وتغذي الدروس المنتج والأمان والمالية كحلقة واحدة.
أفكار للنقاش
- أين تقع كل طبقة عملائك على طيف العزل مقابل الكفاءة اليوم، وهل أي طبقة في النموذج الخاطئ للضمانات التي بعتها أو الهامش الذي تحتاجه؟
- لو اضطررت لإثبات لمدقق أن المستأجر A لا يستطيع الوصول إلى بيانات المستأجر B، أي دليل تستطيع إنتاجه الآن، وكم منه آلي مقابل مؤكَّد فقط؟
- أي مساراتك غير المتزامنة (مهام، ذاكرات مخبأة، webhooks، تصديرات، فهارس بحث) تعيد إنشاء سياق مستأجر، وأيها فقط ترثه أو تثق بالمستدعي؟
- عندما يتجاوز مستأجر المشاركة العادلة، هل تملك مسار ترقية مدعومًا ومسعَّرًا إلى نشرة جسر أو مخصصة، أم تتحول الإجابة افتراضيًا إلى حادثة؟
- هل تستطيع نسبة تكلفة البنية التحتية لمستأجرين فرديين جيدًا بما يكفي لتسمية عميلك الأقل ربحية، وهل سيغيّر ذلك كيف تسعّر؟
- لمستأجر حكومي أو منظم، هل تستطيع فرض إقامة البيانات والعزل المدفوع بالتصنيف بالسياسة، والإنهاء بتصدير معتمَد وحذف قابل للإثبات؟
النقاط الرئيسية
- تعدد المستأجرين، نسخة واحدة تخدم مستأجرين كثيرين، هو المحرك الاقتصادي لـSaaS: يدفع هوامشك، ويضع العزل عبر المستأجرين في مركز عمارتك.
- عامل العزل مقابل الكفاءة كطيف وطبّقه: عبّئ المستأجرين الصغار في تجمّع مشترك كفؤ، اعزل المستأجرين الكبار والمنظمين في نشرات جسر أو صومعة سيدفعون ثمنها.
- لا تجعل تحديد نطاق المستأجر يعتمد أبدًا على فلتر مكتوب يدويًا؛ افرضه بعمق بأمان على مستوى الصف أو طبقة وصول بيانات، واختبر الحد عمدًا.
- انشر سياق المستأجر عبر كل طلب ومهمة وذاكرة مخبأة وسجل، وادفع عن المسارات غير المتزامنة حيث تختبئ التسريبات.
- احتوِ الجيران المزعجين بحصص وحدود معدل وجدولة عادلة لكل مستأجر، ورقِّ المستأجرين الذين يتجاوزون التجمّع بدل تركهم يدهورونه.
- ثنِ المنتج بتهيئة لكل مستأجر، لا شيفرة لكل مستأجر، واجعل دورة حياة المستأجر والمراقبة ونسبة التكلفة لكل مستأجر من الدرجة الأولى.
المراجع والقراءات الإضافية
- Tom Kwok, Thao Nguyen, and Linh Lam, A Software as a Service with Multi-tenancy Support for an Electronic Contract Management Application (IEEE International Conference on Services Computing)
- Frederick Chong and Gianpaolo Carraro, Architecture Strategies for Catching the Long Tail (Microsoft)
- Amazon Web Services, SaaS Lens, AWS Well-Architected Framework and SaaS Tenant Isolation Strategies
- Microsoft, Multitenant SaaS architecture and patterns (Azure Architecture Center)
- Google Cloud, Architecture for Multi-tenant SaaS Applications
- Cor-Paul Bezemer and Andy Zaidman, Multi-Tenant SaaS Applications: Maintenance Dream or Nightmare? (Proceedings of the Joint ERCIM Workshop on Software Evolution)
- The Open Web Application Security Project, OWASP Application Security Verification Standard (access-control and multi-tenancy requirements)
- Martin Kleppmann, Designing Data-Intensive Applications (partitioning, sharding, and data isolation)