توسيع نطاق قواعد البيانات باستخدام مدير خرائط الأجزاء

ينطبق على: قاعدة بيانات Azure SQL

لتوسيع نطاق قواعد البيانات بسهولة على Azure SQL Database، استخدم مدير خريطة جزء. مدير خريطة الأجزاء هو قاعدة بيانات خاصة تحافظ على معلومات الخرائط العالمية عن جميع الأجزاء (قواعد البيانات) في مجموعة الأجزاء. تسمح بيانات التعريف للتطبيق بالاتصال بقاعدة البيانات الصحيحة بناءً على قيمة مفتاح التجزئة. بالإضافة إلى ذلك، تحتوي كل جزء في المجموعة على خرائط تتعقب بيانات الأجزاء المحلية (المعروفة باسم shardlets).

Shard map management

يعد فهم كيفية إنشاء هذه الخرائط أمراً ضرورياً لإدارة خرائط الأجزاء. يتم ذلك باستخدام فئة ShardMapManager (Java، .NET)، الموجودة في مكتبة عميل قاعدة بيانات مرنة لإدارة خرائط الأجزاء.

خرائط الأجزاء وتخطيطات الأجزاء

لكل جزء، يجب تحديد نوع خريطة الجزء المراد إنشاؤه. يعتمد الاختيار على بنية قاعدة البيانات:

  1. مستأجر واحد لكل قاعدة بيانات
  2. عدة مستأجرين لكل قاعدة بيانات (نوعان):
    1. تعيين القائمة
    2. تعيين النطاق

بالنسبة لنموذج المستأجر الفردي، قم بإنشاء خريطة الأجزاء list-mapping. يخصص نموذج المستأجر الفردي قاعدة بيانات واحدة لكل مستأجر. هذا نموذج فعال لمطوري SaaS لأنه يبسط إدارة خريطة الأجزاء.

List mapping

يعيّن نموذج المستأجرين المتعددين عدة مستأجرين لقاعدة بيانات فردية (ويمكنك توزيع مجموعات المستأجرين عبر قواعد بيانات متعددة). استخدم هذا النموذج عندما تتوقع أن يكون لكل مستأجر احتياجات بيانات صغيرة. في هذا النموذج، قم بتعيين نطاق من المستأجرين إلى قاعدة بيانات باستخدام تعيين النطاق.

Range mapping

أو يمكنك تنفيذ نموذج قاعدة بيانات متعددة المستأجرين باستخدام تعيين قائمة لتعيين مستأجرين متعددين لقاعدة بيانات فردية. على سبيل المثال، يتم استخدام DB1 لتخزين معلومات عن معرف المستأجر 1 و5، ويقوم DB2 بتخزين البيانات للمستأجر 7 والمستأجر 10.

Multiple tenants on single DB

الأنواع المدعومة لمفاتيح التجزئة

يدعم Elastic Scale الأنواع التالية كمفاتيح تجزئة:

.NET Java
عدد صحيح عدد صحيح
long long
guid uuid
byte[] byte[]
التاريخ والوقت طابع زمني
timespan duration
datetimeoffset offsetdatetime

قائمة وخرائط جزء النطاق

يمكن إنشاء خرائط الأجزاء باستخدام قوائم بقيم مفاتيح التجزئة الفردية، أو يمكن إنشاؤها باستخدام نطاقات قيم مفتاح التجزئة.

سرد خرائط الأجزاء

تحتويالأجزاء على أجزاء ويتم الحفاظ على تعيين الأجزاء إلى الأجزاء بواسطة خريطة الأجزاء. خريطة جزء القائمة عبارة عن ارتباط بين قيم المفاتيح الفردية التي تحدد الأجزاء وقواعد البيانات التي تعمل كأجزاء. تعدتعيينات القائمة واضحة ويمكن تعيين قيم مفاتيح مختلفة إلى قاعدة البيانات نفسها. على سبيل المثال، يتم تعيين القيمة الرئيسية 1 إلى قاعدة البيانات A، بينما يتم تعيين القيمتين الأساسيتين 3 و6 على قاعدة البيانات B.

المفتاح موقع الأجزاء
1 قاعدة البيانات_A
3 قاعدة البيانات_B
4 قاعدة البيانات_C
6 قاعدة البيانات_B
... ...

نطاق خرائط الأجزاء

في خريطة جزء النطاق، يتم وصف النطاق الرئيسي بواسطة زوج [قيمة منخفضة، قيمة عالية) حيث تكون Low Value هي الحد الأدنى للمفتاح في النطاق، وHigh Value هي أول قيمة أعلى من النطاق.

على سبيل المثال، [0، 100) يشمل جميع الأعداد الصحيحة الأكبر من أو تساوي 0 وأقل من 100. لاحظ أن النطاقات المتعددة يمكن أن تشير إلى نفس قاعدة البيانات، وأن النطاقات المنفصلة مدعومة (على سبيل المثال، [100،200) و[400،600) يشير كلاهما إلى قاعدة البيانات C في المثال التالي.)

المفتاح موقع الأجزاء
[1,50) قاعدة البيانات_A
[50,100) قاعدة البيانات_B
[100,200) قاعدة البيانات_C
[400,600) قاعدة البيانات_C
... ...

كل من الجداول الموضحة أعلاه هو مثال تصوري لكائن ShardMap. كل صف هو مثال مبسط لكائن PointMapping فردي (لخريطة جزء القائمة) أو RangeMapping (لخريطة جزء النطاق).

مدير خريطة الأجزاء

في مكتبة العميل؛ يكون مدير خرائط المقاطع عبارة عن مجموعة من خرائط المقاطع. يتم الاحتفاظ بالبيانات التي يديرها مثيل ShardMapManager في ثلاثة أماكن:

  1. Global Shard Map (GSM) : أنت تحدد قاعدة بيانات لتكون بمثابة مستودع لجميع خرائط الأجزاء وتعييناتها. يتم إنشاء الجداول الخاصة والإجراءات المخزنة تلقائياً لإدارة المعلومات. عادة ما تكون قاعدة بيانات صغيرة ويمكن الوصول إليها بسهولة، ولا ينبغي استخدامها لاحتياجات التطبيق الأخرى. الجداول موجودة في مخطط خاص يسمى __ ShardManagement.
  2. Local Shard Map (LSM) : يتم تعديل كل قاعدة بيانات تحددها لتكون جزءاً لتحتوي على العديد من الجداول الصغيرة والإجراءات المخزنة الخاصة التي تحتوي على معلومات خريطة الأجزاء الخاصة بهذا الجزء وتديرها. هذه المعلومات زائدة عن الحاجة مع المعلومات الموجودة في GSM، وتسمح للتطبيق بالتحقق من صحة معلومات خريطة الأجزاء المخزنة مؤقتاً دون تحميل أي حمل على GSM؛ يستخدم التطبيق LSM لتحديد ما إذا كان التعيين المخزن مؤقتاً لا يزال صالحاً. الجداول المقابلة لـ LSM في كل جزء موجودة أيضاً في مخطط __ ShardManagement.
  3. ذاكرة التخزين المؤقت للتطبيق: يحتفظ كل مثيل تطبيق يصل إلى كائن ShardMapManager بذاكرة تخزين مؤقت محلية في الذاكرة لتعييناته. يقوم بتخزين معلومات التوجيه التي تم استردادها مؤخراً.

إنشاء ShardMapManager

يتم إنشاء كائن ShardMapManager باستخدام نمط مصنع (Java، .NET). تأخذ طريقة ShardMapManagerFactory.GetSqlShardMapManager (Java، .NET) بيانات الاعتماد (بما في ذلك اسم الخادم واسم قاعدة البيانات التي تحمل GSM) في شكل ConnectionString وتقوم بإرجاع مثيل لـ ShardMapManager.

الرجاء ملاحظة: يجب إنشاء مثيل لـ ShardMapManager مرة واحدة فقط لكل نطاق تطبيق، ضمن رمز التكوين لأحد التطبيقات. يؤدي إنشاء مثيلات إضافية من ShardMapManager في نفس مجال التطبيق إلى زيادة استخدام الذاكرة ووحدة المعالجة المركزية للتطبيق. يمكن أن يحتوي ShardMapManager على أي عدد من خرائط الأجزاء. في حين أن خريطة جزء واحد قد تكون كافية للعديد من التطبيقات، فهناك أوقات يتم فيها استخدام مجموعات مختلفة من قواعد البيانات لمخطط مختلف أو لأغراض فريدة؛ في هذه الحالات، قد يكون من الأفضل استخدام خرائط متعددة للأجزاء.

في هذا الرمز، يحاول أحد التطبيقات فتح ShardMapManager باستخدام طريقة TryGetSqlShardMapManager (Java، .NET. في حالة عدم وجود كائنات تمثل ShardMapManager (GSM) العام داخل قاعدة البيانات، تقوم مكتبة العميل بإنشائها باستخدام طريقة CreateSqlShardMapManager (Java، .NET).

// Try to get a reference to the Shard Map Manager in the shardMapManager database.
// If it doesn't already exist, then create it.
ShardMapManager shardMapManager = null;
boolean shardMapManagerExists = ShardMapManagerFactory.tryGetSqlShardMapManager(shardMapManagerConnectionString,ShardMapManagerLoadPolicy.Lazy, refShardMapManager);
shardMapManager = refShardMapManager.argValue;

if (shardMapManagerExists) {
    ConsoleUtils.writeInfo("Shard Map %s already exists", shardMapManager);
}
else {
    // The Shard Map Manager does not exist, so create it
    shardMapManager = ShardMapManagerFactory.createSqlShardMapManager(shardMapManagerConnectionString);
    ConsoleUtils.writeInfo("Created Shard Map %s", shardMapManager);
}
// Try to get a reference to the Shard Map Manager via the Shard Map Manager database.  
// If it doesn't already exist, then create it.
ShardMapManager shardMapManager;
bool shardMapManagerExists = ShardMapManagerFactory.TryGetSqlShardMapManager(
                                        connectionString,
                                        ShardMapManagerLoadPolicy.Lazy,
                                        out shardMapManager);

if (shardMapManagerExists)
{
    Console.WriteLine("Shard Map Manager already exists");
}
else
{
    // Create the Shard Map Manager.
    ShardMapManagerFactory.CreateSqlShardMapManager(connectionString);
    Console.WriteLine("Created SqlShardMapManager");

    shardMapManager = ShardMapManagerFactory.GetSqlShardMapManager(
            connectionString,
            ShardMapManagerLoadPolicy.Lazy);

// The connectionString contains server name, database name, and admin credentials for privileges on both the GSM and the shards themselves.
}

بالنسبة لإصدار .NET، يمكنك استخدام PowerShell لإنشاء مدير جديد لخريطة الأجزاء. يتوفر مثال هنا.

احصل على RangeShardMap أو ListShardMap

بعد إنشاء مدير خريطة جزء، يمكنك الحصول على RangeShardMap (Java، .NET) أو ListShardMap (Java، .NET) باستخدام TryGetRangeShardMap (Javaأو .NET) أو TryGetListShardMap (Javaأو .NET) أو GetShardMap (Java، .NET).

// Creates a new Range Shard Map with the specified name, or gets the Range Shard Map if it already exists.
static <T> RangeShardMap<T> createOrGetRangeShardMap(ShardMapManager shardMapManager,
            String shardMapName,
            ShardKeyType keyType) {
    // Try to get a reference to the Shard Map.
    ReferenceObjectHelper<RangeShardMap<T>> refRangeShardMap = new ReferenceObjectHelper<>(null);
    boolean isGetSuccess = shardMapManager.tryGetRangeShardMap(shardMapName, keyType, refRangeShardMap);
    RangeShardMap<T> shardMap = refRangeShardMap.argValue;

    if (isGetSuccess && shardMap != null) {
        ConsoleUtils.writeInfo("Shard Map %1$s already exists", shardMap.getName());
    }
    else {
        // The Shard Map does not exist, so create it
        try {
            shardMap = shardMapManager.createRangeShardMap(shardMapName, keyType);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        ConsoleUtils.writeInfo("Created Shard Map %1$s", shardMap.getName());
    }

    return shardMap;
}
// Creates a new Range Shard Map with the specified name, or gets the Range Shard Map if it already exists.
public static RangeShardMap<T> CreateOrGetRangeShardMap<T>(ShardMapManager shardMapManager, string shardMapName)
{
    // Try to get a reference to the Shard Map.
    RangeShardMap<T> shardMap;
    bool shardMapExists = shardMapManager.TryGetRangeShardMap(shardMapName, out shardMap);

    if (shardMapExists)
    {
        ConsoleUtils.WriteInfo("Shard Map {0} already exists", shardMap.Name);
    }
    else
    {
        // The Shard Map does not exist, so create it
        shardMap = shardMapManager.CreateRangeShardMap<T>(shardMapName);
        ConsoleUtils.WriteInfo("Created Shard Map {0}", shardMap.Name);
    }

    return shardMap;
}

بيانات اعتماد إدارة خريطة الأجزاء

تختلف التطبيقات التي تدير خرائط الأجزاء وتعالجها عن تلك التي تستخدم خرائط الأجزاء لتوجيه الاتصالات.

لإدارة خرائط الأجزاء (إضافة أو تغيير الأجزاء وخرائط الأجزاء وتعيينات الأجزاء وما إلى ذلك)، يجب إنشاء مثيل لـ ShardMapManager باستخدام بيانات الاعتماد التي لها امتيازات القراءة/الكتابة على كل من قاعدة بيانات GSM وفي كل قاعدة بيانات الذي يعمل بمثابة جزء. يجب أن تسمح بيانات الاعتماد بالكتابة مقابل الجداول في كل من GSM وLSM حيث يتم إدخال معلومات خريطة الأجزاء أو تغييرها، وكذلك لإنشاء جداول LSM على الأجزاء الجديدة.

راجع بيانات الاعتماد المستخدمة للوصول إلى مكتبة عميل قاعدة بيانات مرنة.

تتأثر بيانات التعريف فقط

الأساليب المستخدمة لملء أو تغيير بيانات ShardMapManager لا تغير بيانات المستخدم المخزنة في الأجزاء نفسها. على سبيل المثال، تؤثر طرق مثل CreateShard وDeleteShard وUpdateMapping وما إلى ذلك على بيانات التعريف لخريطة الأجزاء فقط. لا يقومون بإزالة أو إضافة أو تعديل بيانات المستخدم الموجودة في الأجزاء. بدلاً من ذلك، تم تصميم هذه الطرق لتستخدم جنباً إلى جنب مع العمليات المنفصلة التي تقوم بإجرائها لإنشاء قواعد بيانات فعلية أو إزالتها، أو التي تنقل الصفوف من جزء إلى آخر لإعادة توازن بيئة مجزأة. (تستخدم أداة الدمج المنقسم المضمنة مع أدوات قاعدة بيانات مرنة واجهات برمجة التطبيقات هذه جنباً إلى جنب مع تنظيم حركة البيانات الفعلية بين الأجزاء.) راجع القياس باستخدام أداة دمج تقسيم قاعدة البيانات المرنة.

التوجيه المعتمد على البيانات

يتم استخدام مدير خريطة الأجزاء في التطبيقات التي تتطلب اتصالات قاعدة البيانات لتنفيذ عمليات البيانات الخاصة بالتطبيق. يجب أن تقترن هذه الاتصالات بقاعدة البيانات الصحيحة. يُعرف هذا باسم التوجيه المعتمد على البيانات. بالنسبة لهذه التطبيقات، قم بإنشاء مثيل لكائن مدير خريطة الأجزاء من المصنع باستخدام بيانات الاعتماد التي لها حق الوصول للقراءة فقط على قاعدة بيانات GSM. توفر الطلبات الفردية للاتصالات اللاحقة بيانات الاعتماد اللازمة للاتصال بقاعدة بيانات الأجزاء المناسبة.

لاحظ أن هذه التطبيقات (باستخدام ShardMapManager المفتوحة ببيانات اعتماد للقراءة فقط) لا يمكنها إجراء تغييرات على الخرائط أو التعيينات. لتلك الاحتياجات، قم بإنشاء تطبيقات خاصة بالإدارة أو برامج PowerShell النصية التي توفر بيانات اعتماد ذات امتيازات أعلى كما تمت مناقشته سابقاً. راجع بيانات الاعتماد المستخدمة للوصول إلى مكتبة عميل قاعدة بيانات مرنة.

لمزيد من المعلومات، راجع التوجيه المعتمد على البيانات.

تعديل خريطة الأجزاء

يمكن تغيير خريطة الأجزاء بطرق مختلفة. تعدل جميع الطرق التالية بيانات التعريف التي تصف الأجزاء وتعييناتها، ولكنها لا تعدل البيانات فعلياً داخل الأجزاء، ولا تنشئ قواعد البيانات الفعلية أو تحذفها. قد تحتاج بعض العمليات على خريطة الأجزاء الموضحة أدناه إلى التنسيق مع الإجراءات الإدارية التي تنقل البيانات فعلياً أو التي تضيف وتزيل قواعد البيانات التي تعمل كقطع.

تعمل هذه الطرق معاً باعتبارها اللبنات الأساسية المتاحة لتعديل التوزيع العام للبيانات في بيئة قاعدة البيانات المُقسمة.

  • لإضافة الأجزاء أو إزالتها: استخدم CreateShard (Java، .NET) وDeleteShard (Java، .NET) من فئة خريطة الأجزاء (Java، .NET).

    يجب أن يكون الخادم وقاعدة البيانات اللذان يمثلان الجزء المستهدف موجودين بالفعل حتى يتم تنفيذ تلك العمليات. هذه الأساليب ليس لها أي تأثير على قواعد البيانات نفسها، فقط على بيانات التعريف في خريطة الأجزاء.

  • لإنشاء أو إزالة النقاط أو النطاقات التي تم تعيينها للأجزاء: استخدم CreateRangeMapping (Java، .NETDeleteMapping (Java، .NET) من the RangeShardMapping (Java، .NET) لفئة، وCreatePointMapping (Java، .NET) لفئة قائمة خريطة الأجزاء (Java، .NET).

    يمكن تعيين العديد من النقاط أو النطاقات المختلفة لنفس الجزء. تؤثر هذه الطرق على بيانات التعريف فقط - فهي لا تؤثر على أي بيانات قد تكون موجودة بالفعل في الأجزاء. إذا كانت هناك حاجة لإزالة البيانات من قاعدة البيانات حتى تتوافق مع عمليات DeleteMapping، فأنت تقوم بإجراء هذه العمليات بشكل منفصل ولكن مع استخدام هذه الطرق.

  • لتقسيم النطاقات الموجودة إلى نطاقات أو دمج نطاقات متجاورة في نطاق واحد: استخدم SplitMapping (Javaو .NET) وMergeMappings (Java، .NET).

    لاحظ أن عمليات التقسيم والدمج لا تغير الجزء الذي يتم تعيين قيم المفاتيح إليه. يقطع الانقسام النطاق الحالي إلى جزأين، ولكنه يترك كليهما كما تم تعيينهما إلى نفس الجزء. يعمل الدمج على نطاقين متجاورين تم تعيينهما بالفعل إلى نفس الجزء، ما يؤدي إلى اندماجهما في نطاق واحد. يجب تنسيق حركة النقاط أو النطاقات نفسها بين الأجزاء باستخدام UpdateMapping جنباً إلى جنب مع حركة البيانات الفعلية. يمكنك استخدام خدمة التقسيم/الدمج التي تعد جزءاً من أدوات قاعدة البيانات المرنة لتنسيق تغييرات خريطة الأجزاء مع حركة البيانات، عند الحاجة إلى الحركة.

  • لإعادة تعيين (أو نقل) نقاط أو نطاقات فردية إلى أجزاء مختلفة: استخدم UpdateMapping (Java، .NET).

    نظراً لأنه قد يلزم نقل البيانات من جزء إلى آخر كي تتوافق مع عمليات UpdateMapping، فإنك تحتاج إلى إجراء هذه الحركة بشكل منفصل ولكن مع استخدام هذه الطرق.

  • لإجراء التعيينات عبر الإنترنت وغير متصل: استخدم MarkMappingOffline (Javaو .NET) وMarkMappingOnline (Java، .NET) للتحكم في حالة الاتصال عبر الإنترنت للتعيين.

    لا يُسمح ببعض العمليات على تعيينات الأجزاء إلا عندما يكون التعيين في حالة "غير متصل"، بما في ذلك UpdateMapping وDeleteMapping. عندما يكون التعيين في وضع عدم الاتصال، فإن الطلب المعتمد على البيانات المستند إلى مفتاح مضمن في ذلك التعيين يُرجع خطأً. بالإضافة إلى ذلك، عند استخدام النطاق في وضع عدم الاتصال لأول مرة، يتم تلقائياً إنهاء جميع الاتصالات بالجزء المتأثر لمنع النتائج غير المتسقة أو غير المكتملة لطلبات البحث الموجهة ضد النطاقات التي يتم تغييرها.

التعيينات هي كائنات غير قابلة للتغيير في .NET. جميع الطرق المذكورة أعلاه التي تغير التعيينات تبطل أيضاً أي مراجع لها في التعليمات البرمجية الخاصة بك. لتسهيل تنفيذ تسلسل العمليات التي تغير حالة التعيين، فإن جميع الطرق التي تغير التعيين تُرجع مرجع تعيين جديداً، بحيث يمكن ربط العمليات. على سبيل المثال، لحذف تعيين موجود في shardmap sm يحتوي على المفتاح 25، يمكنك تنفيذ ما يلي:

    sm.DeleteMapping(sm.MarkMappingOffline(sm.GetMappingForKey(25)));

إضافة جزء

تحتاج التطبيقات غالباً إلى إضافة أجزاء جديدة للتعامل مع البيانات المتوقعة من المفاتيح الجديدة أو نطاقات المفاتيح، لخريطة الأجزاء الموجودة بالفعل. على سبيل المثال، قد يحتاج التطبيق المُقسَّم بواسطة مُعرِّف المستأجر إلى توفير جزء جديد لمستأجر جديد، أو قد تحتاج البيانات المُقسَّمة شهرياً إلى جزء جديد يتم توفيره قبل بداية كل شهر جديد.

إذا لم يكن النطاق الجديد لقيم المفاتيح جزءاً من تعيين حالي ولم يكن من الضروري نقل البيانات، فمن السهل إضافة الجزء الجديد وربط المفتاح أو النطاق الجديد بهذا الجزء. للحصول على تفاصيل عن إضافة أجزاء جديدة، راجع إضافة جزء جديد.

بالنسبة للسيناريوهات التي تتطلب نقل البيانات، ومع ذلك، فإن أداة الدمج المنقسم ضرورية لتنظيم حركة البيانات بين الأجزاء جنباً إلى جنب مع التحديثات الضرورية لخريطة الأجزاء. للحصول على تفاصيل عن استخدام أداة الدمج المنقسم، راجع نظرة عامة على تقسيم الدمج

الموارد الإضافية

ألم تستخدم أدوات قاعدة بيانات مرنة بعد؟ تحقق من ⁧⁩دليل بدء التشغيل⁩. في حالة وجود أسئلة، تواصل معنا على Microsoft Q&A وهي صفحة الأسئلة حول SQL Database ولطلبات الميزات، أضف أفكاراً جديدة أو صوّت للأفكار الموجودة في منتدى ملاحظات SQL Database.