لدينا تجربة الهجرة كاساندرا بين مجموعات Kubernetes دون فقدان البيانات



على مدار الستة أشهر الماضية ، استخدمنا عامل التشغيل Rook للعمل مع Cassandra في Kubernetes . ومع ذلك ، عندما احتجنا إلى إجراء عملية تافهة للغاية ، فقد يبدو الأمر ، العملية: تغيير المعلمات في تكوين Cassandra ، اتضح أن عامل التشغيل لم يوفر مرونة كافية. لإجراء تغييرات ، كان من الضروري استنساخ المستودع ، وإجراء تغييرات على المصادر وإعادة بناء عامل التشغيل (تم تكوين التكوين في عامل التشغيل نفسه ، لذلك لا تزال معرفة Go مفيدة). كل هذا يستغرق الكثير من الوقت.

لقد قمنا بالفعل بمراجعة المشغلين الحاليين ، وهذه المرة توقفنا في CassKop من Orange ، والتي تدعم الميزات الضرورية ، على وجه الخصوص ، التكوينات المخصصة والمراقبة خارج الصندوق.

مهمة


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

متطلبات الهجرة:

  • الحد الأقصى لوقت الخمول هو 2-3 دقائق لتنفيذ هذا النقل بالفعل في نفس الوقت الذي يتم فيه نقل التطبيق نفسه إلى مجموعة جديدة ؛
  • قم بنقل جميع البيانات دون فقد أو صداع (أي دون أي معالجات إضافية).

كيفية تنفيذ مثل هذه العملية؟ قياسا على RabbitMQ و MongoDB ، قررنا إطلاق تثبيت كاساندرا جديد في كتلة Kubernetes جديدة، ثم دمج كاساندرا اثنين في مجموعات مختلفة ونقل البيانات، وإنهاء العملية برمتها ببساطة عن طريق تعطيل التثبيت الأصلي.

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

في الجزء العملي التالي من المقالة ، سيتم استخدام ثلاثة رموز لمجموعات كاساندرا:

  • Cassandra-new - التثبيت الجديد الذي سنطلقه في مجموعة Kubernetes الجديدة ؛
  • Cassandra-current - تثبيت قديم تعمل معه التطبيقات حاليًا ؛
  • كاساندرا - مؤقت هو تثبيت مؤقت نقوم بتشغيله بجوار كاساندرا - تيار واستخدامه فقط لعملية الترحيل نفسها.

كيف تكون؟


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

يتم تقليل التسلسل العام للإجراءات إلى الخطوات التالية:

  1. رفع كاساندرا الجديدة بعامل جديد في عنقود جديد.
  2. مقياس ل 0 الكتلة كاساندرا الجديدة .
  3. , PVC, .
  4. Cassandra-temporary Cassandra-current , Cassandra-new.
  5. Cassandra-temporary 0 ( ) Cassandra-temporary , Cassandra-temporary Cassandra-current. Cassandra - ( Cassandra ).
  6. نقل البيانات بين كاساندرا-مؤقتة و كاساندرا الحالية مراكز البيانات .
  7. قم بقياس مجموعات Cassandra-current و Cassandra-المؤقتة إلى 0 وقم بتشغيل Cassandra-new في المجموعة الجديدة ، مع عدم نسيان رمي الأقراص. بالتوازي ، نطرح التطبيقات إلى مجموعة جديدة.

نتيجة لهذه التلاعبات ، سيكون وقت التوقف عن العمل ضئيلاً.

بالتفصيل


يجب ألا تكون هناك أي مشاكل في الخطوات الثلاث الأولى - يتم كل شيء بسرعة وسهولة.

عند هذه النقطة ، ستبدو كتلة كاساندرا الحالية كما يلي:

Datacenter: x1
==============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns    Host ID                               Rack
UN  10.244.6.5  790.7 GiB  256          ?       13cd0c7a-4f91-40d0-ac0e-e7c4a9ad584c  rack1
UN  10.244.7.5  770.9 GiB  256          ?       8527813a-e8df-4260-b89d-ceb317ef56ef  rack1
UN  10.244.5.5  825.07 GiB  256          ?       400172bf-6f7c-4709-81c6-980cb7c6db5c  rack1

للتحقق من أن كل شيء يعمل كما هو متوقع ، أنشئ مساحة مفتاح في Cassandra-current . يتم ذلك قبل إطلاق كاساندرا المؤقتة :

create keyspace example with replication ={'class' : 'NetworkTopologyStrategy', 'x1':2};

بعد ذلك ، قم بإنشاء جدول واملأه بالبيانات:

use example;
CREATE TABLE example(id int PRIMARY KEY, name text, phone varint);
INSERT INTO example(id, name, phone) VALUES(1,'Masha', 983123123);
INSERT INTO example(id, name, phone) VALUES(2,'Sergey', 912121231);
INSERT INTO example(id, name, phone) VALUES(3,'Andrey', 914151617);

تشغيل كاساندرا-مؤقتة ، وتذكر أنه قبل ذلك، في كتلة جديدة، أطلقنا بالفعل كاساندرا جديدة (الخطوة رقم 1)، والآن تم إيقاف تشغيله (خطوة رقم 2).

ملاحظات:

  1. عندما نبدأ Cassandra - مؤقتًا ، يجب أن نحدد نفس اسم الكتلة (مع Cassandra-current ). يمكن القيام بذلك من خلال متغير CASSANDRA_CLUSTER_NAME.
  2. لكي تتمكن كاساندرا المؤقتة من رؤية المجموعة الحالية ، تحتاج إلى ضبط البذور. يتم ذلك من خلال متغير CASSANDRA_SEEDSأو من خلال التكوين.

انتباه! قبل أن تبدأ في نقل البيانات ، يجب التأكد من تعيين أنواع تناسق القراءة والكتابة على LOCAL_ONEأو LOCAL_QUORUM.

بعد بدء كاساندرا المؤقت ، يجب أن تبدو المجموعة على هذا النحو (لاحظ ظهور مركز بيانات ثانٍ يحتوي على 3 عقد):

Datacenter: x1
==============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns    Host ID                               Rack
UN  10.244.6.5  790.7 GiB  256          ?       13cd0c7a-4f91-40d0-ac0e-e7c4a9ad584c  rack1
UN  10.244.7.5  770.9 GiB  256          ?       8527813a-e8df-4260-b89d-ceb317ef56ef  rack1
UN  10.244.5.5  825.07 GiB  256          ?       400172bf-6f7c-4709-81c6-980cb7c6db5c  rack1

Datacenter: x2
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address       Load       Tokens       Owns (effective)  Host ID                               Rack
UN  10.244.16.96  267.07 KiB  256          64.4%             3619841e-64a0-417d-a497-541ec602a996  rack1
UN  10.244.18.67  248.29 KiB  256          65.8%             07a2f571-400c-4728-b6f7-c95c26fe5b11  rack1
UN  10.244.16.95  265.85 KiB  256          69.8%             2f4738a2-68d6-4f9e-bf8f-2e1cfc07f791  rack1

الآن يمكنك إجراء النقل. للقيام بذلك ، قم أولاً بنقل مسافة مفتاح الاختبار - تأكد من أن كل شيء على ما يرام:

ALTER KEYSPACE example WITH replication = {'class': 'NetworkTopologyStrategy', x1: 2, x2: 2};


بعد ذلك ، في كل جراب كاساندرا المؤقت ، نفّذ الأمر:

nodetool rebuild -ks example x1

دعنا نذهب إلى أي جراب من كاساندرا - مؤقت ونتحقق من نقل البيانات. يمكنك أيضًا إضافة إدخال واحد آخر إلى Cassandra-current للتحقق من أن البيانات الجديدة قد بدأت في التكرار:

SELECT * FROM example;

 id | name   | phone
----+--------+-----------
  1 |  Masha | 983123123
  2 | Sergey | 912121231
  3 | Andrey | 914151617

(3 rows)

بعد ذلك ، يمكنك القيام ALTERبكل مساحات المفاتيح في Cassandra-current والتنفيذ nodetool rebuild.

عدم وجود مساحة وذاكرة


في هذه المرحلة ، من المفيد أن نتذكر أنه عند تشغيل إعادة الإنشاء ، يتم إنشاء ملفات مؤقتة تعادل في حجمها حجم مساحة المفاتيح! واجهنا مشكلة في أن أكبر مساحة للمفاتيح كانت 350 غيغابايت ، وكانت هناك مساحة قرص حرة أقل.

تعذر توسيع القرص لأنه يتم استخدام التخزين المحلي. جاء الأمر التالي إلى الإنقاذ (تم تنفيذه في كل جراب من كاساندرا الحالية ):

nodetool clearsnapshot

لذلك تم تحرير المكان: في حالتنا ، تم الحصول على 500 جيجابايت من مساحة القرص الخالية بدلاً من 200 جيجابايت المتاحة سابقًا.

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

failed; error='Cannot allocate memory' (errno=12)

لقد قررنا ذلك من خلال إنشاء DaemonSet ، والذي يتم طرحه فقط على العقد ذات Cassandra-المؤقتة ويؤدي:

sysctl -w vm.max_map_count=262144

أخيرًا ، تم ترحيل جميع البيانات!

تبديل الكتلة


بقي فقط تبديل كاساندرا ، التي تم تنفيذها في 5 مراحل:

  1. مقياس كاساندرا-مؤقت و كاساندرا الجاري (لا ننسى أن المشغل لا يزال يعمل هنا!) الى 0.
  2. تبديل الأقراص (يتعلق الأمر بتعيين PV لـ Cassandra-new ).
  3. نبدأ Cassandra-new ، تتبع أن الأقراص الضرورية متصلة.
  4. نقوم ALTERبكافة الجداول لإزالة المجموعة القديمة:

    ALTER KEYSPACE example WITH replication = {'class': 'NetworkTopologyStrategy', 'x2': 2};
  5. حذف كافة عقد الكتلة القديمة. للقيام بذلك ، فقط قم بتشغيل هذا الأمر في أحد جرابها:

    nodetool removenode 3619841e-64a0-417d-a497-541ec602a996

كان إجمالي وقت التوقف عن Cassandra حوالي 3 دقائق - هذا هو الوقت الذي توقفت فيه الحاويات وبدأت ، حيث تم إعداد الأقراص مسبقًا.

اللمسة النهائية مع بروميثيوس


ومع ذلك ، لم ينتهي هذا عند هذا الحد. هناك مصدر مدمج مع Cassandra-new (راجع وثائق المشغل الجديد ) - بالطبع ، استخدمناه. بعد حوالي ساعة واحدة من الإطلاق ، بدأت تنبيهات حول عدم إمكانية الوصول إلى بروميثيوس. بعد التحقق من الحمل ، رأينا أن استهلاك الذاكرة في العقد مع Prometheus قد ازداد.

أظهرت دراسة أخرى للمسألة أن عدد المقاييس المجمعة زاد 2.5 مرة (!). كان الخطأ كاساندرا ، حيث تم جمع ما يزيد قليلاً عن 500 ألف مقياس.

لقد قمنا بتدقيق المقاييس وقمنا بتعطيل المقاييس التي لم نعتبرها ضرورية - من خلال ConfigMap (بالمناسبة ، تم تكوين المصدر). والنتيجة هي 120 ألف مقياس وحمل مخفض بشكل كبير على بروميثيوس (على الرغم من بقاء المقاييس المهمة).

استنتاج


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

أخيرًا: لماذا لم نستخدم الأداة nodetool snapshotالمذكورة في المقالة السابقة؟ والحقيقة هي أن هذا الأمر ينشئ لقطة لمساحة المفاتيح في الحالة التي كان عليها قبل تشغيل الأمر. إلى جانب:

  • يستغرق الأمر وقتًا أطول لالتقاط صورة ونقلها ؛
  • سيتم فقدان كل ما هو مكتوب في كاساندرا في هذا الوقت ؛
  • بسيطة في حالتنا ستكون حوالي ساعة - بدلاً من 3 دقائق ، والتي اتضح أنها تم دمجها بنجاح مع نشر التطبيق في مجموعة جديدة.

ملاحظة


اقرأ أيضا في مدونتنا:


All Articles