MongoDB Sharding: دليل عملي خطوة بخطوة

التقاسم هي عملية تقسيم النطاق الواسع لمجموعات البيانات إلى مجموعة من مجموعات البيانات الأصغر عبر مثيلات MongoDB المتعددة في بيئة موزعة.

ما هو التقاسم؟

توفر تجزئة MongoDB لنا حلاً قابلاً للتوسع لتخزين كمية كبيرة من البيانات بين عدد الخوادم بدلاً من تخزينها على خادم واحد.

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

في الأساس ، هناك نوعان من طرق القياس الموجودة لإجراء بيانات متزايدة مع النظام:

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

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

تعمل طريقة Mongo DB على تقنية القياس الأفقي.

مكونات التكسير

لتحقيق التجزئة في MongoDB ، يلزم وجود المكونات التالية:

Shard هو مثيل Mongo للتعامل مع مجموعة فرعية من البيانات الأصلية. يجب نشر الأجزاء في مجموعة النسخ المتماثلة.

Mongos هو مثيل Mongo ويعمل كواجهة بين تطبيق عميل ومجموعة مُقسمة. يعمل كجهاز توجيه استعلام عن القطع.

خادم التكوين هو مثيل Mongo الذي يخزن معلومات البيانات الوصفية وتفاصيل تكوين الكتلة. يتطلب MongoDB نشر خادم التكوين كمجموعة نسخ متماثلة.

الهندسة المعمارية

تتكون كتلة MongoDB من عدد من مجموعات النسخ المتماثلة.

تتكون كل مجموعة نسخ متماثلة من 3 أو أكثر من مثيلات mongo على الأقل. قد تتكون المجموعة المُقسَّمة من مثيلات متعددة لشظايا mongo ، ويعمل كل مثيل جزء داخل مجموعة نسخ متماثلة للجزء. يتفاعل التطبيق مع Mongos ، والذي بدوره يتواصل مع القطع. لذلك في Sharding ، لا تتفاعل التطبيقات بشكل مباشر مع عُقد الأجزاء. يوزع موجه الاستعلام مجموعات فرعية من البيانات بين عقد الأجزاء بناءً على مفتاح الجزء.

تنفيذ التقسيم

اتبع الخطوات أدناه للتجزئة

الخطوة 1

  • بدء خادم التكوين في مجموعة النسخ المتماثلة وتمكين النسخ المتماثل بينها.

mongod –configsvr –port 27019 –replSet rs0 –dbpath C: datadata1 –bind_ip localhost

mongod –configsvr –port 27018 –replSet rs0 –dbpath C: datadata2 –bind_ip localhost

mongod –configsvr –port 27017 –replSet rs0 –dbpath C: datadata3 –bind_ip localhost

الخطوة 2

  • تهيئة مجموعة النسخ المتماثلة على أحد خوادم التكوين.

rs.initiate ({_id: “rs0”، configsvr: true، members: [   { _id: 0, host: “IP:27017” },   { _id: 1, host: “IP:27018” },   { _id: 2, host: “IP:27019” }    ] })

rs.initiate( { _id : "rs0",  configsvr: true,  members: [   { _id: 0, host: "IP:27017" },   { _id: 1, host: "IP:27018" },   { _id: 2, host: "IP:27019" }    ] })
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1593569257, 1),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(0, 0),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569257, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569257, 1)
}

الخطوه 3

  • بدء تجزئة الخوادم في مجموعة النسخ المتماثلة وتمكين النسخ المتماثل بينها.
  أفضل 6 مدراء بروكسي لإدارة الوكلاء على نطاق واسع

mongod –shardsvr –port 27020 –replSet rs1 –dbpath C: datadata4 –bind_ip localhost

mongod –shardsvr –port 27021 –replSet rs1 –dbpath C: datadata5 –bind_ip localhost

mongod –shardsvr –port 27022 –replSet rs1 –dbpath C: datadata6 –bind_ip localhost

يقوم MongoDB بتهيئة أول خادم تجزئة كخادم أساسي ، لنقل استخدام خادم التجزئة الأساسي ابتدائي طريقة.

الخطوة 4

  • تهيئة مجموعة النسخ المتماثلة على أحد الخوادم التي تمت مشاركتها.

rs.initiate ({_id: “rs0” ، الأعضاء: [   { _id: 0, host: “IP:27020” },   { _id: 1, host: “IP:27021” },   { _id: 2, host: “IP:27022” }    ] })

rs.initiate( { _id : "rs0",  members: [   { _id: 0, host: "IP:27020" },   { _id: 1, host: "IP:27021" },   { _id: 2, host: "IP:27022" }    ] })
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593569748, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1593569748, 1)
}

الخطوة الخامسة

  • ابدأ المانجو للعنقود المكسور

mongos –port 40000 –configdb rs0 / localhost: 27019 ، المضيف المحلي: 27018 ، المضيف المحلي: 27017

الخطوة 6

  • قم بتوصيل خادم الطريق mongo

مونجو بورت 40000

  • الآن ، أضف خوادم تجزئة.

sh.addShard (“rs1 / localhost: 27020 ، المضيف المحلي: 27021 ، المضيف المحلي: 27022”)

sh.addShard( "rs1/localhost:27020,localhost:27021,localhost:27022")
{
        "shardAdded" : "rs1",
        "ok" : 1,
        "operationTime" : Timestamp(1593570212, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570212, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

الخطوة 7

  • على صدفة mongo ، قم بتمكين التجزئة على DB والمجموعات.
  • تفعيل التجزئة على قاعدة البيانات

sh.enableSharding (“geekFlareDB”)

sh.enableSharding("geekFlareDB")
{
        "ok" : 1,
        "operationTime" : Timestamp(1591630612, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1591630612, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

الخطوة 8

  • لتقسيم مفتاح جزء المجموعة (الموضح لاحقًا في هذه المقالة) مطلوب.

بناء الجملة: sh.shardCollection (“dbName.collectionName”، {“key”: 1})

sh.shardCollection("geekFlareDB.geekFlareCollection", { "key" : 1 } )
{
        "collectionsharded" : "geekFlareDB.geekFlareCollection",
        "collectionUUID" : UUID("0d024925-e46c-472a-bf1a-13a8967e97c1"),
        "ok" : 1,
        "operationTime" : Timestamp(1593570389, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570389, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

لاحظ في حالة عدم وجود المجموعة ، قم بإنشاء ما يلي.

db.createCollection("geekFlareCollection")
{
        "ok" : 1,
        "operationTime" : Timestamp(1593570344, 4),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593570344, 5),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

الخطوة 9

أدخل البيانات في المجموعة. ستبدأ سجلات Mongo في النمو ، وتشير إلى أن الموازن يعمل ويحاول موازنة البيانات بين الأجزاء.

الخطوة 10

الخطوة الأخيرة هي التحقق من حالة التجزئة. يمكن التحقق من الحالة عن طريق تشغيل الأمر أدناه على عقدة مسار Mongos.

حالة التقسيم

تحقق من حالة التجزئة عن طريق تشغيل الأمر أدناه على عقدة مسار mongo.

sh.status ()

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5ede66c22c3262378c706d21")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/localhost:27020,localhost:27021,localhost:27022",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs1
        Time of Reported error:  Tue Jun 09 2020 15:25:03 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs1",  "partitioned" : true,  "version" : {  "uuid" : UUID("a770da01-1900-401e-9f34-35ce595a5d54"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCol
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
                geekFlareDB.geekFlareCollection
                        shard key: { "product" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs1     1
                        { "product" : { "$minKey" : 1 } } -->> { "product" : { "$maxKey" : 1 } } on : rs1 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs1",  "partitioned" : false,  "version" : {  "uuid" : UUID("fbc00f03-b5b5-4d13-9d09-259d7fdb7289"),  "lastMod" : 1 } }

mongos>

توزيع البيانات

يوزع جهاز توجيه Mongos الحمل بين الأجزاء بناءً على مفتاح الجزء ، ويوزع البيانات بالتساوي ؛ يدخل الموازن حيز التنفيذ.

  كيفية تخصيص نماذج Google بالسمات والصور والخطوط

المكون الرئيسي لتوزيع البيانات بين القطع هي

  • يلعب الموازن دورًا في موازنة المجموعة الفرعية من البيانات بين العقد المُقسمة. يعمل Balancer عندما يبدأ خادم Mongos في توزيع الأحمال بين الأجزاء. بمجرد البدء ، قام Balancer بتوزيع البيانات بشكل متساوٍ. للتحقق من حالة الموازن ، قم بتشغيل sh.status () أو sh.getBalancerState () أو sh.isBalancerRunning ().
mongos> sh.isBalancerRunning()
true
mongos>

أو

mongos> sh.getBalancerState()
true
mongos>

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

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5efbeff98a8bbb2d27231674")
  }
  shards:
        {  "_id" : "rs1",  "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",  "state" : 1 }
        {  "_id" : "rs2",  "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",  "state" : 1 }
  active mongoses:
        "4.2.7" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  yes
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Could not find host matching read preference { mode: "primary" } for set rs2
        Time of Reported error:  Wed Jul 01 2020 14:39:59 GMT+0530 (India Standard Time)
        Migration Results for the last 24 hours:
                1024 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1024
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "geekFlareDB",  "primary" : "rs2",  "partitioned" : true,  "version" : {  "uuid" : UUID("a8b8dc5c-85b0-4481-bda1-00e53f6f35cd"),  "lastMod" : 1 } }
                geekFlareDB.geekFlareCollection
                        shard key: { "key" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                rs2     1
                        { "key" : { "$minKey" : 1 } } -->> { "key" : { "$maxKey" : 1 } } on : rs2 Timestamp(1, 0)
        {  "_id" : "test",  "primary" : "rs2",  "partitioned" : false,  "version" : {  "uuid" : UUID("a28d7504-1596-460e-9e09-0bdc6450028f"),  "lastMod" : 1 } }

mongos>
  • يحدد Shard Key المنطق لتوزيع مستندات المجموعة المُقسمة بين الأجزاء. يمكن أن يكون مفتاح Shard حقلاً مُفهرسًا أو حقلًا مركبًا مُفهرسًا مطلوب وجوده في جميع مستندات المجموعة المراد إدراجها. سيتم تقسيم البيانات إلى أجزاء ، وسيتم ربط كل جزء بمفتاح الجزء المستند إلى النطاق. على أساس استعلام النطاق ، سيقرر جهاز التوجيه الجزء الذي سيخزن القطعة.

يمكن اختيار Shard Key من خلال النظر في خمس خصائص:

  • عدد العناصر في المجموعة
  • اكتب التوزيع
  • اقرأ التوزيع
  • اقرأ الاستهداف
  • اقرأ المنطقة

مفتاح جزء مثالي يجعل MongoDB لتوزيع الحمل بالتساوي بين جميع الأجزاء. يعد اختيار مفتاح جزء جيد أمرًا في غاية الأهمية.

الصورة: MongoDB

إزالة عقدة الجزء

قبل إزالة الأجزاء من المجموعة ، يتعين على المستخدم ضمان الترحيل الآمن للبيانات إلى الأجزاء المتبقية. يعتني MongoDB بتصريف البيانات بأمان إلى عُقد القطع الأخرى قبل إزالة عقدة الأجزاء المطلوبة.

قم بتشغيل الأمر أدناه لإزالة الجزء المطلوب.

الخطوة 1

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

db.adminCommand ({listShards: 1})

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs1",
                        "host" : "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022",
                        "state" : 1
                },
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572866, 15),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572866, 15),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

الخطوة 2

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

db.adminCommand ({removeShard: “shardedReplicaNodes”})

mongos> db.adminCommand( { removeShard: "rs1/127.0.0.1:27020,127.0.0.1:27021,127.0.0.1:27022" } )
{
        "msg" : "draining started successfully",
        "state" : "started",
        "shard" : "rs1",
        "note" : "you need to drop or movePrimary these databases",
        "dbsToMove" : [ ],
        "ok" : 1,
        "operationTime" : Timestamp(1593572385, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593572385, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

الخطوه 3

للتحقق من حالة جزء التصريف ، قم بإصدار نفس الأمر مرة أخرى.

db.adminCommand ({removeShard: “rs1 / 127.0.0.1: 27020،127.0.0.1: 27021،127.0.0.1: 27022”})

نحن بحاجة إلى الانتظار حتى اكتمال استنزاف البيانات. سيظهر حقلا msg و state إذا اكتمل استنزاف البيانات أم لا ، على النحو التالي

"msg" : "draining ongoing",
"state" : "ongoing",

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

الخطوة 4

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

"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "rs1",
"ok" : 1,

الخطوة الخامسة

أخيرًا ، نحتاج إلى التحقق من الأجزاء المتبقية في المجموعة. للتحقق من الحالة ، أدخل sh.status () أو db.adminCommand ({listShards: 1})

mongos> db.adminCommand( { listShards: 1 } )
{
        "shards" : [
                {
                        "_id" : "rs2",
                        "host" : "rs2/127.0.0.1:27023,127.0.0.1:27024,127.0.0.1:27025",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1593575215, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1593575215, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

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

فوائد التقاسم عبر النسخ المتماثل

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

حدود التكسير

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

استنتاج

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