ترحيل مباشر إلى Azure Managed Instance لـ Apache Cassandra باستخدام وكيل الكتابة المزدوجة

حيثما أمكن، نوصي باستخدام الإمكانية الأصلية لـ Apache Cassandra لترحيل البيانات من المجموعة الحالية إلى Azure Managed Instance لـ Apache Cassandra عن طريق تكوين مجموعة مختلطة. تستخدم هذه الإمكانية بروتوكول التناقل الخاص بـ Apache Cassandra لنسخ البيانات من مركز بيانات المصدر الخاص بك إلى مركز بيانات المثيل الجديد المُدار بطريقة سلسلة. ومع ذلك، قد تكون هناك بعض السيناريوهات حيث لا يكون إصدار قاعدة البيانات المصدر متوافقًا، أو يكون إعداد المجموعة المختلط غير ممكن.

يصف هذا البرنامج التعليمي كيفية ترحيل البيانات إلى Azure Managed Instance لـ Apache Cassandra بطريقة مباشرة باستخدام وكيل الكتابة المزدوجة وApache Spark. يتم استخدام وكيل dual-write لالتقاط التغييرات الحية، بينما يتم نسخ البيانات التاريخية بكميات كبيرة باستخدام Apache Spark. وتتمثل فوائد هذا النهج في:

  • الحد الأدنى من تغييرات التطبيق. يمكن أن يقبل الوكيل الاتصالات من التعليمات البرمجية للتطبيق الخاص بك مع تغييرات تكوين قليلة أو معدومة. سيتم توجيه كافة الطلبات إلى قاعدة البيانات المصدر الخاص بك ومسار غير متزامن يكتب إلى هدف ثانوي.
  • تبعية بروتوكول تحويل العميل. لأن هذا النهج لا يعتمد على الموارد الخلفية أو البروتوكولات الداخلية، يمكن استخدامه مع أي مصدر أو نظام Cassandra الهدف الذي ينفذ بروتوكول تحويل Apache Cassandra.

الصورة التالية توضح النهج.

الرسوم المتحركة التي تظهر الترحيل المباشر للبيانات إلى Azure Managed Instance لـ Apache Cassandra.

المتطلبات الأساسية

تكوين إعدادات تشغيل الخدمة بنظام مجموعة Spark

نوصي بتحديد وقت تشغيل Azure Databricks الإصدار 7.5، والذي يدعم Spark 3.0.

لقطة شاشة توضح العثور على نسخة وقت تشغيل Azure Databricks.

إضافة تبعيات Spark

تحتاج إلى إضافة مكتبة Apache Spark Cassandra Connector إلى مجموعتك للاتصال بأي نقاط نهاية Apache Cassandra متوافقة مع البروتوكول السلكي. في نظام المجموعة، حدد Libraries>Install New>Maven ثم أضف com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0 إحداثيات Maven.

هام

إذا كان لديك متطلب للاحتفاظ بـ Apache Cassandra writetime لكل صف أثناء الترحيل، فإننا نوصي باستخدام هذه العينة. يحتوي ملف jar الخاص بالتبعية في هذا النموذج أيضاً على موصل Spark، لذا يجب عليك تثبيته بدلاً من مجموعة الموصل أعلاه. هذه العينة مفيدة أيضاً إذا كنت تريد إجراء تحقق من مقارنة الصفوف بين المصدر والهدف بعد اكتمال تحميل البيانات التاريخية. راجع القسمين "تشغيل تحميل البيانات التاريخية" و"التحقق من صحة المصدر والهدف" أدناه لمزيد من التفاصيل.

توضح لقطة شاشة البحث عن حزم Maven في Azure Databricks.

حدد Install، ثم أعد تشغيل نظام المجموعة عند اكتمال التثبيت.

ملاحظة

تأكد من إعادة تشغيل نظام مجموعة Azure Databricks بعد تثبيت مكتبة موصل Cassandra.

تثبيت وكيل الكتابة المزدوجة

للحصول على الأداء الأمثل في أثناء الكتابة المزدوجة، نوصي بتثبيت الوكيل على كافة العقد في نظام مجموعة Cassandra المصدر.

#assuming you do not have git already installed
sudo apt-get install git 

#assuming you do not have maven already installed
sudo apt install maven

#clone repo for dual-write proxy
git clone https://github.com/Azure-Samples/cassandra-proxy.git

#change directory
cd cassandra-proxy

#compile the proxy
mvn package

بدء تشغيل وكيل الكتابة المزدوجة

نوصي بتثبيت الوكيل على كافة العقد في نظام مجموعة Cassandra المصدر لديك. على الأقل، قم بتشغيل الأمر التالي لبدء تشغيل الوكيل على كل عقدة. استبدل <target-server> بعنوان IP أو عنوان خادم من إحدى العقد في نظام المجموعة الهدف. استبدل <path to JKS file> بمسار إلى ملف .jks المحلي واستبدل <keystore password> بكلمة المرور المطابقة.

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password>

يفترض من خلال بدء تشغيل الوكيل بهذه الطريقة بأن ما يلي صحيح:

  • تحتوي نقاط النهاية المصدر والهدف على نفس اسم المستخدم وكلمة المرور.
  • تنفذ نقاط النهاية المصدر والهدف طبقة مآخذ التوصيل الآمنة (SSL).

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

تكوين طبقة مأخذ توصيل آمنة

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

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

يمكنك أيضًا تعطيل طبقة مأخذ التوصيل الآمنة لنقاط النهاية المصدر أو الهدف إذا لم يتم تطبيق طبقة مأخذ التوصيل الآمنة. استخدم العلامات --disable-source-tls أو --disable-target-tls:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password> --disable-source-tls true  --disable-target-tls true 

ملاحظة

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

تكوين بيانات الاعتماد والمنفذ

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

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

سيكون المصدر الافتراضي والمنافذ الهدف، عند عدم تحديد، 9042. إذا كان الهدف أو نقطة النهاية Cassandra المصدر يعمل على منفذ مختلف، يمكنك استخدام --source-port أو --target-port لتحديد رقم منفذ مختلف:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

نشر الوكيل عن بُعد

قد تكون هناك ظروف لا تريد فيها تثبيت الوكيل على عقد نظام المجموعة نفسها، وتفضل تثبيته على جهاز منفصل. في هذا السيناريو، تحتاج إلى تحديد عنوان IP الخاص بـ <source-server>:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar <source-server> <destination-server>

تحذير

إذا كنت تفضل تشغيل الوكيل عن بعد على جهاز منفصل (بدلا من تشغيله على جميع العقد في مجموعة Apache Cassandra المصدر)، نوصي بتوزيع الوكيل على نفس عدد الأجهزة التي لديك عقد في نظام المجموعة الخاص بك، وإعداد استبدال لعناوين IP الخاصة بهم في system.peers باستخدام التكوين في الوكيل المذكور هنا. إذا لم تقم بذلك، فقد يؤثر ذلك على الأداء أثناء حدوث الترحيل المباشر، حيث لن يتمكن برنامج تشغيل العميل من فتح الاتصالات بجميع العقد داخل نظام المجموعة.

السماح بتغييرات رمز التطبيق صفر

بشكل افتراضي، يستمع الوكيل على المنفذ 29042. يجب تغيير رمز التطبيق للإشارة إلى هذا المنفذ. ومع ذلك، يمكنك تغيير المنفذ الذي يستمع الوكيل عليه. قد تفعل ذلك إذا كنت ترغب في إزالة تغييرات الرموز على مستوى التطبيق بواسطة:

  • وجود خادم Cassandra المصدر مشغل على منفذ مختلف.
  • وجود وكيل مشغل على منفذ Cassandra القياسي 9042.
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042

ملاحظة

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

في المثال التالي، نقوم بتغيير نظام المجموعة Cassandra المصدر للتشغيل على المنفذ 3074 ثم نبدأ نظام المجموعة على المنفذ 9042:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074

فرض البروتوكولات

لدى الوكيل وظائف لفرض البروتوكولات، والتي قد تكون ضرورية إذا كانت نقطة النهاية المصدر أكثر تقدمًا من الهدف أو غير معتمدة. في هذه الحالة، يمكنك تحديد --protocol-version و--cql-version لفرض البروتوكول للامتثال للهدف:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11

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

تشغيل تحميل البيانات التاريخية

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

import com.datastax.spark.connector._
import com.datastax.spark.connector.cql._
import org.apache.spark.SparkContext

// source cassandra configs
val sourceCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>"
)

//target cassandra configs
val targetCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>",
    //throughput related settings below - tweak these depending on data volumes. 
    "spark.cassandra.output.batch.size.rows"-> "1",
    "spark.cassandra.output.concurrent.writes" -> "1000",
    "spark.cassandra.connection.remoteConnectionsPerExecutor" -> "1",
    "spark.cassandra.concurrent.reads" -> "512",
    "spark.cassandra.output.batch.grouping.buffer.size" -> "1000",
    "spark.cassandra.connection.keep_alive_ms" -> "600000000"
)

//set timestamp to ensure it is before read job starts
val timestamp: Long = System.currentTimeMillis / 1000

//Read from source Cassandra
val DFfromSourceCassandra = sqlContext
  .read
  .format("org.apache.spark.sql.cassandra")
  .options(sourceCassandra)
  .load
  
//Write to target Cassandra
DFfromSourceCassandra
  .write
  .format("org.apache.spark.sql.cassandra")
  .options(targetCassandra)
  .option("writetime", timestamp)
  .mode(SaveMode.Append)
  .save

ملاحظة

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

هام

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

تحقق من المصدر والهدف

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

ملاحظة

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

الخطوات التالية