Cloud Bigtable สำหรับผู้ใช้ Cassandra

1. บทนำ

Codelab นี้เป็นคำแนะนำสำหรับทุกคนที่ย้ายข้อมูลการค้นหาจาก Apache Cassandra ไปยัง Google Cloud Bigtable

ใน Codelab นี้ คุณจะ

  • ใช้โปรแกรมจำลอง Cloud Bigtable
  • ดูกรณีการใช้งานอนุกรมเวลา
  • สร้างกลุ่มตารางและคอลัมน์
  • ดูข้อมูลเทียบเท่ากับ Java ของ Cloud Bigtable ของการแทรก อัปเดต เลือก และลบ CQL

คุณจะให้คะแนนความพึงพอใจสำหรับประสบการณ์ในการใช้ Google Cloud Platform อย่างไร

มือใหม่ ระดับกลาง ผู้ชำนาญ

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านเท่านั้น อ่านและทำแบบฝึกหัด

2. ตั้งค่า

แสดงตัวอย่างชุดข้อมูลเพียงไม่กี่แถวเพื่อให้คุณเข้าใจแนวคิดหลักได้อย่างรวดเร็ว

คาสซานดรา

ระบบจะแสดงคำค้นหา Cassandra ที่เทียบเท่าในแต่ละขั้นตอน ดังนั้นโปรดติดตามคลัสเตอร์ในเครื่องหากต้องการ หรือคุณจะตั้งค่าคลัสเตอร์ Cassandra แบบคลิกเพื่อทำให้ใช้งานได้อย่างรวดเร็วและ SSH ลงในคลัสเตอร์ก็ได้

ถ้าคุณกำลังติดตามอยู่ ให้สร้างคีย์เว้นวรรคและใช้คีย์นั้น กลยุทธ์การจำลองจะไม่สำคัญในที่นี้

cqlsh> create keyspace mykeyspace with replication = {'class':'SimpleStrategy','replication_factor' : 2};
cqlsh> use mykeyspace;

Cloud Bigtable

คุณจะต้องมีอินสแตนซ์ Cloud Bigtable สำหรับตารางของคุณ คุณสามารถตั้งค่าอินสแตนซ์ในเครื่องฟรีโดยใช้โปรแกรมจำลอง คุณไม่จำเป็นต้องสร้าง Keyspace ใน Cloud Bigtable ระบบจะจัดการการจำลองโดยการกำหนดค่าอินสแตนซ์ของคุณ

ใช้คำสั่งต่อไปนี้เพื่อเริ่มโปรแกรมจำลอง

gcloud beta emulators bigtable start

จากนั้นในหน้าต่างหรือแท็บอื่นของเชลล์ ให้ตั้งค่าตัวแปรสภาพแวดล้อมโปรแกรมจำลองด้วยคำสั่งนี้

$(gcloud beta emulators bigtable env-init) #Sets BIGTAB`LE_EMULATOR_HOST

จากนั้นสร้างโปรเจ็กต์ Java ที่จะใช้ในการเรียกใช้ตัวอย่างโค้ด และนำเข้าไคลเอ็นต์ Cloud Bigtable ด้วย Maven, Gradle หรือ SBT จากนั้นสร้างการเชื่อมต่อกับไคลเอ็นต์ข้อมูลในไฟล์ Java ใหม่

BigtableDataSettings settings =
    BigtableDataSettings.newBuilder().setProjectId(projectId).setInstanceId(instanceId).build();

try {
  dataClient = BigtableDataClient.create(settings);
} catch (Exception e) {
  System.out.println("Error during data client connection: \n" + e.toString());
}

3. การสร้างตาราง

ในตาราง Cassandra และ Cloud Bigtable แต่ละแถวจะมีคีย์ที่เชื่อมโยงอยู่ คีย์ Cassandra มีคีย์พาร์ติชันและคอลัมน์คลัสเตอร์ซึ่งอาจแยกกันหรือทับซ้อนกันได้ คีย์ Cloud Bigtable ทั้งหมดจะใช้สำหรับการแยก (พาร์ติชัน) และการจัดลำดับ ระบบทั้งสองนี้มีความคล้ายคลึงกันอย่างมากในด้านการสร้างคีย์หลัก/แถว ทั้ง 2 ระบบเป็นรายการที่จัดเรียงแบบพจนานุกรมซึ่งคีย์ทำหน้าที่เป็นรูปแบบหลักของการกระจายแถวระหว่างโหนด ในกรณีส่วนใหญ่ คุณจะใช้คีย์เดียวกันสำหรับ Cloud Bigtable ได้

ใน Codelab นี้ คุณจะใช้ Cloud Bigtable ในการจัดเก็บข้อมูลอนุกรมเวลาเกี่ยวกับโทรศัพท์มือถือและแท็บเล็ตมือถือ (อย่าสับสนกับแท็บเล็ต Bigtable) วิธีการสร้างตารางมีดังนี้

คาสซานดรา

cqlsh:mykeyspace> create table mobileTimeSeries (
           deviceid text,
           devicetype text,
           date date,
           connected_cell map<timestamp,Boolean>, 
           os_build text, 
           os_name text,
           PRIMARY KEY((devicetype, deviceid), date));

Cloud Bigtable

คุณสามารถสร้างกลุ่มตารางและคอลัมน์ได้โดยใช้ไคลเอ็นต์ Java แต่วิธีที่ง่ายที่สุดคือใช้คำสั่งต่อไปนี้กับเครื่องมือ cbt

cbt createtable mobile-time-series families=stats_summary

Cloud Bigtable เป็นฐานข้อมูล NoSQL ดังนั้นคุณไม่จำเป็นต้องกำหนดสคีมาขณะสร้างตาราง แต่คุณจะต้องคำนึงถึงคำค้นหาที่จะใช้และเพิ่มประสิทธิภาพคีย์ประจำแถวสำหรับการค้นหาดังกล่าว

กลยุทธ์ที่พบบ่อยที่สุดสำหรับการย้ายข้อมูลคีย์คือการนำคีย์พาร์ติชันและคอลัมน์ของคลัสเตอร์ทั้งหมดมารวมกันเพื่อสร้างสตริงที่แสดงถึงคีย์แถวของ Cloud Bigtable โดยทั่วไป เราขอแนะนำให้ใช้คีย์แบบสตริงเนื่องจากช่วยในการแก้ไขข้อบกพร่องของการกระจายคีย์ผ่าน Key Visualizer คุณใช้ตัวคั่น เช่น แฮช "#" ได้ ระหว่างค่าคอลัมน์เพื่อช่วยให้อ่านได้ง่ายขึ้น

ในตัวอย่างนี้ เราจะใช้คีย์แถวของ "[DEVICE_TYPE]#[DEVICE_ID]#[YYYYMMDD]"

4. ส่วนแทรก

ส่วนแทรกระหว่าง Cassandra และ Cloud Bigtable จะคล้ายคลึงกันพอสมควร ในส่วนนี้ คุณจะแทรกแถว 1 แถวแล้วแทรกหลายแถวโดยใช้คีย์แถว "[DEVICE_TYPE]#[DEVICE_ID]#[YYYYMMDD]"

คาสซานดรา

ซิงเกิล

cqlsh:mykeyspace> insert into mobileTimeSeries (deviceid, devicetype, date, connected_cell, os_build) values ('4c410523', 'phone',toDate(now()), {toTimeStamp(now()): true}, 'PQ2A.190405.003');

กลุ่ม

cqlsh:mykeyspace> BEGIN BATCH
insert into mobileTimeSeries (deviceid, devicetype, date, os_name, os_build) values ('a0b81f74', 'tablet', '2019-01-01', 'chromeos', '12155.0.0-rc1');
insert into mobileTimeSeries (deviceid, devicetype, date, os_name, os_build) values ('a0b81f74', 'tablet', '2019-01-02','chromeos', '12145.0.0-rc6');
APPLY BATCH;

Cloud Bigtable

ซิงเกิล

สร้างการเปลี่ยนแปลงด้วยคีย์แถวและข้อมูลที่ต้องการใช้ จากนั้นใช้รูปแบบการเปลี่ยนแปลงกับไคลเอ็นต์ข้อมูล คุณจะต้องเพิ่มแถวข้อมูลสำหรับโทรศัพท์ที่มีข้อมูลเกี่ยวกับการเชื่อมต่อเครือข่ายมือถือและระบบปฏิบัติการของโทรศัพท์

try {
  System.currentTimeMillis();
  long timestamp = (long) 1556712000 * 1000; // Timestamp of June 1, 2019 12:00

  String rowKey = "phone#4c410523#20190501";
  ByteString one = ByteString.copyFrom(new byte[] {0, 0, 0, 0, 0, 0, 0, 1});

  RowMutation rowMutation =
      RowMutation.create(tableId, rowKey)
          .setCell(
              COLUMN_FAMILY_NAME,
              ByteString.copyFrom("connected_cell".getBytes()),
              timestamp,
              one)
          .setCell(COLUMN_FAMILY_NAME, "os_build", timestamp, "PQ2A.190405.003");

  dataClient.mutateRow(rowMutation);
} catch (Exception e) {
  System.out.println("Error during Write: \n" + e.toString());
}

กลุ่ม

กำหนด Mutation หลายรายการในออบเจ็กต์ groupsMutation จากนั้นใช้ไคลเอ็นต์ข้อมูลเพื่อนำการเปลี่ยนแปลงทั้งหมดไปใช้กับการเรียก API ครั้งเดียว คุณจะเพิ่มข้อมูลเกี่ยวกับชื่อและเวอร์ชันของระบบปฏิบัติการของแท็บเล็ตมือถือเป็นเวลา 2-3 วัน

try {
  long timestamp = (long) 1556712000 * 1000; // Timestamp of June 1, 2019 12:00

  BulkMutation bulkMutation =
      BulkMutation.create(tableId)
          .add(
              "tablet#a0b81f74#20190501",
              Mutation.create()
                  .setCell(COLUMN_FAMILY_NAME, "os_name", timestamp, "chromeos")
                  .setCell(COLUMN_FAMILY_NAME, "os_build", timestamp, "12155.0.0-rc1"))
          .add(
              "tablet#a0b81f74#20190502",
              Mutation.create()
                  .setCell(COLUMN_FAMILY_NAME, "os_name", timestamp, "chromeos")
                  .setCell(COLUMN_FAMILY_NAME, "os_build", timestamp, "12155.0.0-rc6"));

  dataClient.bulkMutateRows(bulkMutation);
} catch (Exception e) {
  System.out.println("Error during WriteBatch: \n" + e.toString());
}

5. อัปเดต

ในส่วนนี้จะเป็นการอัปเดตเซลล์ที่ยังไม่ได้เขียน แล้วเขียนค่าใหม่ลงในเซลล์โดยเก็บเวอร์ชันก่อนหน้าไว้ด้วย

Cassandra

การเพิ่มเซลล์

cqlsh:mykeyspace> UPDATE mobileTimeSeries SET os_name = 'android' WHERE devicetype='phone' AND deviceid = '4c410523' AND date = '2019-09-06';

การอัปเดตเซลล์

cqlsh:mykeyspace> UPDATE mobileTimeSeries SET connected_cell = connected_cell +  {toTimeStamp(now()): false} WHERE devicetype='phone' AND deviceid = '4c410523' AND date = '2019-09-06';

Cloud Bigtable

ใน Cloud Bigtable คุณดูแลการอัปเดตได้เช่นเดียวกับการเขียน

การเพิ่มเซลล์

วิธีนี้เหมือนกับการเขียนเซลล์ เพียงระบุคอลัมน์ที่คุณยังไม่ได้เขียนก่อนหน้านี้ คุณจะต้องเพิ่มชื่อระบบปฏิบัติการในแถวของโทรศัพท์

try {
  long timestamp = (long) 1556713800 * 1000; // Timestamp of June 1, 2019 12:30

  String rowKey = "phone#4c410523#20190501";

  RowMutation rowMutation =
      RowMutation.create(tableId, rowKey)
          .setCell(COLUMN_FAMILY_NAME, "os_name", timestamp, "android");

  dataClient.mutateRow(rowMutation);
} catch (Exception e) {
  System.out.println("Error during update: \n" + e.toString());
}

กำลังอัปเดตเซลล์

คุณจะเพิ่มข้อมูลใหม่เกี่ยวกับสถานะการเชื่อมต่อเครือข่ายมือถือของโทรศัพท์ในส่วนนี้ คุณจะใช้เวอร์ชันเซลล์เพื่อเก็บข้อมูลอนุกรมเวลาบางส่วนได้อย่างง่ายดาย เพียงระบุการประทับเวลาสำหรับการเขียนแล้วจะเป็นการเพิ่มเวอร์ชันใหม่ให้กับเซลล์ หากต้องการล้างข้อมูล คุณสามารถใช้การเก็บข้อมูลขยะเพื่อลบเวอร์ชันหลังจากจำนวนหนึ่งหรือระยะเวลาหนึ่งได้

try {
  long timestamp = (long) 1556713800 * 1000; // Timestamp of June 1, 2019 12:30

  String rowKey = "phone#4c410523#20190501";

  ByteString zero = ByteString.copyFrom(new byte[] {0, 0, 0, 0, 0, 0, 0, 0});

  RowMutation rowMutation =
      RowMutation.create(tableId, rowKey)
          .setCell(
              COLUMN_FAMILY_NAME,
              ByteString.copyFrom("connected_cell".getBytes()),
              timestamp,
              zero);

  dataClient.mutateRow(rowMutation);
} catch (Exception e) {
  System.out.println("Error during update2: \n" + e.toString());
}

6. เลือก

คุณจะต้องดึงข้อมูลที่คุณเขียนไว้ลงในตาราง เมื่อย้ายคำสั่ง CQL เลือก คุณต้องพิจารณาหลายๆ แง่มุมของคำสั่งที่เลือก เช่น คอลัมน์ การกรองเฉพาะตำแหน่งที่ระบุ และจำกัดและรวมฟังก์ชัน เช่น จัดกลุ่มตาม ในที่นี้ เพียงดูข้อความการเลือกง่ายๆ 2 ข้อเพื่อให้ทราบแนวคิดพื้นฐาน คุณสามารถดูข้อมูลเพิ่มเติมเกี่ยวกับการเลือกได้ในเอกสารประกอบ ใน Cloud Bigtable มีการดำเนินการเรียกข้อมูล 2 ประเภท ได้แก่ รับและสแกน เรียกข้อมูล 1 แถวขณะสแกนจะดึงข้อมูลช่วงของแถว

Cassandra

ซิงเกิล

cqlsh:mykeyspace> SELECT * FROM mobileTimeSeries WHERE devicetype='phone' AND deviceid = '4c410523' AND date = '2019-09-04';

หลายรายการ

cqlsh:mykeyspace> SELECT * FROM mobileTimeSeries WHERE devicetype='tablet' AND deviceid = 'a0b81f74' AND date >= '2019-09-04';

Cloud Bigtable

โสด

ใช้การค้นหาแถวเพื่อดูข้อมูลของโทรศัพท์ที่ต้องการ ณ วันที่ที่ระบุ ซึ่งทั้งหมดอยู่ภายในแถวเดียว การดำเนินการนี้จะแสดงค่าที่มีการประทับเวลาแต่ละค่า ดังนั้นคุณควรเห็น 2 บรรทัดสำหรับConnected_cell ในการประทับเวลาที่ต่างกัน

try {
  String rowKey = "phone#4c410523#20190501";

  Row row = dataClient.readRow(tableId, rowKey);
  for (RowCell cell : row.getCells()) {

    System.out.printf(
        "Family: %s    Qualifier: %s    Value: %s    Timestamp: %s%n",
        cell.getFamily(),
        cell.getQualifier().toStringUtf8(),
        cell.getValue().toStringUtf8(),
        cell.getTimestamp());
  }
} catch (Exception e) {
  System.out.println("Error during lookup: \n" + e.toString());
}

หลายรายการ

ใช้การสแกนช่วงเพื่อดูข้อมูลของหนึ่งเดือนสำหรับแท็บเล็ตมือถือที่ระบุ ซึ่งจะกระจายอยู่ในหลายแถว คุณสามารถใช้ตัวกรองกับตัวกรองเหล่านี้เพื่อดูข้อมูลบางเวอร์ชันหรือกรองค่าได้

try {
  Query query = Query.create(tableId).range("tablet#a0b81f74#201905", "tablet#a0b81f74#201906");
  ServerStream<Row> rowStream = dataClient.readRows(query);
  for (Row row : rowStream) {
    System.out.println("Row Key: " + row.getKey().toStringUtf8());
    for (RowCell cell : row.getCells()) {

      System.out.printf(
          "Family: %s    Qualifier: %s    Value: %s    Timestamp: %s%n",
          cell.getFamily(),
          cell.getQualifier().toStringUtf8(),
          cell.getValue().toStringUtf8(),
          cell.getTimestamp());
    }
  }
} catch (Exception e) {
  System.out.println("Error during scan: \n" + e.toString());
}

7. การลบ

คุณจะลบข้อมูลที่ป้อนลงในตารางที่นี่ ขั้นแรก คุณจะต้องลบแต่ละแถวและลบหลายแถว

CQL ของ Cassandra ทำให้สามารถลบแถวเดียวและนำออกช่วงได้เมื่อระบุคอลัมน์หลักทั้งหมด ซึ่งทำได้ด้วย Bigtable โดยการสแกนช่วงแล้วดำเนินการลบระดับแถว โปรดทราบว่าคุณจะได้รับผลลัพธ์เดียวกัน แต่จะมีการดำเนินการมากกว่า เนื่องจากการลบแต่ละครั้งจะเป็นการดำเนินการของตัวเอง

คาสซานดรา

ซิงเกิล

cqlsh:mykeyspace> DELETE from mobileTimeSeries where devicetype='phone' and deviceid = '4c410523';

หลายรายการ

cqlsh:mykeyspace> DELETE from mobileTimeSeries where devicetype='tablet' and deviceid = 'a0b81f74';

Cloud Bigtable

ซิงเกิล

คุณจะลบข้อมูลในโทรศัพท์และวันที่ที่ต้องการในส่วนนี้ ใช้แป้นประจำแถวเพื่อลบทีละแถว

try {
  String rowKey = "phone#4c410523#20190501";

  RowMutation mutation = RowMutation.create(tableId, rowKey).deleteRow();

  dataClient.mutateRow(mutation);
} catch (Exception e) {
  System.out.println("Error during Delete: \n" + e.toString());
}

หลายรายการ

คุณจะลบข้อมูลทั้งหมดของแท็บเล็ตอุปกรณ์เคลื่อนที่เครื่องใดเครื่องหนึ่งได้ที่นี่ หากต้องการย้ายข้อมูลการค้นหา CQL โดยลบหลายแถว คุณจะต้องสแกนแล้วลบแต่ละแถวโดยใช้ชุดคีย์ของแถวที่ได้

try {
  Query query = Query.create(tableId).prefix("tablet#a0b81f7");
  ServerStream<Row> rowStream = dataClient.readRows(query);
  BulkMutation bulkMutation = BulkMutation.create(tableId);
  for (Row row : rowStream) {
    bulkMutation.add(row.getKey(), Mutation.create().deleteRow());
  }

  dataClient.bulkMutateRows(bulkMutation);
} catch (Exception e) {
  System.out.println("Error during DeleteMultiple: \n" + e.toString());
}

8. ใกล้เสร็จแล้ว

ล้างข้อมูล

Cassandra

หากคุณสร้างคลัสเตอร์ Cassandra เพื่อติดตามคลัสเตอร์นี้ คุณสามารถลบได้ตามปกติ

Cloud Bigtable

หากคุณสร้างตารางบนอินสแตนซ์ Cloud Bigtable ที่มีอยู่ คุณสามารถลบตารางได้โดยใช้คำสั่ง cbt

cbt deletetable mobile-time-series

หากคุณใช้โปรแกรมจำลอง คุณสามารถหยุดโปรแกรมจำลองเพื่อล้างงานทั้งหมด โดยพิมพ์ Ctrl-C ในเทอร์มินัลที่คุณเริ่มโปรแกรมไป

ขั้นตอนถัดไป