Agregar valores no momento da gravação

Se você quiser agregar seus dados no Bigtable no momento da gravação, use agregações. Os agregados são células da tabela do Bigtable que agregar valores de célula à medida que os dados são gravados. Quando você adiciona um novo valor, função de agregação mescla o valor com o valor agregado que já está na célula. Outros bancos de dados se referem a funcionalidades semelhantes como contadores ou contadores distribuídos.

É possível trabalhar com agregados usando o CLI cbt e bibliotecas de cliente do Bigtable para C++, Go e Java.

Este documento fornece uma visão geral dos agregados e mostra como criar um de colunas agregadas e fornece exemplos que mostram como adicionar um valor a uma célula agregada. Antes de ler este documento, você precisa conhecer a visão geral do Bigtable e as gravações .

Quando usar agregados

Os dados agregados do Bigtable são úteis nas situações em que você precisa dados de uma entidade de forma agregada, e não como pontos de dados individuais. Se você estiver migrando para o Bigtable de bancos de dados como o Apache Cassandra ou o Redis, use os agregados do Bigtable em lugares em que você usava contadores nesses sistemas.

Intervalos de tempo

É possível usar intervalos de tempo para obter valores agregados para um período de tempo, como por hora, dia ou semana. Em vez de agregar dados antes ou depois de serem gravados na tabela, adicione novos valores para agregar células na tabela.

Por exemplo, se você gerencia um serviço que ajuda instituições de caridade a arrecadar dinheiro, pode querem saber a quantidade de doações on-line por dia para cada campanha, mas você não precisam saber a hora exata de cada doação ou o valor por hora. Em na tabela, as chaves de linha representam os IDs da instituição de caridade e você cria uma coluna agregada família chamada donations. Os qualificadores de coluna na linha são IDs de campanha.

À medida que cada doação recebida em um determinado dia para uma campanha é recebida, ela é adicionada à soma na célula agregada na coluna desse dia. Cada solicitação de adição para a célula usa um carimbo de data/hora truncado para o início do dia, de modo que, na prática, cada solicitação tem o mesmo carimbo de data/hora. O truncamento dos carimbos de data/hora garante que todas as doações daquele dia sejam adicionadas à mesma célula. No dia seguinte, todas as suas solicitações vão para uma nova célula, usando carimbos de data/hora truncados até a nova data, e esse padrão continua.

Dependendo do caso de uso, é possível criar novas colunas para o novo agregados. Dependendo do número de buckets que você planeja acumular, considere um design de chave de linha diferente.

Para mais informações sobre intervalos de tempo, consulte Projeto de esquema para série temporal. dados.

Simplificação dos fluxos de trabalho

Com os agregados, você pode agrupar seus dados na tabela do Bigtable sem precisar usar nenhum software de processamento de streaming ou ETL para agregá-los antes ou depois de gravar no Bigtable. Por exemplo, se o aplicativo já publicou mensagens no Pub/Sub e usou o Dataflow para ler as mensagens e agregar os dados antes de gravar no Bigtable, você pode enviar os dados diretamente para células agregadas no Bigtable.

Grupos de colunas agregados

Para criar e atualizar células agregadas, é necessário ter uma ou mais funções de agregação grupos de colunas em sua tabela - grupos de colunas que contêm apenas dados agregados células. Você pode criar famílias de colunas de agregação ao criar uma tabela ou adicionar uma família de colunas de agregação a uma tabela que já está em uso. Quando você cria a coluna família, você especifica o tipo de agregação, como soma.

Não é possível converter uma família de colunas que contém dados não agregados em uma família de colunas agregada. As colunas em famílias de colunas agregadas não podem conter células não agregadas, e as famílias de colunas padrão não podem conter células agregadas.

Para criar uma nova tabela com um grupo de colunas agregado, consulte Criar um tabela. Para adicionar um grupo de colunas agregado a uma tabela, consulte Adicionar grupos de colunas.

Tipos de agregação

O Bigtable é compatível com os seguintes tipos de agregação:

Soma

Quando você adiciona um valor a uma célula agregada de soma (sum), o valor da célula é substituído pela soma do valor recém-adicionado e do valor da célula atual. O tipo de entrada aceito para somas é Int64.

Mínimo

Quando você adiciona um valor a uma célula agregada mínima (min), o valor da célula é substituído pelo valor mais baixo entre o valor recém-adicionado e o valor atual valor da célula. O tipo de entrada com suporte para o valor mínimo é Int64.

Máximo

Quando você adiciona um valor a uma célula de agregação máxima (max), o valor da célula é substituído pelo valor mais alto entre o valor recém-adicionado e o valor atual valor da célula. O tipo de entrada com suporte para max é Int64.

HyperLogLog (HLL)

Quando você adiciona um valor a uma célula agregada de HLL (inthll), o valor é adicionado a um conjunto probabilístico de todos os valores adicionados desde a redefinição mais recente (a criação da célula ou a exclusão dos dados dela). O valor da célula representa o estado desse conjunto. Para informações mais gerais sobre o algoritmo HLL, consulte HyperLogLog.

É possível ler valores de HLL usando a biblioteca Zetasketch. Para mais informações, consulte o repositório do GitHub do Zetasketch. O O tipo de entrada compatível com HLL é BYTES.

Carimbos de data/hora

Uma célula agregada é definida pela chave de linha, pelo grupo de colunas, pelo qualificador de coluna e pelo carimbo de data/hora. O mesmo carimbo de data/hora é usado sempre que você adiciona dados à célula. Se você enviar um valor para a mesma chave de linha, grupo de colunas e qualificador de coluna, mas com uma carimbo de data/hora diferente, uma nova célula agregada é criada na coluna.

Uma solicitação de adição enviada para uma célula agregada precisa incluir um carimbo de data/hora.

Tipo de entrada

O tipo de entrada do valor na solicitação de adição precisa corresponder ao tipo de entrada usado para criar a família de colunas. Por exemplo, se você enviar um valor de string para um grupo de colunas configurado para Int64, a solicitação será rejeitada.

AddToCell

Uma solicitação de adição envia uma mutação AddToCell na API Bigtable Data. Por outro lado, uma solicitação de gravação não agregada envia uma mutação SetCell. Para mais mais informações, consulte a API Data como referência. As operações AddToCell estão sujeitas aos mesmos limites de operações que outras mutações de tabela.

Em uma tabela replicada, uma célula agregada converge para o mesmo valor final todos os clusters no atraso de replicação atual. O valor final agregado de todas as mutações AddToCell enviadas a essa célula em todos os clusters desde a última operação de exclusão ou desde que a célula foi criada.

Coleta de lixo

As células agregadas são tratadas como qualquer outra célula durante a coleta de lixo: se uma célula for marcada para exclusão, a exclusão será replicada para todos os clusters na instância. Para mais informações, consulte Replicação e lixo Google Cloud. Se uma solicitação de adição for enviada para uma célula agregada que foi removida pela coleta de lixo, uma nova célula agregada será criada.

Adicionar exemplos de solicitação

Os exemplos a seguir mostram como adicionar um valor a uma célula agregada. O são adicionados a uma soma em um grupo de colunas que espera o tipo de entrada Int64.

cbt

cbt addtocell TABLE_ID ROW_KEY FAMILY_NAME:COLUMN_QUALIFER=VALUE@TIMESTAMP

Substitua:

  • TABLE_ID: identificador permanente da tabela;
  • ROW_KEY: a chave de linha
  • FAMILY_NAME: o nome do grupo de colunas agregado
  • COLUMN_QUALIFIER: um identificador da coluna
  • VALUE: o valor a ser adicionado à célula.
  • TIMESTAMP: um carimbo de data/hora Unix em microssegundos, como 1710868850000000

Exemplo:

cbt addtocell mobile-data device-1 updates:week12=100@1710868850000000

Go

Para aprender a instalar e usar a biblioteca de cliente para o Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/bigtable"
)

func writeAggregate(w io.Writer, projectID, instanceID string, tableName string) error {
	// projectID := "my-project-id"
	// instanceID := "my-instance-id"
	// tableName := "mobile-time-series"

	ctx := context.Background()
	client, err := bigtable.NewClient(ctx, projectID, instanceID)
	if err != nil {
		return fmt.Errorf("bigtable.NewClient: %w", err)
	}
	defer client.Close()
	tbl := client.Open(tableName)
	columnFamilyName := "view_count"
	viewTimestamp, err := time.Parse(time.RFC3339, "2024-03-13T12:41:34Z")
	if err != nil {
		return err
	}
	hourlyBucket := viewTimestamp.Truncate(time.Hour)

	mut := bigtable.NewMutation()
	mut.AddIntToCell(columnFamilyName, "views", bigtable.Time(hourlyBucket), 1)

	rowKey := "page#index.html"
	if err := tbl.Apply(ctx, rowKey, mut); err != nil {
		return fmt.Errorf("Apply: %w", err)
	}

	fmt.Fprintf(w, "Successfully wrote row: %s\n", rowKey)
	return nil
}

Java

Para aprender a instalar e usar a biblioteca de cliente para o Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, acesse Configurar a autenticação para bibliotecas de cliente.


import com.google.cloud.bigtable.data.v2.BigtableDataClient;
import com.google.cloud.bigtable.data.v2.models.RowMutation;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

public class WriteAggregate {
  private static final String COUNT_COLUMN_FAMILY_NAME = "view_count";
  private static final long MICROS_PER_MILLI = 1000;

  public static void writeAggregate(String projectId, String instanceId, String tableId) {
    // String projectId = "my-project-id";
    // String instanceId = "my-instance-id";
    // String tableId = "page-view-counter";

    try (BigtableDataClient dataClient = BigtableDataClient.create(projectId, instanceId)) {

      String rowKey = "page#index.html";
      Instant viewTimestamp = Instant.parse("2024-03-13T12:41:34.123Z");

      // Bucket the views for an hour into a single count, giving us an hourly view count for a
      // given page.
      Instant hourlyBucket = viewTimestamp.truncatedTo(ChronoUnit.HOURS);
      long hourlyBucketMicros = hourlyBucket.toEpochMilli() * MICROS_PER_MILLI;

      RowMutation rowMutation =
          RowMutation.create(tableId, rowKey)
              .addToCell(COUNT_COLUMN_FAMILY_NAME, "views", hourlyBucketMicros, 1);

      dataClient.mutateRow(rowMutation);
      System.out.printf("Successfully wrote row %s", rowKey);

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

A seguir