Tabelas largas muito grandes podem gerar pontos críticos de armazenamento e degradar o desempenho das consultas quando todos os dados ficam concentrados em um único shard de índice. A indexação por partição resolve esse problema ao dividir um índice de busca em partições menores e gerenciadas independentemente. Ao criar um índice de busca, especifique uma política de particionamento para que o servidor distribua os dados automaticamente. Durante as consultas, o sistema aplica a poda de partições para varrer apenas aquelas que contêm dados correspondentes.
Duas políticas estão disponíveis:
Particionamento por hash — direciona linhas para partições aplicando hash a uma coluna de chave de partição. Consultas de igualdade nessa coluna acionam uma poda precisa de partições.
Particionamento por tempo — agrupa registros por intervalo de tempo. O sistema cria novas partições automaticamente em um ciclo contínuo e exclui as expiradas com base em uma política de Time to Live (TTL).
Pré-requisitos
Antes de começar, verifique se você já:
Escolha uma política de particionamento
Use esta tabela para selecionar a política mais adequada à sua carga de trabalho antes de criar um índice.
|
Particionamento por hash |
Particionamento por tempo |
|
|
Mais indicado para |
Consultas de igualdade em colunas de alta cardinalidade (ID de dispositivo, ID de loja) |
Dados de séries temporais com consultas de intervalo em uma coluna de timestamp (IoV, registros de pedidos, logs de mensagens) |
|
Poda de partições |
Acionada apenas por condições de igualdade ( |
Acionada por condições de intervalo de tempo. Varre apenas as partições que cobrem o período especificado. |
|
Ciclo de vida dos dados |
As partições persistem; não há TTL nativo |
Partições criadas automaticamente em ciclo contínuo; partições antigas excluídas por TTL |
|
Alteração da chave de partição |
Não permitida após a criação do índice |
Não aplicável |
|
Limitações |
Até três níveis de aninhamento; incompatível com particionamento por tempo |
Exige uma coluna de timestamp no índice |
Configure uma tabela de teste
Todos os exemplos deste tópico usam a tabela a seguir. Crie-a antes de executar os exemplos.
CREATE TABLE IF NOT EXISTS search_table (
user_id BIGINT,
storeId VARCHAR,
goodsId VARCHAR,
goodsPrice SMALLINT,
orderTime BIGINT,
info VARCHAR,
PRIMARY KEY (user_id ASC)
);
Particionamento por hash
O particionamento por hash direciona linhas para partições aplicando hash à chave de partição. Linhas com valores de chave idênticos sempre permanecem no mesmo grupo de partições; assim, uma consulta de igualdade nessa chave varre apenas as partições relevantes.
Não é possível alterar a configuração de partição por hash após a criação do índice. Estime o volume de dados e a quantidade desejada de partições antes de criar o índice.
Dimensione as partições corretamente
Cada partição deve armazenar entre 50 milhões e 100 milhões de registros, com tamanho de armazenamento entre 30 GB e 50 GB. A quantidade padrão de partições corresponde ao dobro do número de nós de busca.
Crie um índice com partição por hash
Padrão (particionamento pela chave primária)
Sem a cláusula PARTITION BY, o índice particiona os dados pela chave primária da tabela larga.
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice);
Particionamento por uma coluna específica
Particione por storeId com 64 partições. Use esta opção quando as consultas sempre incluírem uma condição de igualdade em storeId.
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice)
PARTITION BY hash(storeId) PARTITIONS 64;
Use o particionamento multinível para corrigir distorção de dados
Se a chave primária de partição causar distribuição desigual dos dados (pontos críticos), adicione uma chave secundária de partição para distribuir os dados uniformemente entre as partições.
Requer a versão 2.8.1 ou posterior do mecanismo de tabela larga.
Requer a versão 3.9.22 ou posterior do mecanismo de busca.
O particionamento multinível é incompatível com o particionamento por tempo.
Como funciona
Cada chave de partição recebe um salt_factor — um inteiro pequeno que controla a granularidade do hash dessa chave. O número total de partições deve ser uma potência de 2 (2^N), e a soma de todos os valores de salt_factor deve ser igual a N.
Por exemplo, com 2 bilhões de registros e uma meta de 50 milhões de registros por partição, são necessárias aproximadamente 40 partições. Arredonde para cima para 64 (2^6), de modo que N = 6 e a soma dos fatores de salt seja 6.
Compromisso: Aumentar o salt_factor de uma chave melhora a distribuição dos dados nessa dimensão, mas reduz a precisão da poda ao consultar por uma chave diferente. Por exemplo, se storeId tiver salt_factor=2, consultas apenas em storeId reduzem a varredura a 1/4 (1/2^2) de todas as partições. Aumentar para salt_factor=3 reduz a varredura a 1/8 de todas as partições, mas deixa menos espaço para outras chaves contribuírem com a distribuição.
Exemplo de partição por hash multinível
Particione por storeId (salt_factor=2) e goodsId (salt_factor=4), com 64 partições no total. Linhas com o mesmo valor de storeId, mas valores diferentes de goodsId, são distribuídas por 1/4 de todas as partições.
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice)
PARTITION BY hash(storeId(salt_factor=2), goodsId(salt_factor=4)) PARTITIONS 64;
Use _id como chave secundária de partição
Se nenhuma coluna secundária de negócio adequada estiver disponível, use _id (a chave primária composta da tabela larga) como chave secundária de partição para eliminar pontos críticos.
CREATE INDEX IF NOT EXISTS idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice)
PARTITION BY hash(storeId(salt_factor=2), _id(salt_factor=4)) PARTITIONS 64;
Particionamento por tempo
O particionamento por tempo organiza os dados do índice em partições por intervalo de tempo — por exemplo, por semana ou mês. O sistema cria novas partições automaticamente em um ciclo contínuo e remove aquelas cujos dados excederam o TTL.
Ciclo de vida da partição:
Criação — O sistema cria novas partições automaticamente com base em
RANGE_TIME_PARTITION_INTERVAL.Retenção — Os dados da partição são mantidos pelo número de dias definido em
RANGE_TIME_PARTITION_TTL.Exclusão — O sistema remove automaticamente partições mais antigas que o TTL.
Crie um índice com partição por tempo
Partições semanais, retenção de 90 dias
As partições começam 30 dias antes da criação do índice. O sistema cria uma nova partição a cada 7 dias e exclui automaticamente dados com mais de 90 dias.
CREATE INDEX idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice, orderTime)
PARTITION BY RANGE time(orderTime) PARTITIONS 4
WITH (
indexState=ACTIVE,
RANGE_TIME_PARTITION_START='30',
RANGE_TIME_PARTITION_INTERVAL='7',
RANGE_TIME_PARTITION_TTL='90'
);
Partições mensais, retenção de 6 meses, timestamps com precisão de segundos
As partições começam 180 dias antes da criação do índice. O sistema cria uma nova partição a cada 30 dias e exclui automaticamente dados com mais de 180 dias. A coluna orderTime armazena timestamps Unix em segundos (valores de 10 dígitos).
CREATE INDEX idx USING SEARCH ON search_table (storeId, goodsId, goodsPrice, orderTime)
PARTITION BY RANGE time(orderTime) PARTITIONS 4
WITH (
indexState=ACTIVE,
RANGE_TIME_PARTITION_START='180',
RANGE_TIME_PARTITION_INTERVAL='30',
RANGE_TIME_PARTITION_TTL='180',
RANGE_TIME_PARTITION_FIELD_TIMEUNIT='s'
);
Parâmetros de particionamento por tempo
|
Parâmetro |
Obrigatório |
Descrição |
||
|
|
Sim |
Número de dias anteriores à criação do índice a partir dos quais o sistema começa a criar partições. Se o timestamp dos dados históricos for anterior ao horário inicial da partição, o sistema relatará um erro. |
||
|
|
Sim |
Intervalo em dias entre partições criadas automaticamente. Por exemplo, |
||
|
|
Não |
Número de dias para reter os dados da partição. O sistema exclui automaticamente partições mais antigas que esse valor. |
||
|
|
Não |
Unidade de tempo do campo de partição. Padrão: |
||
|
|
Não |
Intervalo máximo permitido em dias entre um timestamp futuro e a hora atual. Se não definido, timestamps futuros não terão limite superior. |
||
|
|
Não |
Formato de gravação do campo de partição de tempo. Padrão: |
epoch_millis`. Aplica-se quando o campo de partição é do tipo |
O parâmetro RANGE_TIME_PARTITION_START define o limite histórico para indexação. Por exemplo, suponha que a data mais antiga na coluna orderTime seja 16 de março de 2021. Para reter todos os dados históricos, calcule o número de dias entre 16 de março de 2021 e a data de criação do índice e defina esse valor como RANGE_TIME_PARTITION_START. Se o timestamp dos dados históricos for anterior ao horário inicial da partição, o sistema relatará um erro.