1. Введение
В этой лабораторной работе вы познакомитесь с использованием Cloud Bigtable с клиентом Java HBase .
Вы узнаете, как
- Избегайте распространенных ошибок при проектировании схемы
- Импортировать данные в файл последовательности
- Запросите свои данные
Когда вы закончите, у вас будет несколько карт, на которых показаны данные об автобусах Нью-Йорка. Например, вы создадите следующую тепловую карту автобусных поездок по Манхэттену:
Как бы вы оценили свой опыт использования Google Cloud Platform?
Как вы будете использовать этот урок?
2. О наборе данных
Вы будете просматривать набор данных об автобусах Нью-Йорка. По этим маршрутам проложено более 300 автобусных маршрутов и 5800 транспортных средств. Наш набор данных представляет собой журнал, который включает название пункта назначения, идентификатор транспортного средства, широту, долготу, ожидаемое время прибытия и запланированное время прибытия. Набор данных состоит из снимков, сделанных примерно каждые 10 минут в июне 2017 года.
3. Разработка схемы
Чтобы добиться максимальной производительности от Cloud Bigtable, необходимо тщательно подходить к разработке схемы . Данные в Cloud Bigtable автоматически сортируются лексикографически, поэтому, если вы хорошо спроектируете свою схему, запросы связанных данных будут очень эффективными. Cloud Bigtable позволяет выполнять запросы с использованием точечного поиска по ключу строки или сканирования диапазона строк , которые возвращают непрерывный набор строк. Однако, если ваша схема недостаточно продумана, вы можете выполнить поиск по нескольким строкам или, что еще хуже, выполнить полное сканирование таблицы, что является чрезвычайно медленной операцией.
Планируйте запросы
Наши данные содержат разнообразную информацию, но для этой кодовой лаборатории вы будете использовать местоположение и пункт назначения автобуса.
Имея эту информацию, вы можете выполнить следующие запросы:
- Получите местоположение одного автобуса за определенный час.
- Получите данные за день по автобусной линии или конкретному автобусу.
- Найдите все автобусы в прямоугольнике на карте.
- Получите текущие местоположения всех автобусов (если вы получали эти данные в режиме реального времени).
Этот набор запросов не может быть оптимально выполнен вместе. Например, если вы сортируете по времени, вы не сможете выполнить сканирование по местоположению без полного сканирования таблицы. Вам необходимо расставить приоритеты на основе запросов, которые вы чаще всего выполняете.
В этой лаборатории кода вы сосредоточитесь на оптимизации и выполнении следующего набора запросов:
- Получите местоположение конкретного автомобиля в течение часа.
- Получите местоположение всей автобусной линии за час.
- Получите расположение всех автобусов на Манхэттене за час.
- Получите самые последние местоположения всех автобусов на Манхэттене за час.
- Получите расположение всей автобусной линии за месяц.
- Получите местоположение всей автобусной линии с определенным пунктом назначения за час.
Создайте ключ строки
В этой лаборатории кода вы будете работать со статическим набором данных, но разработаете схему для масштабируемости. Вы разработаете схему, которая позволит вам передавать в таблицу больше данных шины и при этом работать хорошо.
Вот предлагаемая схема для ключа строки:
[Автобусная компания/Автобусная линия/Метка времени, округленная до часа/Идентификатор автомобиля]. Каждая строка содержит данные за час, а каждая ячейка содержит несколько версий данных с отметкой времени.
Для этой лаборатории кода вы будете использовать одно семейство столбцов, чтобы упростить задачу. Вот пример того, как выглядят данные. Данные сортируются по ключу строки.
Ключ строки | cf:VehicleLocation.Latitude | cf:VehicleLocation.Longitude | ... |
MTA/M86-SBS/1496275200000/NYCT_5824 | 40.781212 @20:52:54.00 40.776163 @20:43:19.00 40.778714 @20:33:46.00 | -73.961942 @20:52:54.00 -73.946949 @20:43:19.00 -73.953731 @20:33:46.00 | ... |
MTA/M86-SBS/1496275200000/NYCT_5840 | 40.780664 @20:13:51.00 40.788416 @20:03:40.00 | -73.958357 @20:13:51.00 -73.976748 @20:03:40.00 | ... |
MTA/M86-SBS/1496275200000/NYCT_5867 | 40.780281 @20:51:45.00 40.779961 @20:43:15.00 40.788416 @20:33:44.00 | -73.946890 @20:51:45.00 -73.959465 @20:43:15.00 -73.976748 @20:33:44.00 | ... |
... | ... | ... | ... |
4. Создайте экземпляр, таблицу и семейство.
Далее вы создадите таблицу Cloud Bigtable.
Сначала создайте новый проект. Используйте встроенную Cloud Shell, которую можно открыть, нажав кнопку «Активировать Cloud Shell» в правом верхнем углу.
Установите следующие переменные среды, чтобы упростить копирование и вставку команд codelab:
INSTANCE_ID="bus-instance" CLUSTER_ID="bus-cluster" TABLE_ID="bus-data" CLUSTER_NUM_NODES=3 CLUSTER_ZONE="us-central1-c"
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
5. Импортируйте данные
Импортируйте набор файлов последовательностей для этой лаборатории кода из gs://cloud-bigtable-public-datasets/bus-data
выполнив следующие действия:
Включите Cloud Dataflow API, выполнив эту команду.
gcloud services enable dataflow.googleapis.com
Выполните следующие команды, чтобы импортировать таблицу.
NUM_WORKERS=$(expr 3 \* $CLUSTER_NUM_NODES) gcloud beta dataflow jobs run import-bus-data-$(date +%s) \ --gcs-location gs://dataflow-templates/latest/GCS_SequenceFile_to_Cloud_Bigtable \ --num-workers=$NUM_WORKERS --max-workers=$NUM_WORKERS \ --parameters bigtableProject=$GOOGLE_CLOUD_PROJECT,bigtableInstanceId=$INSTANCE_ID,bigtableTableId=$TABLE_ID,sourcePattern=gs://cloud-bigtable-public-datasets/bus-data/*
Контролируйте импорт
Вы можете отслеживать задание в пользовательском интерфейсе Cloud Dataflow . Кроме того, вы можете просмотреть нагрузку на свой экземпляр Cloud Bigtable с помощью пользовательского интерфейса мониторинга . Весь импорт займет 5 минут.
6. Получите код
git clone https://github.com/googlecodelabs/cbt-intro-java.git cd cbt-intro-java
Перейдите на Java 11, выполнив следующие команды:
sudo update-java-alternatives -s java-1.11.0-openjdk-amd64 && export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/
7. Выполните поиск
Первый запрос, который вы выполните, — это простой поиск строки. Данные по автобусу линии М86-СБС вы получите 1 июня 2017 года с 12:00 до 1:00. В это время на автобусной линии находится транспортное средство с идентификатором NYCT_5824
.
Имея эту информацию и зная структуру схемы (автобусная компания/автобусная линия/временная метка, округленная до часа/идентификатор транспортного средства), вы можете сделать вывод, что ключ строки:
MTA/M86-SBS/1496275200000/NYCT_5824
BusQueries.java
private static final byte[] COLUMN_FAMILY_NAME = Bytes.toBytes("cf");
private static final byte[] LAT_COLUMN_NAME = Bytes.toBytes("VehicleLocation.Latitude");
private static final byte[] LONG_COLUMN_NAME = Bytes.toBytes("VehicleLocation.Longitude");
String rowKey = "MTA/M86-SBS/1496275200000/NYCT_5824";
Result getResult =
table.get(
new Get(Bytes.toBytes(rowKey))
.addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
.addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME));
Результат должен содержать самое последнее местоположение автобуса в течение этого часа. Но вы хотите видеть все местоположения, поэтому установите максимальное количество версий в запросе на получение.
BusQueries.java
Result getResult =
table.get(
new Get(Bytes.toBytes(rowKey))
.setMaxVersions(Integer.MAX_VALUE)
.addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
.addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME));
В Cloud Shell выполните следующую команду, чтобы получить список широт и долгот для этой шины за час:
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=lookupVehicleInGivenHour
Вы можете скопировать и вставить значения широты и долготы в приложение MapMaker, чтобы визуализировать результаты. После нескольких слоев вам будет предложено создать бесплатную учетную запись. Вы можете создать учетную запись или просто удалить существующие слои. Эта лаборатория кода включает визуализацию каждого шага, если вы просто хотите следовать инструкциям. Вот результат этого первого запроса:
8. Выполните сканирование
Теперь давайте просмотрим все данные по автобусной линии за этот час. Код сканирования очень похож на код получения. Вы указываете сканеру начальную позицию, а затем указываете, что вам нужны только строки для линии шины M86-SBS в течение часа, обозначенного меткой времени 1496275200000.
BusQueries.java
Scan scan;
scan = new Scan();
scan.setMaxVersions(Integer.MAX_VALUE)
.addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
.addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME)
.withStartRow(Bytes.toBytes("MTA/M86-SBS/1496275200000"))
.setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/1496275200000"));
ResultScanner scanner = table.getScanner(scan);
Запустите следующую команду, чтобы получить результаты.
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=scanBusLineInGivenHour
Приложение Map Maker может отображать несколько списков одновременно, поэтому вы можете увидеть, какой из автобусов является транспортным средством из первого запущенного вами запроса.
Интересная модификация этого запроса заключается в просмотре данных по автобусной линии M86-SBS за весь месяц, и это очень легко сделать. Удалите временную метку из начальной строки и фильтр префикса, чтобы получить результат.
BusQueries.java
scan.withStartRow(Bytes.toBytes("MTA/M86-SBS/"))
.setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/"));
// Optionally, reduce the results to receive one version per column
// since there are so many data points.
scan.setMaxVersions(1);
Запустите следующую команду, чтобы получить результаты. (Будет длинный список результатов.)
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=scanEntireBusLine
Если скопировать результаты в MapMaker, можно просмотреть тепловую карту автобусного маршрута. Оранжевые точки обозначают остановки, а ярко-красные — начало и конец маршрута.
9. Внедряйте фильтры
Далее вы отфильтруете автобусы, идущие на восток, и автобусы, идущие на запад, и создадите для каждого отдельную тепловую карту.
BusQueries.java
Scan scan;
ResultScanner scanner;
scan = new Scan();
SingleColumnValueFilter valueFilter =
new SingleColumnValueFilter(
COLUMN_FAMILY_NAME,
Bytes.toBytes("DestinationName"),
CompareOp.EQUAL,
Bytes.toBytes("Select Bus Service Yorkville East End AV"));
scan.setMaxVersions(1)
.addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
.addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME);
scan.withStartRow(Bytes.toBytes("MTA/M86-SBS/"))
.setRowPrefixFilter(Bytes.toBytes("MTA/M86-SBS/"));
scan.setFilter(valueFilter);
scanner = table.getScanner(scan);
Запустите следующую команду, чтобы получить результаты для автобусов, идущих на восток.
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=filterBusesGoingEast
Чтобы автобусы шли на запад, измените строку в valueFilter:
BusQueries.java
SingleColumnValueFilter valueFilter =
new SingleColumnValueFilter(
COLUMN_FAMILY_NAME,
Bytes.toBytes("DestinationName"),
CompareOp.EQUAL,
Bytes.toBytes("Select Bus Service Westside West End AV"));
Запустите следующую команду, чтобы получить результаты для автобусов, идущих на запад.
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=filterBusesGoingWest
Автобусы едут на восток
Автобусы едут на запад
Сравнивая две тепловые карты, вы можете увидеть различия в маршрутах, а также заметить разницу в темпе. Одна из интерпретаций данных заключается в том, что на маршруте, идущем на запад, автобусы останавливаются чаще, особенно при въезде в Центральный парк. А в автобусах, идущих на восток, вы не увидите много узких мест.
10. Выполните сканирование нескольких диапазонов.
В последнем запросе вы рассмотрите случай, когда вас интересует множество автобусных линий в определенной области:
BusQueries.java
private static final String[] MANHATTAN_BUS_LINES = {"M1","M2","M3",...
Scan scan;
ResultScanner scanner;
List<RowRange> ranges = new ArrayList<>();
for (String busLine : MANHATTAN_BUS_LINES) {
ranges.add(
new RowRange(
Bytes.toBytes("MTA/" + busLine + "/1496275200000"), true,
Bytes.toBytes("MTA/" + busLine + "/1496275200001"), false));
}
Filter filter = new MultiRowRangeFilter(ranges);
scan = new Scan();
scan.setFilter(filter);
scan.setMaxVersions(Integer.MAX_VALUE)
.addColumn(COLUMN_FAMILY_NAME, LAT_COLUMN_NAME)
.addColumn(COLUMN_FAMILY_NAME, LONG_COLUMN_NAME);
scan.withStartRow(Bytes.toBytes("MTA/M")).setRowPrefixFilter(Bytes.toBytes("MTA/M"));
scanner = table.getScanner(scan);
Запустите следующую команду, чтобы получить результаты.
mvn package exec:java -Dbigtable.projectID=$GOOGLE_CLOUD_PROJECT \ -Dbigtable.instanceID=$INSTANCE_ID -Dbigtable.table=$TABLE_ID \ -Dquery=scanManhattanBusesInGivenHour
11. Завершить
Наведите порядок, чтобы избежать обвинений
Чтобы избежать взимания платы с вашей учетной записи Google Cloud Platform за ресурсы, используемые в этой лаборатории кода, вам следует удалить свой экземпляр.
gcloud bigtable instances delete $INSTANCE_ID
Что мы рассмотрели
- Проектирование схемы
- Настройка экземпляра, таблицы и семейства
- Импорт файлов последовательностей с потоком данных
- Запрос с поиском, сканированием, сканированием с фильтром и многодиапазонным сканированием
Следующие шаги
- Подробнее о Cloud Bigtable можно узнать в документации .
- Опробуйте другие функции Google Cloud Platform самостоятельно. Посмотрите наши уроки .
- Узнайте, как отслеживать данные временных рядов с помощью интеграции OpenTSDB.