O LindormTable roteia automaticamente os dados entre o armazenamento quente e o frio conforme o tempo de retenção. Defina um limite de tempo em uma tabela ou família de colunas: dados mais recentes que o limite permanecem no armazenamento quente, enquanto dados mais antigos são arquivados no armazenamento frio durante a compactação.
Como funciona
Ao gravar dados em uma tabela, eles são direcionados inicialmente para o armazenamento quente (tipo Standard ou Performance). Periodicamente, o Lindorm executa uma operação de compaction em segundo plano. Durante essa compactação, o sistema compara o timestamp de cada linha com o limite configurado (COLD_BOUNDARY para HBase Shell e API Java, ou CHS para Lindorm SQL). Linhas cujos timestamps ultrapassam esse limite são movidas para o armazenamento frio.
O arquivamento é assíncrono, ou seja, a migração dos dados não ocorre no exato momento em que atingem a idade definida. Para forçar uma transferência imediata, execute major_compact manualmente.
Por padrão, o timestamp de uma linha corresponde à hora do sistema no momento da gravação. Caso utilize a API ApsaraDB for HBase for Java, especifique um timestamp personalizado. Consulte Considerações operacionais para entender como timestamps personalizados afetam o roteamento de armazenamento.
Pré-requisitos
Antes de começar, verifique se você atende aos seguintes requisitos:
O recurso de armazenamento frio está ativado. Para mais informações sobre como ativar o recurso, consulte Enable Capacity storage.
Versão 2.1.8 ou superior do LindormTable instalada. Para mais detalhes, consulte Release notes of LindormTable e Upgrade the minor engine version of a Lindorm instance.
-
Conexão estabelecida com o LindormTable por meio de uma das opções abaixo:
Apache HBase Shell. Para mais informações, consulte Use Lindorm Shell to connect to LindormTable.
API ApsaraDB for HBase for Java. Para mais informações, consulte Use ApsaraDB for HBase API for Java to develop applications.
lindorm-cli. Para mais informações, consulte Use lindorm-cli to connect to and use LindormTable.
Atributo
STORAGE_POLICYda tabela ou família de colunas de destino definido com um valor diferente deCOLD. Para mais informações, consulte Configure cold storage.
Definir o limite entre dados quentes e frios
Escolha o método correspondente ao seu cliente.
Usar Apache HBase Shell
Etapa 1: Criar uma tabela com limite
HBase(main):002:0> create 'chsTable', {NAME=>'f', COLD_BOUNDARY=>'86400'}
|
Parâmetro |
Descrição |
|
|
Família de colunas a ser configurada. |
|
|
Limite de tempo em segundos. Dados armazenados por um período superior a este valor são arquivados no armazenamento frio durante a compactação. Por exemplo, |
Etapa 2 (opcional): Alterar o limite
Após alterar o limite, a movimentação de dados entre os armazenamentos frio e quente ocorre na próxima compactação. Para acionar uma transferência imediata, execute major_compact 'chsTable'.
HBase(main):005:0> alter 'chsTable', {NAME=>'f', COLD_BOUNDARY=>'42300'}
Etapa 3 (opcional): Desativar a separação de dados quentes e frios
Ao desativar a separação de dados quentes e frios, os dados retornam do armazenamento frio para o quente durante a próxima compactação. Para acionar uma transferência imediata, execute major_compact 'chsTable'.
HBase(main):004:0> alter 'chsTable', {NAME=>'f', COLD_BOUNDARY=>""}
Usar API ApsaraDB for HBase for Java
Etapa 1: Criar uma tabela com limite
Admin admin = connection.getAdmin();
TableName tableName = TableName.valueOf("chsTable");
HTableDescriptor descriptor = new HTableDescriptor(tableName);
HColumnDescriptor cf = new HColumnDescriptor("f");
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, "86400");
descriptor.addFamily(cf);
admin.createTable(descriptor);
Etapa 2 (opcional): Alterar o limite
Após alterar o limite, a movimentação de dados entre os armazenamentos frio e quente ocorre na próxima compactação.
HTableDescriptor descriptor = admin
.getTableDescriptor(tableName);
HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, "86400");
admin.modifyTable(tableName, descriptor);
Etapa 3 (opcional): Desativar a separação de dados quentes e frios
Ao desativar a separação de dados quentes e frios, os dados retornam do armazenamento frio para o quente durante a próxima compactação.
HTableDescriptor descriptor = admin
.getTableDescriptor(tableName);
HColumnDescriptor cf = descriptor.getFamily("f".getBytes());
cf.setValue(AliHBaseConstants.COLD_BOUNDARY, null);
admin.modifyTable(tableName, descriptor);
Usar lindorm-cli (Lindorm SQL)
Etapa 1: Criar uma tabela com limite
Utilize a instrução CREATE TABLE:
CREATE TABLE dt (
p1 integer, p2 integer, c1 varchar, c2 bigint,
constraint pk primary key(p1 desc))
WITH (COMPRESSION = 'ZSTD', CHS = '86400', CHS_L2 = 'storagetype=COLD');
Ou ative a separação de dados quentes e frios em uma tabela existente usando ALTER TABLE:
-- Enable hot and cold data separation on an existing table.
-- The table was created without CHS:
-- CREATE TABLE dt (p1 integer, p2 integer, c1 varchar, c2 bigint,
-- constraint pk primary key(p1 desc)) WITH (COMPRESSION = 'ZSTD');
ALTER TABLE dt SET 'CHS' ='86400', 'CHS_L2' = 'storagetype=COLD';
|
Parâmetro |
Descrição |
|
|
Limite de tempo em segundos. Dados armazenados por um período superior a este valor são arquivados no armazenamento frio durante a compactação. Por exemplo, |
|
|
Atributo de armazenamento de camada 2. Defina como |
|
|
Algoritmo de compressão aplicado a todos os dados da tabela. O valor não diferencia maiúsculas de minúsculas. Valor padrão: |
Etapa 2 (opcional): Alterar o limite
Após alterar o limite, a movimentação de dados entre os armazenamentos frio e quente ocorre na próxima compactação. Para acionar uma transferência imediata, execute major_compact na tabela. Para consultar a sintaxe, veja ALTER TABLE.
ALTER TABLE dt SET 'CHS'='1000';
Etapa 3 (opcional): Desativar a separação de dados quentes e frios
Ao desativar a separação de dados quentes e frios, os dados retornam do armazenamento frio para o quente durante a próxima compactação. Para acionar uma transferência imediata, execute major_compact na tabela.
ALTER TABLE dt SET 'CHS'='', 'CHS_L2' = '';
Gravar dados
Grave dados em uma tabela com separação quente/frio da mesma forma que em uma tabela ampla padrão. Os dados são sempre gravados primeiro no armazenamento quente e movidos para o armazenamento frio na próxima compactação, assim que ultrapassarem o limite configurado.
Se utilizar a API ApsaraDB for HBase for Java, defina um timestamp personalizado em cada linha. Esse timestamp determina em qual camada de armazenamento a linha será alocada, e não o horário da operação de gravação em si. Consulte Comportamento de timestamp personalizado para obter detalhes.
Consultar dados
O LindormTable armazena dados quentes e frios na mesma tabela, permitindo acesso a todos os dados por meio de uma única consulta. Por padrão, uma consulta sem intervalo de tempo pode ler o armazenamento frio, e o throughput é limitado pela especificação desse armazenamento.
Para restringir uma consulta apenas ao armazenamento quente, utilize uma das opções a seguir:
Parâmetro
HOT_ONLY(Apache HBase Shell e API Java)Hint
_l_hot_only_(Lindorm SQL)Parâmetro
TimeRange, configurado com um intervalo dentro da janela de dados quentes
Se um campo em uma linha do armazenamento frio for atualizado, o campo atualizado é armazenado no armazenamento quente, enquanto os dados originais permanecem no armazenamento frio. Consultas com HOT_ONLY ou um TimeRange restrito retornam apenas o campo atualizado, e não a linha completa. Para retornar a linha inteira, faça a consulta sem HOT_ONLY e certifique-se de que o TimeRange cubra o período desde a inserção inicial até a atualização mais recente. Evite atualizar dados armazenados no armazenamento frio.
Consultas GET
Apache HBase Shell
-- Query all data (may include cold storage)
HBase(main):013:0> get 'chsTable', 'row1'
-- Query only hot storage
HBase(main):015:0> get 'chsTable', 'row1', {HOT_ONLY=>true}
-- Query by time range (UNIX timestamp in milliseconds)
HBase(main):016:0> get 'chsTable', 'row1', {TIMERANGE => [0, 1568203111265]}
O parâmetro TimeRange aceita timestamps UNIX em milissegundos desde 1º de janeiro de 1970, 00:00:00 UTC. O Lindorm compara o TimeRange com o COLD_BOUNDARY para determinar quais camadas de armazenamento devem ser lidas.
API ApsaraDB for HBase for Java
// Query all data (may include cold storage)
Get get = new Get("row1".getBytes());
System.out.println("result: " + table.get(get));
// Query only hot storage
get = new Get("row1".getBytes());
get.setAttribute(AliHBaseConstants.HOT_ONLY, Bytes.toBytes(true));
// Query by time range
get = new Get("row1".getBytes());
get.setTimeRange(0, 1568203111265);
Lindorm SQL
SELECT /*+ _l_hot_only_ */ * FROM dt WHERE pk IN (1, 2, 3);
Consultas SCAN
Apenas o Apache HBase Shell e a API ApsaraDB for HBase for Java suportam consultas SCAN de intervalo. Sem o uso de HOT_ONLY ou de um TimeRange que abranja exclusivamente dados quentes, o Lindorm lê ambas as camadas de armazenamento e mescla os resultados.
Apache HBase Shell
-- Scan all data (may include cold storage)
Lindorm(main):017:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9'}
-- Scan only hot storage
Lindorm(main):018:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9', HOT_ONLY=>true}
-- Scan by time range
Lindorm(main):019:0> scan 'chsTable', {STARTROW =>'row1', STOPROW=>'row9', TIMERANGE => [0, 1568203111265]}
API ApsaraDB for HBase for Java
TableName tableName = TableName.valueOf("chsTable");
Table table = connection.getTable(tableName);
// Scan all data (may include cold storage)
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
System.out.println("scan result:" + result);
}
// Scan only hot storage
scan = new Scan();
scan.setAttribute(AliLindormConstants.HOT_ONLY, Bytes.toBytes(true));
// Scan by time range
scan = new Scan();
scan.setTimeRange(0, 1568203111265);
Priorizar dados quentes em consultas SCAN
Em consultas SCAN que recuperam dados ordenados — como todos os pedidos ou mensagens de um usuário — o LindormTable normalmente lê tanto o armazenamento quente quanto o frio, o que aumenta o tempo de resposta. Ative a priorização de dados quentes com COLD_HOT_MERGE para varrer o armazenamento quente primeiro. O armazenamento frio só é lido quando o número de linhas no armazenamento quente for inferior à quantidade mínima de linhas de dados a serem consultadas.
O parâmetro COLD_HOT_MERGE está disponível apenas no Apache HBase Shell e na API ApsaraDB for HBase for Java.
Apache HBase Shell
Lindorm(main):002:0> scan 'chsTable', {COLD_HOT_MERGE=>true}
|
Parâmetro |
Valor |
Descrição |
|
|
|
Varre o armazenamento quente primeiro. O armazenamento frio é lido apenas quando o número de linhas no armazenamento quente é menor que a quantidade mínima de linhas de dados a serem consultadas. |
|
|
|
Desativa a priorização de dados quentes. |
API ApsaraDB for HBase for Java
scan = new Scan();
scan.setAttribute(AliHBaseConstants.COLD_HOT_MERGE, Bytes.toBytes(true));
scanner = table.getScanner(scan);
Notas de uso
-
A ordem das chaves de linha não é garantida. Quando
COLD_HOT_MERGEestá ativado, as linhas quentes são retornadas antes das frias. O conjunto de resultados contém linhas quentes e frias classificadas separadamente por chave de linha, portanto, o resultado geral não é classificado globalmente por chave de linha.// Normal scan (lexicographic order) HBase(main):001:0> scan 'chsTable' ROW COLUMN+CELL coldRow column=f:value, timestamp=1560578400000, value=cold_value hotRow column=f:value, timestamp=1565848800000, value=hot_value 2 row(s) // With COLD_HOT_MERGE=true (hot rows first) HBase(main):002:0> scan 'chsTable', {COLD_HOT_MERGE=>true} ROW COLUMN+CELL hotRow column=f:value, timestamp=1565848800000, value=hot_value coldRow column=f:value, timestamp=1560578400000, value=cold_value 2 row(s)Para manter uma ordem significativa em sua aplicação, projete chaves de linha que codifiquem informações de ordenação — por exemplo, uma chave composta pelo ID do cliente e pelo horário de criação do pedido.
Linhas com campos atualizados aparecem duas vezes. Se uma linha no armazenamento frio foi parcialmente atualizada, ela abrange tanto o armazenamento quente quanto o frio. Com
COLD_HOT_MERGEativado, os resultados incluem duas entradas para a mesma chave de linha: uma do armazenamento quente e outra do frio.
Considerações operacionais
Comportamento de timestamp personalizado
O timestamp definido em uma linha determina em qual camada de armazenamento ela será alocada, e não o momento da gravação. Exemplos:
Uma linha gravada com um timestamp três dias no futuro será arquivada no armazenamento frio três dias depois de uma linha gravada com o timestamp atual.
Uma linha gravada com um timestamp três dias no passado, quando o limite está definido para três dias, é arquivada no armazenamento frio de forma assíncrona logo após a gravação, e não após mais três dias.
Utilize timestamps personalizados com cautela. Linhas gravadas com timestamps passados podem ser movidas para o armazenamento frio imediatamente após a próxima compactação, o que pode gerar comportamentos inesperados se seus padrões de consulta presumirem que dados gravados recentemente estão sempre no armazenamento quente.
Dados frios acessados frequentemente
Se as consultas acessarem consistentemente o armazenamento frio, verifique se o valor de COLD_BOUNDARY (ou CHS) corresponde aos seus padrões reais de acesso. O throughput do armazenamento frio é limitado pela especificação dessa camada, portanto, o acesso frequente a dados frios degrada o desempenho das consultas.
Perguntas frequentes
Após atualizar uma linha fria, ela ainda é considerada dado frio?
Não. A atualização de uma linha renova seu timestamp, fazendo com que o LindormTable a trate como dado quente.
Defini HOT_ONLY, mas minha consulta ainda retorna dados frios. Por quê?
Os dados são arquivados no armazenamento frio de forma assíncrona durante a compactação. Algumas linhas antigas o suficiente para serem consideradas frias podem não ter sido arquivadas ainda, permanecendo fisicamente no armazenamento quente e sendo retornadas pelas consultas.
Para excluir esses dados, especifique um intervalo de tempo explícito além de HOT_ONLY. Utilize os hints _l_ts_min_ e _l_ts_max_ no Lindorm SQL para definir a janela com precisão:
-- _l_ts_min_: difference between current time and the hot/cold boundary
-- _l_ts_max_: current system time
-- Both values must use the same unit.
SELECT /*+ _l_hot_only_(true), _l_ts_min_(1000), _l_ts_max_(2001) */ * FROM test WHERE p1>1;
Minha consulta atinge o tempo limite mesmo com HOT_ONLY e TimeRange especificados. Por quê?
Isso geralmente ocorre após migrar dados para uma tabela ou ativar a separação de dados quentes e frios pela primeira vez. Uma grande quantidade de dados frios ainda reside fisicamente no armazenamento quente porque a compactação ainda não foi executada. Execute major compaction na tabela para forçar a movimentação dos dados. Para consultar a sintaxe, veja ALTER TABLE.