1. Wprowadzenie
To ćwiczenie w Codelabs jest przeznaczone dla każdego, kto przenosi zapytania z Apache Cassandra do Google Cloud Bigtable.
W ramach tego ćwiczenia w Codelabs
- Używanie emulatora Cloud Bigtable
- Poznaj przypadek użycia ciągu czasowego
- Tworzenie tabeli i grupy kolumn
- Poznaj odpowiedniki Cloud Bigtable w Javie dotyczące wstawiania, aktualizowania, wyboru i usuwania w CQL
Jak oceniasz swoje doświadczenia z korzystaniem z Google Cloud Platform?
Jak wykorzystasz ten samouczek?
2. Skonfiguruj
Zobaczysz przykładowy zbiór danych zawierający tylko kilka wierszy, który pozwoli Ci szybko zrozumieć podstawowe pojęcia.
Cassandra
W każdym kroku dostępne będą takie same zapytania Cassandra, więc możesz wykonać opisane niżej czynności w klastrze lokalnym. Możesz też szybko skonfigurować klaster Cassandra, który można łatwo wdrożyć i użyć do niego SSH.
Jeśli je śledzisz, utwórz i wykorzystaj obszar klawiszy. Strategia replikacji nie będzie w tym przypadku ważna.
cqlsh> create keyspace mykeyspace with replication = {'class':'SimpleStrategy','replication_factor' : 2}; cqlsh> use mykeyspace;
Cloud Bigtable
Potrzebujesz instancji Cloud Bigtable dla tabeli. Możesz skonfigurować instancję lokalną bezpłatnie za pomocą emulatora. Nie musisz tworzyć przestrzeni kluczy w Cloud Bigtable, replikacja jest obsługiwana przez konfigurację instancji.
Użyj tego polecenia, aby uruchomić emulator:
gcloud beta emulators bigtable start
Następnie w innym oknie powłoki lub na innej karcie ustaw zmienną środowiskową emulatora za pomocą tego polecenia:
$(gcloud beta emulators bigtable env-init) #Sets BIGTAB`LE_EMULATOR_HOST
Następnie utwórz projekt w Javie, którego użyjesz do uruchomienia przykładowego kodu, i zaimportuj klienta Cloud Bigtable za pomocą Maven, Gradle lub SBT. Następnie w nowym pliku Java utwórz połączenie z klientem danych.
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. Tworzenie tabeli
W tabelach Cassandra i Cloud Bigtable z każdym wierszem powiązany jest klucz. Klucze Cassandra mają klucz partycji i kolumnę grupowania, które mogą być oddzielne lub nakładać się na siebie. Do podziału (partycji) i kolejności używane są wszystkie klucze Cloud Bigtable. Te 2 systemy są bardzo podobne pod względem konstrukcji klucza podstawowego/wiersza. Oba systemy są zasadniczo posortowanymi leksykograficznie listami, na których klucze stanowią główną formę rozkładu wierszy między węzłami. W większości przypadków można wykorzystać ten sam klucz w Cloud Bigtable.
Dzięki temu ćwiczeniu w programowaniu wykorzystasz Cloud Bigtable do przechowywania danych ciągu czasowego o telefonach komórkowych i tabletach mobilnych (nie należy ich mylić z dużymi tabletami). Poniżej znajdziesz instrukcje tworzenia tabeli.
Cassandra
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
Tabele i grupę kolumn możesz utworzyć za pomocą klienta w języku Java, ale najłatwiej zrobisz to w narzędziu cbt:
cbt createtable mobile-time-series families=stats_summary
Cloud Bigtable to baza danych NoSQL, więc nie musisz definiować schematu podczas tworzenia tabeli, ale warto zastanowić się nad użyciem zapytań i zoptymalizować dla nich klucz wiersza.
Najpowszechniejszą strategią migracji kluczy jest po prostu połączenie wszystkich kluczy partycji i kolumn grupowych w celu utworzenia ciągu reprezentującego klucz wiersza Cloud Bigtable. Zasadniczo zalecamy używanie kluczy opartych na ciągach znaków, ponieważ pomagają one w debugowaniu dystrybucji kluczy za pomocą narzędzia Key Visualizer. Możesz używać separatora, np. znaku „#” między wartościami kolumn, aby zwiększyć czytelność.
W tym przykładzie użyjemy klucza wiersza „[DEVICE_TYPE]#[DEVICE_ID]#[RRRRMMDD]”
4. Wstawki
Wstawki są dość podobne w Cassandra i Cloud Bigtable. W tym miejscu wstawisz jeden wiersz, a potem kilka wierszy, korzystając z klucza wiersza „[DEVICE_TYPE]#[DEVICE_ID]#[RRRRMMDD]”.
Cassandra
Singiel
cqlsh:mykeyspace> insert into mobileTimeSeries (deviceid, devicetype, date, connected_cell, os_build) values ('4c410523', 'phone',toDate(now()), {toTimeStamp(now()): true}, 'PQ2A.190405.003');
Wsad
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
Singiel
Utwórz mutację z kluczem wiersza i danymi, których chcesz użyć, a następnie zastosuj ją w kliencie danych. Dodajesz wiersz danych dotyczący telefonu z informacjami o połączeniu z siecią komórkową i systemie operacyjnym.
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());
}
Wsad
Zdefiniuj wiele mutacji w obiekcieBulkMutation, a następnie za pomocą klienta danych zastosuj wszystkie mutacje za pomocą jednego wywołania interfejsu API. Dodajesz dane z kilku dni o nazwie i wersji systemu operacyjnego tabletu.
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. Aktualizacje
W tym przykładzie zaktualizujesz komórkę, która nie została jeszcze zapisana, a następnie wpiszesz w niej nową wartość, zachowując jednocześnie wcześniejsze wersje.
Cassandra
Dodawanie komórek
cqlsh:mykeyspace> UPDATE mobileTimeSeries SET os_name = 'android' WHERE devicetype='phone' AND deviceid = '4c410523' AND date = '2019-09-06';
Aktualizowanie komórek
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
W Cloud Bigtable aktualizacje można traktować tak samo jak zapisy.
Dodawanie komórek
Ta funkcja działa tak samo jak zapisywanie komórek. Wystarczy, że dodasz kolumnę, w której dotychczas nie były zapisywane dane. W tym miejscu dodasz nazwę systemu operacyjnego do wiersza telefonu.
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());
}
Aktualizuję komórki
Dodaj w tym miejscu nowe dane o stanie połączenia telefonu z siecią komórkową. Do łatwego przechowywania części danych ciągów czasowych możesz używać wersji komórek. Wystarczy, że podasz sygnaturę czasową zapisu, a dodasz nową wersję komórki. Aby wyczyścić dane, możesz użyć funkcji odśmiecania, aby usunąć wersje po określonej liczbie lub przez określony czas.
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. Wybiera
Teraz pobierzesz dane zapisane w tabeli. Podczas migracji instrukcji wyboru CQL musisz wziąć pod uwagę kilka aspektów instrukcji wyboru, takich jak kolumny, filtrowanie według klauzul Gdzie oraz funkcje ograniczania i agregacji, takie jak „grupuj według”. Oto 2 proste spostrzeżenia, które pomogą Ci zrozumieć podstawowe pojęcie, ale więcej informacji na ten temat znajdziesz w dokumentacji. W Cloud Bigtable dostępne są 2 typy operacji pobierania: pobieranie i skanowanie. Get pobiera 1 wiersz, a skanowanie pobiera zakres wierszy.
Cassandra
Singiel
cqlsh:mykeyspace> SELECT * FROM mobileTimeSeries WHERE devicetype='phone' AND deviceid = '4c410523' AND date = '2019-09-04';
Wiele
cqlsh:mykeyspace> SELECT * FROM mobileTimeSeries WHERE devicetype='tablet' AND deviceid = 'a0b81f74' AND date >= '2019-09-04';
Cloud Bigtable
Pojedynczy
Wyszukiwanie wierszy w celu uzyskania danych o konkretnym telefonie z określonego dnia, które mieści się w jednym wierszu. Spowoduje to zwrócenie każdej wersji wartości oznaczonej sygnaturą czasową, więc powinny się pojawić 2 wiersze dla connection_cell o różnych sygnaturach czasowych.
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());
}
Wiele
Skanowanie zakresów pozwala wyświetlić dane z określonego tabletu mobilnego z określonego miesiąca w wielu wierszach. Możesz użyć filtrów, aby uzyskać tylko określone wersje danych lub filtrować według wartości.
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. Usunięcia
W tym miejscu usuniesz dane umieszczone w tabeli. Najpierw usuń pojedynczy wiersz, a potem wiele wierszy.
CQL Cassandra umożliwia usuwanie pojedynczych wierszy i zakresów, gdy określone są wszystkie kolumny podstawowe. W Bigtable możesz to zrobić, skanując zakres, a następnie wykonując usuwanie na poziomie wiersza. Pamiętaj, że uzyskasz ten sam wynik, ale z uwzględnieniem większej liczby operacji, ponieważ każde usunięcie będzie osobną operacją.
Cassandra
Singiel
cqlsh:mykeyspace> DELETE from mobileTimeSeries where devicetype='phone' and deviceid = '4c410523';
Wiele
cqlsh:mykeyspace> DELETE from mobileTimeSeries where devicetype='tablet' and deviceid = 'a0b81f74';
Cloud Bigtable
Singiel
W tym miejscu usuniesz dane z określonego telefonu i daty. Za pomocą klucza wiersza możesz usunąć wiersz po jednym wierszu.
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());
}
Wiele
W tym miejscu usuniesz wszystkie dane określonego tabletu mobilnego. Aby przenieść zapytanie CQL z wieloma wierszami, musisz przeprowadzić skanowanie, a następnie usunąć każdy wiersz, używając wynikowego zestawu kluczy wierszy.
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. Kończę
Czyszczenie danych
Cassandra
Jeśli w związku z tym został przez Ciebie utworzony klaster Cassandra, możesz go usunąć w normalny sposób.
Cloud Bigtable
Jeśli tabela została utworzona na podstawie istniejącej instancji Cloud Bigtable, możesz ją usunąć za pomocą polecenia cbt
cbt deletetable mobile-time-series
Jeśli korzystasz z emulatora, możesz go po prostu zatrzymać, aby usunąć całą pracę, wpisując CTRL-C w terminalu, w którym została uruchomiona.
Dalsze kroki
- Więcej informacji o Cloud Bigtable znajdziesz w dokumentacji.
- Zapoznaj się ze szczegółowymi ćwiczeniami z programowania w Cloud Bigtable.
- Wypróbuj inne funkcje Google Cloud Platform. Zapoznaj się z naszymi samouczkami.
- Dowiedz się, jak monitorować dane ciągów czasowych za pomocą integracji z OpenTSDB