Cloud Bigtable для пользователей Cassandra

1. Введение

Эта лаборатория кода представляет собой руководство для всех, кто переносит запросы из Apache Cassandra в Google Cloud Bigtable.

В этой лаборатории кода вы

  • Используйте эмулятор Cloud Bigtable
  • Изучите вариант использования таймсерий
  • Создание семейства таблиц и столбцов
  • Изучите Java-эквиваленты CQL-вставки, обновления, выбора и удаления в Cloud Bigtable.

Как бы вы оценили свой опыт использования 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, ваша репликация обрабатывается конфигурацией вашего экземпляра.

Используйте следующую команду для запуска эмулятора:

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 используются для разделения (разделов) и упорядочивания. Эти две системы невероятно похожи, когда дело доходит до построения первичного ключа/ключа строки. Обе системы по сути представляют собой лексикографически отсортированные списки, в которых ключи выступают в качестве основной формы распределения строк между узлами. В большинстве случаев вы можете повторно использовать один и тот же ключ для Cloud Bigtable.

В этой кодовой лаборатории вы будете использовать 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));

Облачный большой стол

Вы можете создать семейство таблиц и столбцов с помощью клиента Java , но проще всего использовать следующую команду с инструментом cbt :

cbt createtable mobile-time-series families=stats_summary

Cloud Bigtable — это база данных NoSQL, поэтому вам не нужно определять схему при создании таблицы, но вам нужно подумать о запросах, которые вы собираетесь выполнять, и оптимизировать ключ строки для них.

Наиболее распространенная стратегия миграции ключей — просто взять все ключи разделов и столбцы кластеризации и объединить их, чтобы сформировать строку, представляющую ключ строки Cloud Bigtable. Обычно мы рекомендуем использовать ключи на основе строк, поскольку они помогают при отладке распределения ключей с помощью Key Visualizer . Вы можете использовать разделитель, например решетку «#», между значениями столбца, чтобы улучшить читаемость.

В этом примере мы будем использовать ключ строки «[DEVICE_TYPE]#[DEVICE_ID]#[ГГГГММДД]».

4. Вставки

Вставки между Cassandra и Cloud Bigtable довольно похожи. Здесь вы вставите одну строку, а затем несколько строк, используя ключ строки «[DEVICE_TYPE]#[DEVICE_ID]#[ГГГГММДД]».

Кассандра

Одинокий

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;

Облачный большой стол

Одинокий

Создайте мутацию с ключом строки и данными, которые вы хотите использовать, а затем примените мутацию с помощью клиента данных. Вы добавите строку данных для телефона с информацией о его сотовом соединении и операционной системе.

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

Партия

Определите несколько мутаций для объекта BulkMutation, а затем используйте клиент данных, чтобы применить все мутации с помощью одного вызова API. Вы добавите данные за несколько дней о названии и версии операционной системы мобильного планшета.

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. Обновления

Здесь вы обновите ячейку, которая еще не была записана, а затем запишите в ячейку новое значение, сохранив при этом предыдущие версии.

Кассандра

Добавление ячеек

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 вы можете обрабатывать обновления так же, как и записи.

Добавление ячеек

Это то же самое, что и запись ячеек, просто укажите столбец, в который вы ранее не записывали. Здесь вы добавите название операционной системы в строку телефона.

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. Выбор

Теперь вы получите данные, которые вы записали в таблицу. При миграции операторов select CQL необходимо учитывать несколько аспектов операторов select, таких как столбцы, фильтрация с помощью предложенийwhere, а также функции ограничения и агрегирования, такие как группировка по. Здесь вы просто рассмотрите два простых оператора выбора, чтобы понять основную идею, но дополнительную информацию о выборе вы можете найти в документации. В Cloud Bigtable есть два типа операций извлечения: получение и сканирование. Get извлекает одну строку, а scan извлекает диапазон строк.

Кассандра

Одинокий

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';

Облачный большой стол

Одинокий

Используйте поиск по строкам, чтобы получить данные для определенного телефона на указанную дату, которые находятся в одной строке. Это вернет каждую версию значений с отметкой времени, поэтому вы должны увидеть две строки для linked_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';

Облачный большой стол

Одинокий

Здесь вы удалите данные для конкретного телефона и даты. Используйте клавишу строки для удаления одной строки за раз.

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 для выполнения этой задачи, смело удаляйте его, как обычно.

Облачный большой стол

Если вы создали свою таблицу в существующем экземпляре Cloud Bigtable, вы можете удалить ее с помощью команды cbt.

cbt deletetable mobile-time-series

Если вы использовали эмулятор, вы можете просто остановить эмулятор, чтобы завершить всю работу, набрав CTRL-C в терминале, в котором вы его запустили.

Следующие шаги