التصنيفات
infrastructure optimization

Redis ام Memcached


Redis و Memcached كلاهما أنظمة مفتوحة المصدر عالية الأداء لإدارة الذاكرة المؤقتة . كلا النظامين يخزن معظم البيانات الموجودة في الذاكرة المؤقتة الـ Ram ويدير عدة عمليات عليها. لكن الفرق الجوهري بين النظامين تقريبا هو ان Redis يدعم بنى بيانات ( Data structure ) اكثر بكثير , بما في ذلك linked lists والـ hash tables وغيرها.
في هذه المقالة ، سنبحث الفرق بين Redis و Memcached. وبعض المعلومات عن ميزات النظامين

مقارنة الميزات

العمليات على السيرفر ( server side )
يدعم Redis عمليات التخزين وتمثيل البيانات في السيرفر ، ويمتلك عدد اكبر من بنى البيانات ( Data structure ) ويدعم عمليات أكثر من Memcached.
في Memcached ، اذا اردت اجراء بعض التعديلات على البيانات المخزنة مثل اعادة ترتيبها او ازالة التكرار او غيرها تحتاج إلى جلب البيانات من الذاكرة ثم تعديلها ( لربما عبر كود تكتبه في برنامجك او ارسالها لجهة العميل clinet side ) ثم تعييد ارجاع البيانات للسيرفر او الرام ان كنت تخزن البيانات على نفس السيرفر . والنتيجة هي أن هذا يزيد بشكل كبير من عدد العمليات والطلبات على السيرفر و الشبكة وأحجام البيانات. في Redis ، تكون هذه العمليات المعقدة اكثر كفائة وفعالية . لذلك ، إذا كنت بحاجة لدعم بنى بيانات وعمليات أكثر تعقيدًا ، فإن Redis يعد اختيارًا جيدًا.

مقارنة الكفاءة في استخدام الذاكرة
Memcached يعتبر ذو كفائة عاليه في تخزين البيانات على شكل ( key-value ) . بينما يتبنى Rides تمثيل البيانات على شكل ( hash structure ) ، لذلك معدل كفائة الذاكرة أعلى من Memcached بفضل ما يسمى بوضع ضغط البيانات ( combined compression mode )

مقارنة الأداء
يعتمد الـ Redis ال ( single threaded ) بعمليات الادخال والاخراج لذلك فهو يعتمد على نواة واحدة من المعالج ( singel core ) فقط بينما تستخدم Memcached ال ( multithreaded ) بالتالي ممكن ان تستخدم اكثر من نواة في المعالج ( multiple cores ) . لذلك في المتوسط ​​، تفتخر Redis بأداء أعلى من Memcached في تخزين البيانات الصغيرة عند قياسها من ناحية عدد الانوية المستخدمة في معالجة البيانات. بينما يتفوق Memcached Redis لتخزين البيانات من 100K أو أعلى. على الرغم من قيام Redis بإجراء بعض التحسينات لتخزين البيانات الكبيرة ، إلا أنها لا تزال أدنى من Memcached.

دعونا الآن نناقش بعض النقاط لدعم المقارنات المذكورة أعلاه.

أنواع البيانات المختلفة المدعومة

بخلاف Memcached الذي يدعم فقط البيانات ذات بالبنية الأساسية البسيطة ( key-value structure )، يدعم Redis أنواع البيانات أكثر ثراءً وتعقدياً، بما في ذلك String و Hash و List و Set و Set Sorted Set.
بشكل عام يستخدم Redis الـ redisObject لتمثيل كافة المفاتيح والقيم. المعلومات الأساسية لـ redisObject هي كما هو موضح أدناه:

 يمثل المخطط السابق البيانات في ال ( value object ).
يمثل ( encoding ) طريقة التخزين لأنواع البيانات المختلفة في Redis ، مثل type = string يمثل أن القيمة تخزن نص ،
او مثلا int. إذا كان int ، وغيرها
الآن دعونا نناقش بعض أنواع البيانات.

النصوص strings

تستخدم الاوامر التالية: set/get/decr/incr/mget .

تستخدم عادةً : للنصوص ( strings ) فهي نوع البيانات الأكثر شيوعًا بالعادة تخزن على شكل key/value .

Hash

تستخدم الاوامر التالية: hget/hset/hgetall وغيرها.

تستخدم عادةً : لتخزين معلومات المستخدم ، بما في ذلك رقم المستخدم واسم المستخدم والعمر وتاريخ الميلاد ؛ ويتم إستعادة اسم المستخدم أو العمر أو عيد الميلاد من خلال معرف المستخدم ID.

السلاسل List

تستخدم الاوامر التالية: lpush/rpush/lpop/rpop/lrange.

تستخدم عادةً : السلاسل ( List ) هي أهم بنية بيانات في Redis. في الواقع ، من الممكن تطبيق قائمة Twitter وقائمة المعجبين باستخدام السلاسل ( List ) في الـ Redis.

Set

تستخدم الاوامر التالية: sadd/spop/smembers/sunion وغيرها.

تستخدم عادةً : الـ Set في الـ Redis مماثلة للـ List . إلا انها يمكنها إزالة التكرارات تلقائيًا. عندما تحتاج إلى تخزين قائمة بيانات دون أي تكرار ، فإن الـ Set تعد خيارًا جيدًا. بالإضافة إلى ذلك ، توفر المجموعة واجهة  اوامر للاستعلام على ما إذا كان العضو ضمن مجموعة ، وهي ميزة لا توفرها ال List.

Sorted Set

تستخدم الاوامر التالية: zadd/zrange/zrem/zcard وغيرها.

تستخدم عادةً : هنالك تشابه كبير بينها وبين ال Set. الفرق هو أنه أن الـ Set لا تقوم تلقائيًا بترتيب البيانات ، فإن الـ Sorted Set يمكنها فرز البيانات من خلال قيمة مرجعية معينة يقدمها المستخدم . والأكثر من ذلك ، أن هذا الأخير تفرز البيانات التي يتم إدخالها تلقائيًا. يمكنك اختيار بنية الـ sorted set عندما تحتاج إلى قائمة منظمة بدون بيانات مكررة ، مثل الـ Time line لتويتر ، والذي يمكن ان يكون وقت النشر كـ ( قيمة مرجعية ) مع الفرز التلقائي للبيانات التي يتم الحصول عليها حسب الوقت.

 الاختلاف في ادارة الذاكرة

في Redis ، لا يتم تخزين البيانات في الذاكرة المؤقتة الـ Ram بل من الممكن ان يقوم Redis بنقل بعض البيانات إلى القرص الصلب ال Hard Disk. وهذا فرق كبير بين Redis و Memcached. فعند امتلاء الذاكرة المؤقتة الـ Ram ، قد يقوم Redis بنقل القيم غير المستخدمة لفترة طويلة إلى القرص الصلب. يقوم Redis بتخزين جميع المفاتيح ( key’s ). إذا اكتشف أن استخدام الذاكرة يتجاوز قيمة معينة ( عادة تكون معرفة مسبقاً ) ، فسيؤدي ذلك إلى تشغيل عملية النقل الـ Swap. يقوم Redis بحساب قيم المفاتيح التي سيتم نقلها إلى القرص استنادًا إلى المعادلة التالية
“قابلية التبديل = عمر البيانات * لوغ ( الحجم في الذاكرة )”.
ثم يقوم بنقل هذه القيم للقرص الصلب الـ Hard Disk ويقوم بمحوها من الذاكرة المؤقته الـ Ram. تتيح هذه الميزة لـ Redis الحفاظ على بيانات بحجم أكبر من سعة ذاكرة الجهاز.

في الوقت نفسه ، عندما يقوم Redis بتبديل البيانات الموجودة في الذاكرة المؤقتة الـ Ram إلى القرص الصلب الـ Hard Disk ، تقوم Thread بتوفير خدمات الاستعلام والادخال ،  ويقوم thread فرعي بعملية نقل البيانات وكلاهما يعملان على نفس المنطقة من الذاكرة. إذا قمت بتحديث البيانات التي تجري عليها عملية النقل ، فسوف يقوم Redis بتجميد كل عمليات التحديق هذه العملية لحين انتهاء عملية النقل ، مما يحول دون تنفيذ هذا التغيير حتى تكمل الthread عملية المبادلة. عندما تقرأ بيانات من Redis ، إذا كانت قيمة مفتاح القراءة غير موجودة في الذاكرة ، فإن Redis يحتاج إلى تحميل البيانات من القرص الصلب ثم يعيدها إليك ،هنا تحدث مشكلة I/O . بشكل افتراضي ، سيواجه Redis الازدحام ، أي أنه لن يستجيب إلا بعد التحميل الناجح لجميع ملفات النقل من القرص الصلب .
هذه الطريقة مناسبة للعمليات عندما يكون هناك عدد صغير من العملاء. ولكن إذا قمت بتطبيق Redis في موقع كبير بعمليات قراءة وكتابة كثير ، فلن يكون قادرًا على تلبية المتطلبات بكفائة. يوجد بعض التوصيات لحل هذه المشكلة ولكن ان اذكرها هنا.

دعم استمرارية البيانات
( data persistence )

على الرغم من ان Redis يتعامل مع الذاكرة المؤقتة الـ Ram ، إلا أن Redis يدعم استمرارية بيانات الذاكرة ( memory data persistence ) حيث تستطيع استعادة البيانات في حال حصلت مشكلة او قطع في الطاقة عبر اليتين هما ( RDB snapshot و AOF log ) بينما لم يقدم Memcached اي يدعم عمليات استمرار البيانات الا في النسخة الاخيرة التي تحمل الرقم 1.5.18 عبر الية DAX filesystem mounts.

لقطة RDB


يدعم Redis تخزين لقطة ( snapshot ) عن البيانات الحالية في ملف بيانات للاستعادة في الحالات الطارئة . ولكن كيف يمكننا إنشاء لقطة لقاعدة البيانات الحالية مع عمليات كتابة البيانات المستمرة؟ يقوم Redis عند إنشاء لقطة بالكتابة من خلال انشاء عملية كتابة فرعية . تقوم العملية الحالية بتكوين عملية فرعية تخزن كل البيانات بشكل دوري وتكتبها في ملف RDB. يمكننا تهيئة توقيت إنشاء لقطة RDB من خلال أمر الحفظ لـ Redis. على سبيل المثال ، إذا كنت ترغب في تكوين إنشاء لقطة لمرة واحدة كل 10 دقائق ، يمكنك تكوين إنشاء لقطة بعد كل 1000 عملية كتابة. يمكنك أيضًا تكوين قواعد متعددة للتنفيذ معًا. توجد تعريفات لهذه القواعد في ملفات تهيئة Redis. يمكنك أيضًا تعيين القواعد باستخدام الأمر CONFIG SET من Redis أثناء وقت تشغيل Redis دون إعادة تشغيل Redis.

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

سجل AOF

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

بالنهاية بالنسبة ل Redis
لمتطلبات العمل العامة ، أقترح عليك استخدام RDB لأن RDB اخف على النظام من سجلات AOF. اما ان كانت بياناتك حساسة ولا تحتمل مخاطرة فقد أي للبيانات ، أوصيك باستخدام سجلات AOF.

الخلاصة

استعرضنا في هذه المقالة بعض جوانب القوة لدى النظامين ارجوا تنتبه عزيزي القاريء انني لم اغطي كل الجوانب لدى النظامين لذلك لا تعتبر هذه المقالة تفضيل ل Redis على ال Memcached لكن هذا رأي شخصي بالنهاية وما يحسم الافضلية هو استخدامك للنظام وحجم بياناتك

المراجع

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *