Agregar valores no momento da gravação

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

O tipo de agregação que o Bigtable oferece é a soma. Quando você adiciona um valor a uma célula de soma agregada, o valor da célula é substituído pela soma do valor recém-adicionado e do valor da célula atual.

Durante a visualização, é possível trabalhar com agregados usando a CLI cbt e as bibliotecas de cliente do Bigtable para C++, Go e Java.

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

Quando usar agregados

Os agregados do Bigtable são úteis para situações em que você considera dados de uma entidade agregados 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, poderá usar os agregados do Bigtable em locais onde anteriormente dependia de contadores nesses sistemas.

Intervalos de tempo

É possível usá-los para obter valores agregados de um período, como uma hora, um dia ou uma semana. Em vez de agregar dados antes ou depois de serem gravados na tabela, adicione novos valores às células na tabela.

Por exemplo, se você administra um serviço que ajuda instituições de caridade a arrecadar dinheiro, convém saber a quantidade de doações on-line por dia para cada campanha, mas não precisa saber o horário exato de cada doação ou o valor por hora. Na sua tabela, as chaves de linha representam os IDs de instituição de caridade, e você cria um grupo de colunas agregado chamado donations. Os qualificadores de coluna na linha são IDs de campanhas.

Como cada valor de doação recebido em um determinado dia para uma campanha é recebido, ele é adicionado à soma na célula agregada da coluna referente a esse dia. Cada solicitação de adição à célula usa um carimbo de data/hora truncado no início do dia, de modo que, na verdade, cada solicitação tenha o mesmo carimbo de data/hora. Truncar os carimbos de data/hora garante que todas as doações desse 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 que são truncados até a nova data, e esse padrão continua.

Dependendo do seu caso de uso, você pode optar por criar novas colunas para os novos agregadores. Para mais informações sobre intervalos de tempo, consulte Projeto de esquema para dados de série temporal.

Fluxos de trabalho otimizados

Os agregados permitem agregar os dados na tabela do Bigtable sem precisar usar nenhum software de ETL ou processamento de streaming para agregar os dados antes ou depois de gravá-los no Bigtable. Por exemplo, se o aplicativo publicou mensagens anteriormente no Pub/Sub e usou o Dataflow para ler as mensagens e agregar os dados antes de gravá-los no Bigtable, será possível enviar os dados diretamente para agregar as células no Bigtable.

Grupos de colunas agregadas

Para criar e atualizar células agregadas, você precisa ter um ou mais grupos de colunas agregadas na tabela, grupos de colunas que contenham apenas células agregadas. É possível criá-las ao criar uma tabela ou adicionar um grupo de colunas agregadas a uma tabela que já esteja em uso. Ao criar o grupo de colunas, você especifica o tipo de agregação, como soma.

Não é possível converter um grupo de colunas que contenha dados não agregados em um grupo de colunas agregadas. As colunas em grupos de colunas de agregação não podem conter células não agregadas, e os grupos de colunas padrão não podem conter células agregadas.

Para criar uma nova tabela com um grupo de colunas de agregação, consulte Criar uma tabela. Para adicionar um grupo de colunas agregadas a uma tabela, consulte Adicionar grupos de colunas.

Tipos de agregação

O Bigtable oferece suporte ao tipo de agregação sum. O tipo de entrada com suporte para somas é Int64.

Timestamps

Uma célula agregada é definida por chave de linha, grupo de colunas, qualificador de coluna e carimbo de data/hora. Use o mesmo carimbo de data/hora sempre que adicionar dados à célula. Se você enviar um valor para a mesma chave de linha, grupo de colunas e qualificador de coluna, mas com um carimbo de data/hora diferente, uma nova célula agregada será criada na coluna.

Uma solicitação de adição enviada a 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 com que o grupo de colunas é criado. 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 informações, consulte a referência da API Data. 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 total em todos os clusters dentro do atraso atual da replicação. O valor total é o agregado de todas as mutações AddToCell enviadas para essa célula em todos os clusters desde a última operação de exclusão ou desde que a célula foi criada.

Adicionar exemplos de solicitações

Os exemplos a seguir mostram como adicionar um valor a uma célula agregada. Os exemplos 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 de agregação.
  • COLUMN_QUALIFIER: um identificador da coluna.
  • VALUE: o valor a ser adicionado à célula
  • TIMESTAMP: um carimbo de data/hora do Unix em microssegundos, como 1710868850000000

Exemplo:

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

Go

Para saber como 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 saber como 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