نمط مخبأ جانبا

Azure Cache for Redis

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

السياق والمشكلة

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

حل

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

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

يمكن للتطبيق محاكاة وظيفة التخزين المؤقت للقراءة من خلال تنفيذ استراتيجية التخزين المؤقت. تقوم هذه الإستراتيجية بتحميل البيانات في ذاكرة التخزين المؤقت عند الطلب. يوضح الشكل استخدام نمط Cache-Aside لتخزين البيانات في ذاكرة التخزين المؤقت.

استخدام نمط Cache-Aside لتخزين البيانات في ذاكرة التخزين المؤقت

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

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

المسائل والاعتبارات

راع النقاط التالية عند تحديد كيفية تنفيذ هذا النمط:

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

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

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

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

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

موعد استخدام النمط

استخدم هذا النمط عندما:

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

قد لا يكون هذا النمط مناسبًا:

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

تصميم حمل العمل

يجب على المهندس المعماري تقييم كيفية استخدام نمط Cache-Aside في تصميم حمل العمل الخاص بهم لمعالجة الأهداف والمبادئ التي تغطيها ركائز Azure Well-Architected Framework. على سبيل المثال:

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

- RE:05 التكرار
تساعد كفاءة الأداء حمل العمل الخاص بك على تلبية الطلبات بكفاءة من خلال التحسينات في التحجيم والبيانات والرمز. يمكن الحصول على أداء أفضل في حمل العمل الخاص بك عند استخدام ذاكرة التخزين المؤقت للبيانات كثيفة القراءة التي لا تتغير كثيرا وتم تصميم حمل العمل الخاص بك لتحمل قدر معين من الثبات.

- أداء بيانات PE:08
- PE:12 تحسين الأداء المستمر

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

مثال

في Microsoft Azure، يمكنك استخدام Azure Cache لـ Redis لإنشاء ذاكرة تخزين مؤقت موزعة يمكن مشاركتها بواسطة مثيلات متعددة من التطبيق.

يستخدم مثال التعليمات البرمجية التالي عميل StackExchange.Redis ، وهي مكتبة عميل Redis مكتوبة ل .NET. للاتصال بمثيل Azure Cache لمثيل Redis، قم باستدعاء الأسلوب الثابت ConnectionMultiplexer.Connect وقم بتمرير سلسلة الاتصال. تقوم الطريقة بإرجاع ConnectionMultiplexer الذي يمثل الاتصال. تتمثل إحدى طرق مشاركة مثيل ConnectionMultiplexer في تطبيقك في الحصول على خاصية ثابتة تقوم بإرجاع مثيل متصل، على غرار المثال التالي. يوفر هذا الأسلوب طريقة آمنة لمؤشر الترابط لتهيئة مثيل واحد متصل فقط.

private static ConnectionMultiplexer Connection;

// Redis connection string information
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
    string cacheConnection = ConfigurationManager.AppSettings["CacheConnection"].ToString();
    return ConnectionMultiplexer.Connect(cacheConnection);
});

public static ConnectionMultiplexer Connection => lazyConnection.Value;

يُظهر الأسلوب GetMyEntityAsync في مثال التعليمات البرمجية التالي تنفيذ نمط ذاكرة التخزين المؤقت. يسترد هذا الأسلوب كائنًا من ذاكرة التخزين المؤقت باستخدام طريقة القراءة.

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

// Set five minute expiration as a default
private const double DefaultExpirationTimeInMinutes = 5.0;

public async Task<MyEntity> GetMyEntityAsync(int id)
{
  // Define a unique key for this method and its parameters.
  var key = $"MyEntity:{id}";
  var cache = Connection.GetDatabase();

  // Try to get the entity from the cache.
  var json = await cache.StringGetAsync(key).ConfigureAwait(false);
  var value = string.IsNullOrWhiteSpace(json)
                ? default(MyEntity)
                : JsonConvert.DeserializeObject<MyEntity>(json);

  if (value == null) // Cache miss
  {
    // If there's a cache miss, get the entity from the original store and cache it.
    // Code has been omitted because it is data store dependent.
    value = ...;

    // Avoid caching a null value.
    if (value != null)
    {
      // Put the item in the cache with a custom expiration time that
      // depends on how critical it is to have stale data.
      await cache.StringSetAsync(key, JsonConvert.SerializeObject(value)).ConfigureAwait(false);
      await cache.KeyExpireAsync(key, TimeSpan.FromMinutes(DefaultExpirationTimeInMinutes)).ConfigureAwait(false);
    }
  }

  return value;
}

تستخدم الأمثلة Azure Cache لـ Redis للوصول إلى المتجر واسترداد المعلومات من ذاكرة التخزين المؤقت. لمزيد من المعلومات، راجع استخدام Azure Cache لـ Redis وكيفية إنشاء تطبيق ويب باستخدام Azure Cache لـ Redis.

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

public async Task UpdateEntityAsync(MyEntity entity)
{
    // Update the object in the original data store.
    await this.store.UpdateEntityAsync(entity).ConfigureAwait(false);

    // Invalidate the current cache object.
    var cache = Connection.GetDatabase();
    var id = entity.Id;
    var key = $"MyEntity:{id}"; // The key for the cached object.
    await cache.KeyDeleteAsync(key).ConfigureAwait(false); // Delete this key from the cache.
}

إشعار

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

قد تكون المعلومات التالية ذات صلة عند تنفيذ هذا النمط:

  • يوضح لك نمط تطبيق الويب الموثوق به كيفية تطبيق نمط ذاكرة التخزين المؤقت المصاحبة لتطبيقات الويب المتقاربة على السحابة.

  • دليل التخزين المؤقت. يوفر معلومات إضافية حول كيفية تخزين البيانات مؤقتًا في أحد الحلول السحابية، والمشكلات التي يجب مراعاتها عند تنفيذ ذاكرة تخزين مؤقت.

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