Bigtable وDataflow: Database Monitoring Art (برنامج HBase Java Client)

1. مقدمة

في هذا الدرس التطبيقي حول الترميز، ستستخدم أدوات المراقبة في Cloud Bigtable لإنشاء أعمال فنية متنوعة من خلال كتابة البيانات وقراءتها باستخدام Cloud Dataflow وعميل Java HBase.

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

  • تحميل كميات كبيرة من البيانات إلى Bigtable باستخدام Cloud Dataflow
  • مراقبة مثيلات وجداول Bigtable أثناء نقل البيانات
  • طلب بحث عن Bigtable باستخدام مهمة Dataflow
  • استكشف أداة العرض المرئي الرئيسية التي يمكن استخدامها للعثور على نقاط الاتصال بسبب تصميم المخطط
  • إنشاء أعمال فنية باستخدام أداة العرض الرئيسية للمرئيات

d098cc81f78f02eb.png

كيف تقيّم تجربتك في استخدام Cloud Bigtable؟

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

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

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

2. إنشاء قاعدة بيانات Bigtable

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

إنشاء مشروع

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

a74d156ca7862b28.png

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

BIGTABLE_PROJECT=$GOOGLE_CLOUD_PROJECT
INSTANCE_ID="keyviz-art-instance"
CLUSTER_ID="keyviz-art-cluster"
TABLE_ID="art"
CLUSTER_NUM_NODES=1
CLUSTER_ZONE="us-central1-c" # You can choose a zone closer to you

يتضمّن 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

3- التعلم: الكتابة في Bigtable باستخدام Dataflow

أساسيات الكتابة

عند الكتابة إلى Cloud Bigtable، عليك تقديم كائن إعداد CloudBigtableTableConfiguration. يحدد هذا الكائن رقم تعريف المشروع ورقم تعريف المثيل للجدول، بالإضافة إلى اسم الجدول نفسه:

CloudBigtableTableConfiguration bigtableTableConfig =
    new CloudBigtableTableConfiguration.Builder()
        .withProjectId(PROJECT_ID)
        .withInstanceId(INSTANCE_ID)
        .withTableId(TABLE_ID)
        .build();

بعد ذلك، يمكن لمسار الإحالة الناجحة تمرير كائنات HBase Mutation التي يمكن أن تشمل "وضع وحذف".

p.apply(Create.of("hello", "world"))
    .apply(
        ParDo.of(
            new DoFn<String, Mutation>() {
              @ProcessElement
              public void processElement(@Element String rowkey, OutputReceiver<Mutation> out) {
                long timestamp = System.currentTimeMillis();
                Put row = new Put(Bytes.toBytes(rowkey));

                row.addColumn(...);
                out.output(row);
              }
            }))
    .apply(CloudBigtableIO.writeToTable(bigtableTableConfig));

مهمة LoadData Dataflow

ستوضح لك الصفحة التالية كيفية تشغيل مهمة LoadData، ولكن سأذكر هنا الأجزاء المهمة في مسار التنفيذ.

لإنشاء بيانات، عليك إنشاء مسار يستخدم الفئة GenerateSequence (على نحو يشبه التكرار الحلقي for) لكتابة عدد من الصفوف يحتوي على بضع وحدات ميغابايت من البيانات العشوائية. سيكون مفتاح الصف هو رقم التسلسل المضغوط والمعكوس، لذا يصبح 250 0000000052.

LoadData.java

String numberFormat = "%0" + maxLength + "d";

p.apply(GenerateSequence.from(0).to(max))
    .apply(
        ParDo.of(
            new DoFn<Long, Mutation>() {
              @ProcessElement
              public void processElement(@Element Long rowkey, OutputReceiver<Mutation> out) {
                String paddedRowkey = String.format(numberFormat, rowkey);

                // Reverse the rowkey for more efficient writing
                String reversedRowkey = new StringBuilder(paddedRowkey).reverse().toString();
                Put row = new Put(Bytes.toBytes(reversedRowkey));

                // Generate random bytes
                byte[] b = new byte[(int) rowSize];
                new Random().nextBytes(b);

                long timestamp = System.currentTimeMillis();
                row.addColumn(Bytes.toBytes(COLUMN_FAMILY), Bytes.toBytes("C"), timestamp, b);
                out.output(row);
              }
            }))
    .apply(CloudBigtableIO.writeToTable(bigtableTableConfig));

4. إنشاء بيانات في Bigtable ومراقبة التدفق الداخلي

ستعمل الأوامر التالية على تشغيل مهمة تدفق البيانات التي تنشئ 40 غيغابايت من البيانات في جدولك، وهو ما يكفي لتنشيط أداة التمثيل المرئي للمفاتيح:

تفعيل Cloud Dataflow API

gcloud services enable dataflow.googleapis.com

احصل على الرمز من github وغيّره إلى الدليل

git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
cd java-docs-samples/bigtable/beam/keyviz-art

إنشاء البيانات (يستغرق النص البرمجي حوالي 15 دقيقة)

mvn compile exec:java -Dexec.mainClass=keyviz.LoadData \
"-Dexec.args=--bigtableProjectId=$BIGTABLE_PROJECT \
--bigtableInstanceId=$INSTANCE_ID --runner=dataflow \
--bigtableTableId=$TABLE_ID --project=$GOOGLE_CLOUD_PROJECT"

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

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

في واجهة مستخدم Dataflow، ستتمكن من رؤية الرسم البياني للوظائف ومقاييس الوظائف المختلفة، بما في ذلك العناصر التي تمت معالجتها ووحدات المعالجة المركزية الافتراضية الحالية ومعدلات البيانات.

9cecc290f5acea15.png

abb0561342dc6b60.png

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

996f8589332dfc19.png

5- التعلم: القراءة من Bigtable باستخدام Dataflow

أساسيات القراءة

عند القراءة من Cloud Bigtable، يجب توفير كائن إعداد CloudBigtableTableScanConfiguration. وهي تشبه CloudBigtableTableConfiguration، ولكن يمكنك تحديد الصفوف المطلوب مسحها ضوئيًا والقراءة منها.

Scan scan = new Scan();
scan.setCacheBlocks(false);
scan.setFilter(new FirstKeyOnlyFilter());

CloudBigtableScanConfiguration config =
    new CloudBigtableScanConfiguration.Builder()
        .withProjectId(options.getBigtableProjectId())
        .withInstanceId(options.getBigtableInstanceId())
        .withTableId(options.getBigtableTableId())
        .withScan(scan)
        .build();

ثم استخدم ذلك لبدء المسار:

p.apply(Read.from(CloudBigtableIO.read(config)))
    .apply(...

مع ذلك، إذا أردت إجراء قراءة كجزء من المسار، يمكنك تمرير CloudBigtableTableConfiguration إلى doFn يمتد إلى AbstractCloudBigtableTableDoFn.

p.apply(GenerateSequence.from(0).to(10))
    .apply(ParDo.of(new ReadFromTableFn(bigtableTableConfig, options)));

بعد ذلك، اتّصِل بـ super() مع ضبط الإعدادات وgetConnection() للحصول على اتصال موزّع.

public static class ReadFromTableFn extends AbstractCloudBigtableTableDoFn<Long, Void> {
    public ReadFromTableFn(CloudBigtableConfiguration config, ReadDataOptions readDataOptions) {
      super(config);
    }

    @ProcessElement
    public void processElement(PipelineOptions po) {
        Table table = getConnection().getTable(TableName.valueOf(options.getBigtableTableId()));
        ResultScanner imageData = table.getScanner(scan);
    }   
}

وظيفة ReadDataflow

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

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

ReadData.java

p.apply(GenerateSequence.from(0).withRate(1, new Duration(1000)))
    .apply(ParDo.of(new ReadFromTableFn(bigtableTableConfig, options)));

ReadData.java

  public static class ReadFromTableFn extends AbstractCloudBigtableTableDoFn<Long, Void> {

    List<List<Float>> imageData = new ArrayList<>();
    String[] keys;

    public ReadFromTableFn(CloudBigtableConfiguration config, ReadDataOptions readDataOptions) {
      super(config);
      keys = new String[Math.toIntExact(getNumRows(readDataOptions))];
      downloadImageData(readDataOptions.getFilePath());
      generateRowkeys(getNumRows(readDataOptions));
    }

    @ProcessElement
    public void processElement(PipelineOptions po) {
      // Determine which column will be drawn based on runtime of job.
      long timestampDiff = System.currentTimeMillis() - START_TIME;
      long minutes = (timestampDiff / 1000) / 60;
      int timeOffsetIndex = Math.toIntExact(minutes / KEY_VIZ_WINDOW_MINUTES);

      ReadDataOptions options = po.as(ReadDataOptions.class);
      long count = 0;

      List<RowRange> ranges = getRangesForTimeIndex(timeOffsetIndex, getNumRows(options));
      if (ranges.size() == 0) {
        return;
      }

      try {
        // Scan with a filter that will only return the first key from each row. This filter is used
        // to more efficiently perform row count operations.
        Filter rangeFilters = new MultiRowRangeFilter(ranges);
        FilterList firstKeyFilterWithRanges = new FilterList(
            rangeFilters,
            new FirstKeyOnlyFilter(),
            new KeyOnlyFilter());
        Scan scan =
            new Scan()
                .addFamily(Bytes.toBytes(COLUMN_FAMILY))
                .setFilter(firstKeyFilterWithRanges);

        Table table = getConnection().getTable(TableName.valueOf(options.getBigtableTableId()));
        ResultScanner imageData = table.getScanner(scan);
      } catch (Exception e) {
        System.out.println("Error reading.");
        e.printStackTrace();
      }
    }

    /**
     * Download the image data as a grid of weights and store them in a 2D array.
     */
    private void downloadImageData(String artUrl) {
    ...
    }

    /**
     * Generates an array with the rowkeys that were loaded into the specified Bigtable. This is
     * used to create the correct intervals for scanning equal sections of rowkeys. Since Bigtable
     * sorts keys lexicographically if we just used standard intervals, each section would have
     * different sizes.
     */
    private void generateRowkeys(long maxInput) {
    ...
    }

    /**
     * Get the ranges to scan for the given time index.
     */
    private List<RowRange> getRangesForTimeIndex(@Element Integer timeOffsetIndex, long maxInput) {
    ...
    }
  }

6- جارٍ إنشاء تحفتك الفنية

ad9c4c0b90626a3b.png

الآن بعد أن فهمت كيفية تحميل البيانات إلى Bigtable والقراءة منها باستخدام Dataflow، يمكنك تشغيل الأمر النهائي الذي سينشئ صورة للموناليزا على مدار 8 ساعات.

mvn compile exec:java -Dexec.mainClass=keyviz.ReadData \
"-Dexec.args=--bigtableProjectId=$BIGTABLE_PROJECT \
--bigtableInstanceId=$INSTANCE_ID --runner=dataflow \
--bigtableTableId=$TABLE_ID --project=$GOOGLE_CLOUD_PROJECT"

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

يتم إنشاء أسماء الملفات من مثال gs://keyviz-art/[painting]_[hours]h.txt: gs://keyviz-art/american_gothic_4h.txt

خيارات الطلاء:

  • american_gothic
  • mona_lisa
  • pearl_earring
  • persistence_of_memory
  • starry_night
  • sunday_afternoon
  • the_scream

خيارات الساعة: 1، و4، و8، و12، و24، و48، و72، و96، و120، و144

يمكنك إتاحة ملف أو حزمة GCS بشكل علني من خلال منح allUsers الدور "Storage Object Viewer".

ee089815364150d2.png

بعد اختيار الصورة، ما عليك سوى تغيير معلَمة --file-path في الأمر التالي:

mvn compile exec:java -Dexec.mainClass=keyviz.ReadData \
"-Dexec.args=--bigtableProjectId=$BIGTABLE_PROJECT \
--bigtableInstanceId=$INSTANCE_ID --runner=dataflow \
--bigtableTableId=$TABLE_ID --project=$GOOGLE_CLOUD_PROJECT \
--filePath=gs://keyviz-art/american_gothic_4h.txt"

7. التحقّق من ذلك لاحقًا

قد يستغرق ظهور الصورة الكاملة بضع ساعات، ولكن بعد 30 دقيقة، يجب أن تبدأ في رؤية النشاط في أداة العرض الرئيسية. هناك عدة معلمات يمكنك استخدامها: التكبير/التصغير والسطوع والمقياس. يمكنك التكبير أو التصغير باستخدام عجلة التمرير على الماوس، أو عن طريق سحب مستطيل على شبكة أداة العرض الرئيسية.

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

8e847f03df25572b.png

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

33eb5dcf4e4be861.png

8. إنهاء

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

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

gcloud bigtable instances delete $INSTANCE_ID

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

  • الكتابة في Bigtable باستخدام Dataflow
  • القراءة من Bigtable باستخدام Dataflow (في بداية مسار الإحالة الناجحة، في منتصف المسار)
  • استخدام أدوات تتبُّع Dataflow
  • استخدام أدوات مراقبة Bigtable، بما في ذلك Key Visualizer

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