لو عندك Redis cluster بـ 8 سيرفرات وضفت سيرفر تاسع لمعالجة موجة Black Friday، النسخة الساذجة من hash(key) % N هتفقدك 89% من الكاش في ثانية واحدة. كل request هيرجع للـ DB، الـ DB هتقع تحت الضغط، والموقع هيقع معاها. Consistent Hashing بيخلي عدد المفاتيح اللي بتتنقل ≈ 1/N فقط، يعني 11% بدل 89%. المقال ده يوريك ليه بالظبط، وإزاي تطبّقه بـ 30 سطر Python.
Consistent Hashing: حلّ مشكلة سكيل الكاش الموزّع من جذرها
المشكلة باختصار
لما عندك مفاتيح كاش وعايز توزّعها على N سيرفر، أبسط طريقة هي:
server_index = hash(key) % N
المعادلة دي شغّالة طول ما N ثابت. اللحظة اللي N بيتغير فيها — إضافة سيرفر، فشل سيرفر، صيانة مجدولة — كل المفاتيح تقريبًا بتعيد التوزيع، وكاش كل التطبيق بيبقى cold. النتيجة: thundering herd على الـ DB، latency بيقفز 10×، وأحيانًا outage كامل.
مثال للمبتدئ: شركة شحن وموظفي التوصيل
اعتبر شركة شحن عندها 10 موظفين توصيل، كل موظف مسؤول عن مجموعة شوارع. الطريقة الساذجة: رقم_الشارع % 10 يحدد الموظف. شغّال تمام لحد ما الموظف رقم 7 يستقيل. فجأة كل الشوارع بتتعاد قسمتها على 9 بدل 10، يعني الشارع رقم 23 اللي كان بياخده موظف 3 بقى مع موظف 5، والشارع 47 اتنقل من موظف 7 لـ موظف 2، وهكذا. النتيجة: 80% من الشوارع غيّرت موظف، وكل موظف لازم يطبع خرايط جديدة من الصفر ويحفظ زباين جداد.
Consistent Hashing بيقول حاجة مختلفة تمامًا: بدل ما تقسم على عدد الموظفين، رتّب الموظفين على دايرة بترقيم 0 لـ 360. كل شارع بيختار أقرب موظف على الدايرة في اتجاه عقارب الساعة. لما موظف 7 يستقيل، بس الشوارع اللي كانت بتاعته هي اللي بتنتقل لموظف 8، وباقي الموظفين مش متأثرين خالص.
التعريف العلمي الدقيق
Consistent Hashing هي تقنية توزيع keys على عدد متغيّر من nodes بحيث متوسط عدد الـ keys اللي بتعيد التوزيع لما node بيتشال أو يتضاف يساوي K/N، حيث K هو العدد الكلي للـ keys و N هو عدد الـ nodes. بمعنى: إضافة سيرفر تاسع لـ 8 سيرفرات بتنقل 1/9 ≈ 11% من المفاتيح فقط، بدل 89% في الطريقة الساذجة.
اقترحها David Karger وزملاؤه في ورقة 1997 في مؤتمر STOC بعنوان "Consistent Hashing and Random Trees"، وكانت الورقة الأساس لتوزيع تحميل الكاش في Akamai CDN. اليوم بتشغّل DynamoDB partitioning، Cassandra ring، Discord session routing، Riak، وRedis Cluster (بشكل معدّل اسمه hash slots).
الفكرة الأساسية: الـ Hash Ring
- اعمل hash لكل node بقيمة في فضاء كبير (مثلاً 0 لـ 2³²).
- اعمل hash للـ key نفسه بنفس الدالة.
- المالك للـ key = أول node بعد قيمة hash الـ key لو مشيت في اتجاه عقارب الساعة على الدايرة.