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 ในเทอร์มินัลที่คุณเริ่มโปรแกรมไป
ขั้นตอนถัดไป
- ดูข้อมูลเพิ่มเติมเกี่ยวกับ Cloud Bigtable ในเอกสารประกอบ
- ลองใช้ Cloud Bigtable Codelab ที่ละเอียดยิ่งขึ้น
- ลองใช้ฟีเจอร์อื่นๆ ของ Google Cloud Platform ด้วยตัวคุณเอง ดูวิดีโอบทแนะนำ
- ดูวิธีตรวจสอบข้อมูลอนุกรมเวลาด้วยการผสานรวม OpenTSDB