PmaControl logo PmaControl
  • مرحباً
  • PmaControl
    • وكلاء الذكاء الاصطناعي 13 وكلاء محليين
    • عروضنا المجتمع، السحابة، محليًا، المميز
    • التوثيق أدلة، API، الهندسة المعمارية
    • السوق المكونات الإضافية للمجتمع
    • عملاء أكثر من 28 شركة
    • الأسئلة الشائعة 25 سؤالا / 7 فئات
    قواعد البيانات
    • ماريا دي بي 31 مادة
    • ماي إس كيو إل 11 مادة
    • مجموعة جاليرا 6 عناصر
    • ماكس سكيل 3 عناصر
    • ProxySQL 2 عناصر
    • أمازون أورورا ماي إس كيو إل 0 العناصر
    • قاعدة بيانات أزور 0 العناصر
    • انقر البيت 0 العناصر
    • GCP CloudSQL 0 العناصر
    • بيركوناسيرفر 0 العناصر
    • متجر واحد 0 العناصر
    • تي دي بي 0 العناصر
    • سرعة 0 العناصر
    الحلول
    • دعم 24 × 7 حالات الطوارئ MariaDB وMySQL
    • Observabilité SQL المراقبة والتنبيهات والطوبولوجيا
    • Haute disponibilité النسخ المتماثل، تجاوز الفشل، جاليرا
    • Disaster Recovery النسخ الاحتياطي والاستعادة، RPO/RTO
    • Sécurité & conformité التدقيق، اللائحة العامة لحماية البيانات، SOC2
    • Migration & upgrade صفر توقف عن العمل، pt-osc، gh-ost
  • عروضنا
  • موارد
    • التوثيق الأدلة الفنية وواجهات برمجة التطبيقات
    • مركز تحسين MySQL مؤشر تخفيض السعر والمقاييس والإعدادات والحوادث
    • الأسئلة الشائعة 25 سؤالا متكررا
    • الشهادات ملاحظات العملاء وحالات الاستخدام
    • مدونة مقالات ورؤى
    • خريطة الطريق الميزات القادمة
    مجالات الخبرة
    • Observabilité SQL المراقبة والتنبيهات وطوبولوجيا Dot3
    • Haute disponibilité النسخ المتماثل، تجاوز الفشل، جاليرا
    • Sécurité & conformité التدقيق، اللائحة العامة لحماية البيانات، SOC2، ISO 27001
    • Disaster Recovery النسخ الاحتياطي والاستعادة، RPO/RTO
    • Performance & optimisation ملخصات، شرح، ضبط
    • Migration & upgrade صفر توقف عن العمل، pt-osc
    روابط سريعة
    • جيثب ويكي 26 صفحة - التثبيت والمحرك والمكونات الإضافية
    • كود المصدر مستودع جيثب الرسمي
    • دعم 24 × 7 حالات الطوارئ MariaDB وMySQL
    • احجز عرضًا توضيحيًا 30 دقيقة - هندسة معمارية حقيقية
  • دعم 24 × 7
  • احجز عرضًا توضيحيًا
احجز عرضًا توضيحيًا
🇫🇷 FR Français 🇬🇧 EN English 🇵🇱 PL Polski 🇷🇺 RU Русский 🇨🇳 ZH 中文 🇸🇦 AR العربية
← العودة إلى بلوق

GeoIP في PmaControl: دقة IPv4 وIPv6 بدون ملف mmdb في كل طلب

تم النشر بتاريخ 15 أبريل 2026 بواسطة Aurélien LEQUOY
pmacontrol geoip ipv6 mariadb performance architecture
يشارك X LinkedIn Facebook Email PDF
GeoIP في PmaControl: دقة IPv4 وIPv6 بدون ملف mmdb في كل طلب

المشكلة

عند مراقبة أكثر من 100 خادم MariaDB / MySQL منتشرة عبر مراكز بيانات وبلدان متعددة، يظهر سؤال واحد في كل مرة تقوم فيها بعرض الصفحة الرئيسية: أين يوجد هذا الخادم؟

الإجابة الكلاسيكية: افتح ملف MaxMind GeoLite2 .mmdb، وقم بالبحث عن كل عنوان IP، واعرض علم الدولة. بسيطة...إلا أن:

  • فتح ملف .mmdb بحجم 70 ميجابايت مع كل طلب HTTP أمر مكلف
  • مع وجود 100 خادم يجب حلها، يعني ذلك 100 عملية بحث عن الملفات في كل صفحة
  • الملف عبارة عن شجرة ثنائية محسنة للقراءة المتسلسلة، وليس للتقسيم المتوازي
  • في PHP-FPM، يقوم كل عامل بإعادة تحميل الملف بشكل مستقل

في PmaControl، يتم تحديث صفحة server/main كل ثانية باستخدام AJAX. فتح .mmdb 100 مرة في الثانية هو هراء.

الحل: ضع كل شيء في MariaDB

الفكرة بسيطة: قم باستيراد جميع نطاقات GeoLite2 إلى جدول MariaDB، ثم قم بإجراء عمليات البحث الكلاسيكية عن SQL. يعد SELECT المزود بفهرس أسرع بكثير من فحص الشجرة الثنائية على القرص.

الرسم التخطيطي

CREATE TABLE data_geoip (
  id INT AUTO_INCREMENT PRIMARY KEY,
  network_start VARBINARY(16) NOT NULL,
  network_end   VARBINARY(16) NOT NULL,
  country_iso   CHAR(2) NOT NULL DEFAULT '',
  country_name  VARCHAR(100) NOT NULL DEFAULT '',
  INDEX idx_network_start (network_start)
) ENGINE=InnoDB;

يعد اختيار VARBINARY(16) أمرًا بالغ الأهمية:

  • 4 بايت كافية لـ IPv4 (32 بت)
  • 16 بايت مطلوبة لـ IPv6 (128 بت)
  • VARBINARY(16) يخزن كليهما بالتساوي
  • INET6_ATON() يحول أي IP (v4 أو v6) إلى ثنائي قابل للمقارنة

طلب البحث

SELECT country_iso FROM data_geoip
WHERE network_start <= INET6_ATON('89.30.104.134')
  AND network_end   >= INET6_ATON('89.30.104.134')
LIMIT 1;

النتيجة: FR (فرنسا). وقت التنفيذ: < 1 مللي ثانية.

يعمل نفس الاستعلام مع IPv6:

SELECT country_iso FROM data_geoip
WHERE network_start <= INET6_ATON('2001:4860:4860::8888')
  AND network_end   >= INET6_ATON('2001:4860:4860::8888')
LIMIT 1;

النتيجة: US (الولايات المتحدة — هذا هو DNS العام لـ Google).

الاستيراد: تكرار مساحة IP

IPv4: من 0.0.0.0 إلى 255.255.255.255

مساحة IPv4 هي 2^32 = 4.3 مليار عنوان. نحن لا نستعرضها واحدًا تلو الآخر — بل نستخدم getWithPrefixLen() من قارئ MaxMind الذي يُرجع CIDR الكامل لكل عنوان:

$ip = 0;
while ($ip <= 4294967295) {
    [$record, $prefixLen] = $reader->getWithPrefixLen(long2ip($ip));

    // Calculer la fin du réseau
    $networkSize = 1 << (32 - $prefixLen);
    $networkEnd = $ip + $networkSize - 1;

    if ($record && !empty($record['country']['iso_code'])) {
        // INSERT dans data_geoip
    }

    // Sauter tout le bloc CIDR
    $ip = $networkEnd + 1;
}

النتيجة: ~650,000 نطاق تم استيرادها في ثوانٍ. يغطي كل نطاق كتلة CIDR بأكملها (على سبيل المثال: 89.30.104.0/22 → 1024 عنوانًا في سطر واحد).

IPv6: مساحة 2000::/3

مساحة IPv6 هي 2^128 عنوان - من المستحيل التنقل مثل IPv4. لكن العناوين العامة القابلة للتوجيه موجودة في كتلة 2000::/3 (البث الموحد العالمي)، وتكون تخصيصات GeoIP عادةً في /32 إلى /48.

المبدأ هو نفسه: التقدم بحجم البادئة التي تم إرجاعها. الفرق: نحن نعمل مع عناوين ثنائية بحجم 16 بايت.

$current = inet_pton('2000::');
$end6    = inet_pton('3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff');

while ($current <= $end6) {
    [$record, $prefixLen] = $reader->getWithPrefixLen(inet_ntop($current));
    $endBin = binNetworkEnd($current, $prefixLen);

    if ($record && !empty($record['country']['iso_code'])) {
        // INSERT avec UNHEX(bin2hex(...))
    }

    $current = binIncrement($endBin); // +1 en arithmétique 128 bits
}

يتم تنفيذ الحساب الثنائي 128 بت بلغة PHP خالصة (لا يتطلب GMP):

// Incrémenter une adresse IPv6 de 1
function binIncrement(string $bin): string|false
{
    $bytes = unpack('C16', $bin);
    for ($i = 15; $i >= 0; $i--) {
        $bytes[$i]++;
        if ($bytes[$i] <= 255) return pack('C16', ...$bytes);
        $bytes[$i] = 0; // carry
    }
    return false; // overflow
}

النتيجة في الإنتاج

مجلدات

الجدول IPv4 IPv6 المجموع
data_geoip (بلد) ~650 ألف ~180 ألف نطاقات ~ 830 ألف
data_geoip_city (مدينة) ~3.7 م ~1.2 م ~4.9 مليون صف

الأداء

عملية الوقت
بلد الاستيراد (IPv4 + IPv6) ~30 ثانية
استيراد المدينة (IPv4 + IPv6) ~5 دقائق
بحث 1 IP <1 مللي ثانية
بحث عن 100 IP (خادم الصفحة/الرئيسي) ~15 مللي ثانية إجمالي
تحديث AJAX (1x/ثانية) لا يذكر

العرض

في الصفحة الرئيسية لـ PmaControl، يعرض كل خادم علامة الرموز التعبيرية الخاصة به بجوار عنوان IP:

🇫🇷 89.30.104.134:3306    PIXID-MDB-MASTER1
🇩🇪 136.243.1.1:3306       Hetzner-Slave
🇯🇵 210.171.224.1:3306     NTT-Tokyo
🇺🇸 8.8.8.8:3306           Google-Test

عناوين IP الخاصة (10.x، 172.16-31.x، 192.168.x، 127.x) لا تحتوي على سجل GeoLite2 - العلامة مفقودة ببساطة.

تحديث

يقوم MaxMind بتحديث GeoLite2 كل أسبوع. للتحديث:

# Télécharger le nouveau .mmdb dans data/
# Puis relancer l'import :
php App/Webroot/index.php server loadGeoip       # country (~30s)
php App/Webroot/index.php server loadGeoipCity   # city (~5min)

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

مدينة الطاولة: اذهب إلى أبعد من ذلك

يضيف الجدول data_geoip_city المنطقة والمدينة وإحداثيات نظام تحديد المواقع العالمي (GPS) والمنطقة الزمنية:

SELECT country_iso, region_name, city, latitude, longitude, time_zone
FROM data_geoip_city
WHERE network_start <= INET6_ATON('136.243.1.1')
  AND network_end   >= INET6_ATON('136.243.1.1')
LIMIT 1;

النتيجة: DE | Saxony | Falkenstein | 50.4779 | 12.3713 | Europe/Berlin

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

لماذا لا يقتصر الأمر على الانضمام الأيسر فقط؟

قد نرغب في إجراء LEFT JOIN data_geoip g ON g.network_start <= INET6_ATON(s.ip) AND g.network_end >= INET6_ATON(s.ip) مباشرة في طلب الخادم. المشكلة: مع نطاقات تبلغ 650 ألفًا، يكون هذا الانضمام إلى النطاق مكلفًا بالنسبة للمُحسِّن. نحن نفضل عمليات البحث الفردية N (1 لكل عنوان IP فريد) والتي تكون فورية بفضل الفهرس.

الخلاصة

من خلال استيراد بيانات GeoLite2 إلى MariaDB، فإننا نزيل الاعتماد على ملف .mmdb في كل مرة يتم فيها عرض الصفحة. يصبح البحث SELECT مفهرسًا عند < 1 مللي ثانية، ومتوافقًا مع IPv4 وIPv6، ويكون التحديث أسبوعيًا بسيطًا TRUNCATE + INSERT.

كود المصدر متاح على GitHub - نرحب بالمساهمات.

يشارك X LinkedIn Facebook Email PDF
← العودة إلى بلوق

تعليقات (0)

لا توجد تعليقات حتى الآن.

اترك تعليقا

PmaControl
+33 6 63 28 27 47 contact@pmacontrol.com
إشعارات قانونية GitHub اتصال
لا تنتظر وقوع الحادث حتى تفهم هندستك المعمارية. © 2014-2026 PmaControl — 68Koncept