Bigtable و Dataflow: هنر نظارت بر پایگاه داده (HBase Java Client)

1. مقدمه

در این کد لبه، از ابزارهای نظارتی Cloud Bigtable برای ایجاد آثار هنری مختلف از طریق نوشتن و خواندن داده ها با Cloud Dataflow و سرویس گیرنده Java HBase استفاده خواهید کرد.

شما یاد خواهید گرفت که چگونه

  • با استفاده از Cloud Dataflow مقادیر زیادی داده را در Bigtable بارگیری کنید
  • نمونه‌ها و جداول Bigtable را در حین دریافت داده‌های شما نظارت کنید
  • Bigtable را با استفاده از یک کار جریان داده جستجو کنید
  • ابزار تصویرسازی کلیدی را که می‌تواند برای یافتن نقاط مهم به دلیل طراحی طرح شما مورد استفاده قرار گیرد، کاوش کنید
  • با استفاده از تجسم کننده کلید، هنر ایجاد کنید

d098cc81f78f02eb.png

تجربه خود را در استفاده از Cloud Bigtable چگونه ارزیابی می کنید؟

تازه کار متوسط مسلط

چگونه از این آموزش استفاده خواهید کرد؟

فقط از طریق آن را بخوانید آن را بخوانید و تمرینات را کامل کنید

2. پایگاه داده Bigtable خود را ایجاد کنید

Cloud Bigtable سرویس پایگاه داده Big Data NoSQL گوگل است. این همان پایگاه داده ای است که بسیاری از خدمات اصلی گوگل از جمله جستجو، تجزیه و تحلیل، نقشه ها و جیمیل را تامین می کند. این برای اجرای حجم های کاری تحلیلی بزرگ و ساخت برنامه های کاربردی با تاخیر کم ایده آل است. برای معرفی عمیق، مقدمه ای بر Cloud Bigtable Codelab را بررسی کنید.

یک پروژه ایجاد کنید

ابتدا یک پروژه جدید ایجاد کنید. از Cloud Shell داخلی استفاده کنید، که می توانید با کلیک کردن روی دکمه "فعال کردن پوسته ابری" در گوشه سمت راست بالا، آن را باز کنید.

a74d156ca7862b28.png

متغیرهای محیطی زیر را تنظیم کنید تا کپی و چسباندن دستورات Codelab آسانتر شود:

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 که قبلاً نصب شده‌اند.

با اجرای این دستور، API های 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 را ارسال کند که می تواند شامل Put و Delete باشد.

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 گیگابایت داده را در جدول شما تولید می کند، بیش از اندازه کافی برای فعال کردن Key Visualizer:

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، می‌توانید نمودار کار و معیارهای مختلف کار از جمله عناصر پردازش شده، vCPUهای فعلی و توان عملیاتی را مشاهده کنید.

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);
    }   
}

کار ReadData Dataflow

برای این کد لبه شما باید هر ثانیه از جدول بخوانید، بنابراین می توانید خط لوله خود را با یک دنباله تولید شده شروع کنید که بر اساس زمان یک فایل 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 بخوانید، می‌توانید فرمان نهایی را اجرا کنید که تصویری از مونالیزا را در مدت ۸ ساعت ایجاد می‌کند.

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

گزینه های نقاشی:

  • آمریکایی_گوتیک
  • مونالیزا
  • مروارید_گوشواره
  • تداوم_حافظه
  • ستاره_شب
  • یکشنبه_بعدازظهر
  • the_scream

گزینه های ساعت: 1، 4، 8، 12، 24، 48، 72، 96، 120، 144

سطل یا فایل GCS خود را با دادن نقش Storage Object Viewer به allUsers عمومی کنید.

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

همچنین می توانید تنظیم کنید که کدام متریک نمایش داده شود. OPs، Read bytes client، Writes bytes client برای نام بردن چند مورد وجود دارد. به نظر می‌رسد که "Read bytes client" تصاویر صافی تولید می‌کند در حالی که "Ops" تصاویری با خطوط بیشتری تولید می‌کند که می‌تواند در برخی از تصاویر واقعاً جالب به نظر برسد.

33eb5dcf4e4be861.png

8. کار را تمام کنید

برای جلوگیری از هزینه، تمیز کنید

برای جلوگیری از تحمیل هزینه به حساب Google Cloud Platform برای منابع استفاده شده در این کد، باید نمونه خود را حذف کنید.

gcloud bigtable instances delete $INSTANCE_ID

آنچه را پوشش داده ایم

  • نوشتن در Bigtable با Dataflow
  • خواندن از Bigtable با Dataflow (در ابتدای خط لوله شما، در وسط خط لوله شما)
  • با استفاده از ابزارهای نظارت بر جریان داده
  • با استفاده از ابزارهای نظارت Bigtable از جمله Key Visualizer

مراحل بعدی

  • درباره نحوه ایجاد هنر Key Visualizer بیشتر بخوانید.
  • درباره Cloud Bigtable در مستندات بیشتر بیاموزید.
  • سایر ویژگی های Google Cloud Platform را برای خودتان امتحان کنید. نگاهی به آموزش های ما بیندازید.