مقدّمة عن Cloud Bigtable

1. مقدمة

في هذا الدرس التطبيقي، ستتعرف على كيفية استخدام Cloud Bigtable مع برنامج Java HBase.

ستتعرَّف على كيفية

  • تجنُّب الأخطاء الشائعة باستخدام تصميم المخطط
  • استيراد البيانات في ملف تسلسل
  • الاستعلام عن بياناتك

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

7349d94f7d41f1d1.png

ما هو تقييمك لتجربتك في استخدام Google Cloud Platform؟

حديث متوسط بارع

كيف ستستخدم هذا البرنامج التعليمي؟

القراءة فقط اقرأها وأكمِل التمارين

2. لمحة عن مجموعة البيانات

ستتعرف على مجموعة بيانات حول حافلات مدينة نيويورك. هناك أكثر من 300 مسار للحافلات و5800 مركبة تتبع هذه المسارات. مجموعة البيانات هي سجلّ يتضمّن اسم الوجهة ومعرّف المركبة وخط العرض وخط الطول ووقت الوصول المتوقّع ووقت الوصول المجدول. تتكون مجموعة البيانات من لقطات مأخوذة كل 10 دقائق تقريبًا لشهر يونيو 2017.

3- تصميم المخطط

للحصول على أفضل أداء من Cloud Bigtable، عليك التفكير جيدًا عند تصميم مخطّطك. يتم فرز البيانات في Cloud Bigtable تلقائيًا بطريقة معقّدة، لذلك إذا صممت المخطط جيدًا، سيكون الاستعلام عن البيانات ذات الصلة أمرًا فعالاً للغاية. تسمح Cloud Bigtable بطلبات البحث التي تستخدم عمليات البحث عن النقاط حسب مفتاح الصف أو عمليات فحص نطاق الصفوف التي تعرض مجموعة متجاورة من الصفوف. ومع ذلك، إذا لم يكن المخطط لديك مدروسًا جيدًا، فقد تجد نفسك تُجري عمليات بحث عدة صفوف معًا، أو ما هو أسوأ من ذلك، عند إجراء عمليات فحص للجدول بالكامل، وهي عمليات بطيئة للغاية.

التخطيط لطلبات البحث

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

باستخدام هذه المعلومات، يمكنك إجراء طلبات البحث التالية:

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

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

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

  • يمكنك الحصول على المواقع الجغرافية لمركبة معيّنة خلال ساعة واحدة.
  • احصل على المواقع الجغرافية لخط حافلات كامل خلال ساعة.
  • احصل على مواقع جميع الحافلات في مانهاتن في غضون ساعة.
  • احصل على أحدث المواقع لجميع الحافلات في مانهاتن في غضون ساعة.
  • معرفة المواقع الجغرافية لخط حافلات كامل على مدار الشهر
  • يمكنك تحديد المواقع الجغرافية لخط حافلات بأكمله في وجهة معيّنة خلال ساعة.

تصميم مفتاح الصف

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

وفي ما يلي المخطط المقترح لمفتاح الصف:

[شركة الحافلات/خط الحافلة/الطابع الزمني، مقرَّب إلى الساعة/رقم تعريف المركبة]. يحتوي كل صف على ساعة من البيانات، وتحتوي كل خلية على إصدارات متعددة ذات طابع زمني من البيانات.

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

مفتاح الصف

cf:VehicleLocation.Latitude

cf:VehicleLocation.Longitude

...

MTA/M86-SBS/1496275200000/NYCT_5824

40.781212 @20:52:54.0040.776163 @20:43:19.0040.778714 @20:33:46.00

-73.961942 @20:52:54.00-73.946949 @20:43:19.00-73.953731 @20:33:46.00

...

MTA/M86-SBS/1496275200000/NYCT_5840

40.780664 @20:13:51.0040.788416 @20:03:40.00

-73.958357 @20:13:51.00 -73.976748 @20:03:40.00

...

MTA/M86-SBS/1496275200000/NYCT_5867

40.780281 @20:51:45.0040.779961 @20:43:15.0040.788416 @20:33:44.00

-73.946890 @20:51:45.00-73.959465 @20:43:15.00-73.976748 @20:33:44.00

...

...

...

...

...

4. إنشاء مثيل وجدول وعائلة

بعد ذلك، ستقوم بإنشاء جدول Cloud Bigtable.

أولاً، قم بإنشاء مشروع جديد. استخدام Cloud Shell المدمَج، الذي يمكنك فتحه بالنقر على "تفعيل Cloud Shell" في أعلى الجانب الأيسر.

a74d156ca7862b28.png

اضبط متغيّرات البيئة التالية لتسهيل نسخ أوامر الدرس التطبيقي حول الترميز ولصقها:

INSTANCE_ID="bus-instance"
CLUSTER_ID="bus-cluster"
TABLE_ID="bus-data"
CLUSTER_NUM_NODES=3
CLUSTER_ZONE="us-central1-c"

يتضمّن Cloud Shell الأدوات التي يمكنك استخدامها في هذا الدرس التطبيقي حول الترميز، وأداة سطر أوامر gcloud وواجهة سطر الأوامر cbt وMaven، والتي سبق تثبيتها.

فعِّل واجهات برمجة تطبيقات Cloud Bigtable من خلال تشغيل هذا الأمر.

gcloud services enable bigtable.googleapis.com bigtableadmin.googleapis.com

أنشئ مثيلاً باستخدام الأمر التالي:

gcloud bigtable instances create $INSTANCE_ID \
    --cluster=$CLUSTER_ID \
    --cluster-zone=$CLUSTER_ZONE \
    --cluster-num-nodes=$CLUSTER_NUM_NODES \
    --display-name=$INSTANCE_ID

بعد إنشاء المثيل، املأ ملف إعداد cbt ثم أنشئ مجموعة جدول وعمود عن طريق تشغيل الأوامر التالية:

echo project = $GOOGLE_CLOUD_PROJECT > ~/.cbtrc
echo instance = $INSTANCE_ID >> ~/.cbtrc

cbt createtable $TABLE_ID
cbt createfamily $TABLE_ID cf

5- استيراد البيانات

استيراد مجموعة من ملفات التسلسل لهذا الدرس التطبيقي حول الترميز من gs://cloud-bigtable-public-datasets/bus-data باتّباع الخطوات التالية:

فعِّل Cloud Dataflow API من خلال تنفيذ هذا الأمر.

gcloud services enable dataflow.googleapis.com

شغِّل الأوامر التالية لاستيراد الجدول.

NUM_WORKERS=$(expr 3 \* $CLUSTER_NUM_NODES)
gcloud beta dataflow jobs run import-bus-data-$(date +%s) \
--gcs-location gs://dataflow-templates/latest/GCS_SequenceFile_to_Cloud_Bigtable \
--num-workers=$NUM_WORKERS --max-workers=$NUM_WORKERS \
--parameters bigtableProject=$GOOGLE_CLOUD_PROJECT,bigtableInstanceId=$INSTANCE_ID,bigtableTableId=$TABLE_ID,sourcePattern=gs://cloud-bigtable-public-datasets/bus-data/*

مراقبة الاستيراد

يمكنك مراقبة المهمة في واجهة مستخدم Cloud Dataflow. يمكنك أيضًا عرض التحميل على مثيل Cloud Bigtable باستخدام واجهة مستخدم المراقبة الخاصة به. من المفترض أن تستغرق عملية الاستيراد بأكملها 5 دقائق.

6- الحصول على الرمز‏

git clone https://github.com/googlecodelabs/cbt-intro-java.git
cd cbt-intro-java

يمكنك التغيير إلى Java 11 عن طريق تشغيل الأوامر التالية:

sudo update-java-alternatives -s java-1.11.0-openjdk-amd64 && export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/

7. إجراء عملية بحث

الاستعلام الأول الذي ستقوم بإجرائه هو بحث بسيط عن صف. ستتلقّى بيانات الحافلة على خط M86-SBS في 1 حزيران (يونيو) 2017 من الساعة 12:00 صباحًا إلى الساعة 1:00 صباحًا. ثم ركبت مركبة برقم التعريف NYCT_5824 على خط الحافلة.

باستخدام هذه المعلومات، ومعرفة تصميم المخطط (شركة الحافلات/خط الحافلة/الطابع الزمني، مقرَّب إلى الساعة/رقم تعريف المركبة)، يمكنك استنتاج أن مفتاح الصف هو:

MTA/M86-SBS/1496275200000/NYCT_5824

BusQueries.java

private static final byte[] COLUMN_FAMILY_NAME = Bytes.toBytes("cf");
private static final byte[] LAT_COLUMN_NAME = Bytes.toBytes("VehicleLocation.Latitude");
private static final byte[] LONG_COLUMN_NAME = Bytes.toBytes("VehicleLocation.Longitude");

String rowKey = "MTA/M86-SBS/1496275200000/NYCT_5824";
Result getResult =
    table.get(
        new Get(Bytes.toBytes(rowKey))
            .addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
            .addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME));

ينبغي أن تتضمن النتيجة أحدث موقع للحافلة خلال تلك الساعة. لكنك تريد الاطّلاع على جميع المواقع الجغرافية، لذا عيِّن الحد الأقصى لعدد النُسخ في طلب الحصول على.

BusQueries.java

Result getResult =
    table.get(
        new Get(Bytes.toBytes(rowKey))
            .setMaxVersions(Integer.MAX_VALUE)
            .addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
            .addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME));

في Cloud Shell، شغِّل الأمر التالي للحصول على قائمة بخطوط الطول والعرض لهذه الحافلة على مدار الساعة:

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=lookupVehicleInGivenHour

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

f1a1fac6051c6210.png

8. إجراء فحص

والآن، لنعرض كل بيانات خط الحافلات لتلك الساعة. يبدو رمز المسح الضوئي مشابهًا إلى حد كبير لرمز الحصول على الرمز. يمكنك تحديد موضع بداية للماسح الضوئي ثم الإشارة إلى أنّك تريد فقط الحصول على صفوف لخط الحافلات M86-SBS خلال الساعة التي يُشار إليها بالطابع الزمني 1496275200000.

BusQueries.java

Scan scan;
scan = new Scan();
scan.setMaxVersions(Integer.MAX_VALUE)
    .addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
    .addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME)
    .withStartRow(Bytes.toBytes("MTA/M86-SBS/1496275200000"))
    .setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/1496275200000"));
ResultScanner scanner = table.getScanner(scan);

قم بتشغيل الأمر التالي للحصول على النتائج.

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=scanBusLineInGivenHour

c18a4ac6522d08a2.png

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

234c1b51e3b201e.png

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

BusQueries.java

scan.withStartRow(Bytes.toBytes("MTA/M86-SBS/"))
    .setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/"));

// Optionally, reduce the results to receive one version per column
// since there are so many data points.
scan.setMaxVersions(1);

قم بتشغيل الأمر التالي للحصول على النتائج. (ستكون هناك قائمة طويلة من النتائج.)

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=scanEntireBusLine

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

346f52e61b3d8902.png

9. فلاتر المقدمة

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

BusQueries.java

Scan scan;
ResultScanner scanner;
scan = new Scan();
SingleColumnValueFilter valueFilter =
    new SingleColumnValueFilter(
        COLUMN_FAMILY_NAME,
        Bytes.toBytes("DestinationName"),
        CompareOp.EQUAL,
        Bytes.toBytes("Select Bus Service Yorkville East End AV"));

scan.setMaxVersions(1)
    .addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
    .addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME);
scan.withStartRow(Bytes.toBytes("MTA/M86-SBS/"))
    .setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/"));
scan.setFilter(valueFilter);
scanner = table.getScanner(scan);

قم بتشغيل الأمر التالي للحصول على نتائج الحافلات المتجهة نحو الشرق.

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=filterBusesGoingEast

لتوجيه الحافلات إلى الغرب، قم بتغيير السلسلة في valueFilter:

BusQueries.java

SingleColumnValueFilter valueFilter =
    new SingleColumnValueFilter(
        COLUMN_FAMILY_NAME,
        Bytes.toBytes("DestinationName"),
        CompareOp.EQUAL,
        Bytes.toBytes("Select Bus Service Westside West End AV"));

قم بتشغيل الأمر التالي للحصول على نتائج الحافلات المتجهة للغرب.

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=filterBusesGoingWest

حافلات تتجه شرقًا

76f6f62096a6847a.png

حافلات تتجه غربًا

2b5771ee9046399f.png

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

10. إجراء فحص متعدد النطاقات

بالنسبة للاستعلام الأخير، ستتناول الحالة عندما تهتم بالعديد من خطوط الحافلات في منطقة ما:

BusQueries.java

private static final String[] MANHATTAN_BUS_LINES = {"M1","M2","M3",...

Scan scan;
ResultScanner scanner;
List<RowRange> ranges = new ArrayList<>();
for (String busLine : MANHATTAN_BUS_LINES) {
  ranges.add(
      new RowRange(
          Bytes.toBytes("MTA/" + busLine + "/1496275200000"), true,
          Bytes.toBytes("MTA/" + busLine + "/1496275200001"), false));
}
Filter filter = new MultiRowRangeFilter(ranges);
scan = new Scan();
scan.setFilter(filter);
scan.setMaxVersions(Integer.MAX_VALUE)
    .addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
    .addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME);
scan.withStartRow(Bytes.toBytes("MTA/M")).setRowPrefixFilter(Bytes.toBytes("MTA/M"));
scanner = table.getScanner(scan);

قم بتشغيل الأمر التالي للحصول على النتائج.

mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \
-Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \
-Dquery=scanManhattanBusesInGivenHour

7349d94f7d41f1d1.png

11. إنهاء

إخلاء مساحة تخزين لتجنُّب تحصيل رسوم

لتجنُّب تحمُّل أي رسوم من حسابك على Google Cloud Platform مقابل الموارد المستخدَمة في هذا الدرس التطبيقي حول الترميز، عليك حذف المثيل.

gcloud bigtable instances delete $INSTANCE_ID

النقاط التي تناولناها

  • تصميم المخطط
  • إعداد مثيل وجدول وعائلة
  • استيراد ملفات التسلسل باستخدام dataflow
  • إجراء طلبات البحث عن طريق إجراء بحث وفحص وفحص باستخدام فلتر وفحص متعدد النطاقات

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