Hologres é um motor de data warehouse em tempo real compatível com o protocolo PostgreSQL. Ele suporta gravações em tempo real, atualizações e processamento analítico online (OLAP) em petabytes de dados, além de serviços de dados online com alta concorrência e baixa latência.
Este tópico explica como executar testes de desempenho para gravações, atualizações e consultas pontuais usando holo-e2e-performance-tool, e apresenta resultados de benchmark de referência em uma instância de 64 vCPUs.
Cenários de teste
|
Cenário |
O que é testado |
Formatos de armazenamento |
|
Gravação de dados |
Throughput de gravação em tabelas orientadas a linha, orientadas a coluna e híbridas linha-coluna |
Todos os três |
|
Atualização de dados |
Throughput de atualização para atualizações globais e parciais em tabelas com chave primária |
Todos os três |
|
Consulta pontual |
Desempenho de consulta pontual filtrando por chave primária |
Apenas orientadas a linha e híbridas linha-coluna |
Tabelas orientadas a coluna não são adequadas para consultas pontuais e são excluídas desse cenário.
Como funciona
Os três cenários de teste são interdependentes e se constroem em sequência:
Teste de gravação -- Popula uma tabela com dados de teste.
Teste de atualização -- Reutiliza a mesma tabela para medir o throughput de atualização (mantenha a tabela do passo 1).
Teste de consulta pontual -- Consulta a mesma tabela pela chave primária.
Mecanismo de gravação e atualização
A ferramenta suporta dois modos de gravação:
Modo Fixed Copy -- Usa a instrução
COPYdo PostgreSQL, otimizada com Fixed Plan para execução SQL mais rápida.Modo Insert -- Usa instruções
INSERTpadrão, também otimizadas com Fixed Plan.
Em ambos os modos, a ferramenta adiciona automaticamente duas colunas à tabela:
|
Coluna |
Função |
Comportamento |
|
|
Chave primária e chave de distribuição |
Começa em 1 e é incrementada a cada linha |
|
|
Chave de segmento |
Definida com o timestamp atual a cada gravação |
Para cada coluna TEXT configurada, a ferramenta grava uma string do comprimento especificado com o valor de id concatenado. O teste é encerrado quando o número de linhas ou a duração alvo é atingido.
Durante as atualizações, o mesmo padrão incremental de id é utilizado. Para atualizações parciais, apenas um subconjunto das colunas TEXT é reescrito.
Mecanismo de consulta pontual
A ferramenta suporta dois modos de consulta:
Modo assíncrono -- A API de consulta pontual é não bloqueante. Múltiplas requisições são agrupadas em uma única instrução SQL, maximizando o throughput. Mais indicado para cenários de alto throughput, como junções de tabelas em tempo real baseadas em Flink.
Modo síncrono -- A API de consulta pontual é bloqueante. Cada requisição corresponde a uma instrução SQL e é concluída antes da próxima iniciar. Recomendado para cenários sensíveis à latência.
Durante o teste, a ferramenta seleciona aleatoriamente uma chave primária dentro do intervalo configurado e executa uma consulta pontual. O teste é encerrado quando a duração alvo é atingida.
Pré-requisitos
Antes de começar, prepare os seguintes itens:
Uma instância Hologres (dedicada, pagamento conforme o uso). Os resultados de benchmark deste tópico utilizam uma instância de 64 vCPUs e 256 GB de memória. Prefira uma instância recém-criada em vez de uma que tenha passado por upgrade ou downgrade, para minimizar variáveis que possam afetar os resultados.
-
Uma instância Elastic Compute Service (ECS) para atuar como cliente de teste:
Tipo de instância recomendado:
ecs.g6.4xlargeSistema operacional: Alibaba Cloud Linux 3.2104 LTS 64-bit
Armazenamento: SSD empresarial (ESSD)
A instância ECS deve estar na mesma região, Virtual Private Cloud (VPC) e zona da instância Hologres
Um banco de dados criado na instância Hologres. Para mais detalhes, consulte Create a database.
Java Development Kit (JDK) 11 instalado na instância ECS. Para mais detalhes, consulte Manually deploy OpenJDK.
O arquivo JAR do holo-e2e-performance-tool, enviado para a instância ECS. Para instruções de upload, consulte Use Workbench.
As especificações de ECS acima são recomendações, não requisitos obrigatórios. Durante os testes, monitore o CPU e a largura de banda de rede da instância ECS para confirmar que o cliente não é um gargalo.
Sobre a ferramenta de teste
holo-e2e-performance-tool é uma ferramenta open-source desenvolvida pela equipe do Hologres. Ela integra criação de tabelas, geração de dados de teste e medição de desempenho em um único JAR, dispensando a preparação prévia de dados de teste. A chave primária dos dados gerados é uma sequência de inteiros consecutivos, o que garante taxas de acerto completas durante os testes de atualização e consulta pontual.
Executar um teste de gravação de dados
Passo 1: Crie o arquivo de configuração
Na instância ECS, crie um arquivo chamado test_insert.conf com o seguinte conteúdo:
# Connection configuration
holoClient.jdbcUrl=jdbc:hologres://<ENDPOINT>:<PORT>/<DBNAME>
holoClient.username=<AccessKey_ID>
holoClient.password=<AccessKey_Secret>
holoClient.writeThreadSize=100
# Write configuration
put.threadSize=8
put.testByTime=false
put.rowNumber=200000000
put.testTime=600000
# Table configuration
put.tableName=kv_test
put.columnCount=20
put.columnSize=20
put.orientation=row
# Other configurations
put.createTableBeforeRun=true
put.deleteTableAfterDone=false
put.vacuumTableBeforeRun=false
Este exemplo cria uma tabela orientada a linha. Para testar uma tabela orientada a coluna ou híbrida linha-coluna, altereorientationparacolumnourow,column.
Substitua os marcadores pelos valores reais:
|
Marcador |
Descrição |
Onde encontrar |
|
|
Nome de domínio VPC da instância Hologres |
Instance Details > Network Information no console do Hologres |
|
|
Número da porta da instância Hologres |
Mesmo local indicado acima |
|
|
Nome do banco de dados de teste |
O banco de dados criado nos pré-requisitos |
|
|
AccessKey ID da sua conta Alibaba Cloud |
Página AccessKey Management |
|
|
AccessKey secret da sua conta Alibaba Cloud |
Mesmo local indicado acima |
Parâmetros de configuração
Módulo | Parâmetro | Descrição | Observações |
Conexão |
| String de conexão Java Database Connectivity (JDBC). Formato: | Use o nome de domínio VPC para |
| AccessKey ID | ||
| AccessKey secret | ||
| Número de threads de gravação por Holo Client. Cada thread utiliza uma conexão. Aplica-se apenas ao modo Insert. | No modo Fixed Copy, a contagem de conexões é igual a | |
Gravação |
| Número de threads de geração de dados | No modo Fixed Copy, cada thread usa uma conexão (total de conexões = |
| Define se o teste é executado por duração fixa ou por número fixo de linhas |
| |
| Número alvo de linhas. Válido apenas quando | ||
| Duração alvo em milissegundos. Válido apenas quando | ||
Tabela |
| Nome da tabela de teste | |
| Número de colunas TEXT na tabela | ||
| Comprimento em caracteres de cada coluna TEXT | ||
| Formato de armazenamento da tabela |
| |
Outros |
| Define se a tabela será criada antes do início do teste |
|
| Define se a tabela será excluída após a conclusão do teste | Defina como | |
| Define se o | O |
Passo 2: Execute o teste
# Fixed Copy mode
java -jar holo-e2e-performance-tool-1.0.0.jar test_insert.conf FIXED_COPY
# Or, Insert mode
java -jar holo-e2e-performance-tool-1.0.0.jar test_insert.conf INSERT
Passo 3: Visualize os resultados
cat result.csv
Consulte Campos do resultado para o formato de saída.
Mantenha a tabela de teste (deleteTableAfterDone=false) se você planeja executar testes de atualização ou consulta pontual em seguida.
Executar um teste de atualização de dados
O teste de atualização reutiliza a tabela populada durante o teste de gravação. Dois tipos de atualização são suportados: atualização global (todas as colunas) e atualização parcial (um subconjunto de colunas).
Atualização global
-
Crie um arquivo chamado
test_update.conf. Use a mesma configuração do teste de gravação, alterandocreateTableBeforeRunparafalse:A única alteração em relação à configuração do teste de gravação é
createTableBeforeRun=false. Isso preserva a tabela e os dados existentes.# Connection configuration holoClient.jdbcUrl=jdbc:hologres://<ENDPOINT>:<PORT>/<DBNAME> holoClient.username=<AccessKey_ID> holoClient.password=<AccessKey_Secret> holoClient.writeThreadSize=100 # Write configuration put.threadSize=8 put.testByTime=false put.rowNumber=200000000 put.testTime=600000 # Table configuration put.tableName=kv_test put.columnCount=20 put.columnSize=20 put.orientation=row # Other configurations put.createTableBeforeRun=false put.deleteTableAfterDone=false put.vacuumTableBeforeRun=false -
Execute o teste:
java -jar holo-e2e-performance-tool-1.0.0.jar test_update.conf FIXED_COPY -
Visualize os resultados:
cat result.csv
Atualização parcial
A atualização parcial grava em um subconjunto das colunas TEXT. O parâmetro writeColumnCount controla quantas colunas são atualizadas.
-
Crie um arquivo chamado
test_update_part.conf. Adicione o parâmetrowriteColumnCountà seção de configuração de tabela:writeColumnCount=10atualiza 10 das 20 colunas TEXT (50%). Ajuste essa proporção de acordo com sua carga de trabalho.# Connection configuration holoClient.jdbcUrl=jdbc:hologres://<ENDPOINT>:<PORT>/<DBNAME> holoClient.username=<AccessKey_ID> holoClient.password=<AccessKey_Secret> holoClient.writeThreadSize=100 # Write configuration put.threadSize=8 put.testByTime=false put.rowNumber=200000000 put.testTime=600000 # Table configuration put.tableName=kv_test put.columnCount=20 put.columnSize=20 put.writeColumnCount=10 put.orientation=row # Other configurations put.createTableBeforeRun=false put.deleteTableAfterDone=false put.vacuumTableBeforeRun=false -
Execute o teste:
java -jar holo-e2e-performance-tool-1.0.0.jar test_update_part.conf FIXED_COPY -
Visualize os resultados:
cat result.csv
Executar um teste de consulta pontual
Passo 1: Crie o arquivo de configuração
Crie um arquivo chamado test_get.conf:
# Connection configuration
holoClient.jdbcUrl=jdbc:hologres://<ENDPOINT>:<PORT>/<DBNAME>
holoClient.username=<AccessKey_ID>
holoClient.password=<AccessKey_Secret>
holoClient.readThreadSize=32
# Test configuration
get.threadSize=8
get.testTime=300000
get.tableName=kv_test
get.async=true
get.vacuumTableBeforeRun=true
get.keyRangeParams=L1-200000000
# Table initialization configuration (used only in PREPARE_GET_DATA mode)
prepareGetData.rowNumber=200000000
prepareGetData.orientation=row
put.columnCount=20
put.columnSize=20
Este exemplo configura consultas pontuais assíncronas em uma tabela orientada a linha. Para testar consultas síncronas, definaget.async=falsee ajustethreadSizeereadThreadSizeconforme necessário (consulte a tabela de parâmetros abaixo).
Parâmetros de consulta pontual
Módulo | Parâmetro | Descrição | Observações |
Conexão |
| Número de conexões de consulta | Modo assíncrono: defina como 2 a 4 vezes o valor de |
Teste |
| Número de threads que geram requisições de consulta | Modo assíncrono: 8 é um bom padrão para instâncias de 64 vCPUs. Modo síncrono: aumente para 500 para maior throughput. |
| Duração do teste em milissegundos | ||
| Nome da tabela alvo | ||
| Define se as consultas pontuais são assíncronas |
| |
| Define se o | Executar o | |
| Intervalo de chaves primárias para as consultas. Formato: |
| |
Inicialização de tabela (apenas no modo PREPARE_GET_DATA) |
| Número de linhas a gerar | |
| Formato de armazenamento |
| |
| Número de colunas TEXT | ||
| Comprimento em caracteres por coluna |
Passo 2: Execute o teste
Se a tabela já contém dados dos testes de gravação ou atualização, pule a preparação de dados e execute a consulta pontual diretamente:
# (Optional) Prepare data -- only if the table has no data
java -jar holo-e2e-performance-tool-1.0.0.jar test_get.conf PREPARE_GET_DATA
# Run the point query test
java -jar holo-e2e-performance-tool-1.0.0.jar test_get.conf GET
Para usar dados reais de negócio em vez de dados gerados, a tabela deve ter uma chave primária de coluna única do tipo INT ou BIGINT com valores consecutivos.
Passo 3: Visualize os resultados
cat result.csv
Campos do resultado
Todos os modos de teste gravam os resultados em result.csv no diretório atual. O arquivo contém os seguintes campos:
|
Campo |
Descrição |
|
|
Horário de início do teste |
|
|
Horário de término do teste |
|
|
Total de linhas processadas |
|
|
QPS médio no último 1 minuto |
|
|
QPS médio nos últimos 5 minutos |
|
|
QPS médio nos últimos 15 minutos |
|
|
Latência média (ms). Coletada apenas nos modos Insert e GET. |
|
|
Latência P99 (ms). Coletada apenas nos modos Insert e GET. |
|
|
Latência P999 (ms). Coletada apenas nos modos Insert e GET. |
|
|
Versão da instância Hologres |
Resultados de benchmark
Os resultados a seguir foram coletados em uma instância Hologres V3.0.22 com 64 vCPUs, utilizando JDK 11 e modo Fixed Copy. Cada cenário utilizou 200 milhões de linhas com tamanho de coluna de 20 caracteres. O volume total de dados recomendado para uma instância de 64 vCPUs é de 40 milhões a 400 milhões de linhas. Quantidades de colunas testadas: 20, 50 e 100. Os valores de QPS são extraídos da métrica qps1 e os valores de latência, de latencyMean.
O tipo de instância, o esquema da tabela, o volume de dados e a concorrência influenciam significativamente o desempenho. Use estes números como linha de base e ajuste a concorrência em múltiplas execuções de teste para sua configuração específica. Se a utilização de CPU não estiver totalmente saturada após uma execução, aumente a concorrência para encontrar o throughput ideal.
Escolha um formato de armazenamento
Antes de analisar os números, use este guia para selecionar o formato de armazenamento adequado à sua carga de trabalho:
|
Carga de trabalho |
Formato recomendado |
Justificativa |
|
Muitas gravações, sem consultas pontuais |
Orientado a linhas |
Maior throughput de gravação e atualização (aproximadamente 3x mais rápido que o orientado a colunas) |
|
Gravações mistas e consultas pontuais |
Híbrido linha-coluna |
Suporta tanto gravações de alto throughput quanto consultas pontuais de baixa latência |
|
Consultas analíticas em tabelas largas |
Orientado a colunas |
Otimizado para varreduras de colunas, mas com throughput de gravação menor |
|
Atualizações parciais de colunas |
Orientado a linhas |
Atualizações parciais em tabelas orientadas a linhas atingem o maior QPS |
20 colunas
Storage format | Scenario | Concurrency | QPS (x 10,000) | Latency (ms) |
Row-oriented | Write (Fixed Copy) | threadSize=8 | 88.3 | -- |
Global update (Fixed Copy) | threadSize=8 | 91.1 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 136.7 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 43.6 | 8.60 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 26.1 | 7.88 | |
Column-oriented | Write (Fixed Copy) | threadSize=8 | 29.9 | -- |
Global update (Fixed Copy) | threadSize=8 | 18.5 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 12.8 | -- | |
Row-column hybrid | Write (Fixed Copy) | threadSize=8 | 25.0 | -- |
Global update (Fixed Copy) | threadSize=8 | 17.3 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 17.5 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 40.4 | 8.75 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 27.0 | 8.12 |
50 colunas
Storage format | Scenario | Concurrency | QPS (x 10,000) | Latency (ms) |
Row-oriented | Write (Fixed Copy) | threadSize=8 | 41.9 | -- |
Global update (Fixed Copy) | threadSize=8 | 38.2 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 69.8 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 35.7 | 10.20 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 24.0 | 9.28 | |
Column-oriented | Write (Fixed Copy) | threadSize=8 | 15.5 | -- |
Global update (Fixed Copy) | threadSize=8 | 11.7 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 6.4 | -- | |
Row-column hybrid | Write (Fixed Copy) | threadSize=8 | 13.7 | -- |
Global update (Fixed Copy) | threadSize=8 | 10.5 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 11.6 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 31.5 | 12.29 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 24.2 | 10.00 |
100 colunas
Storage format | Scenario | Concurrency | QPS (x 10,000) | Latency (ms) |
Row-oriented | Write (Fixed Copy) | threadSize=8 | 24.4 | -- |
Global update (Fixed Copy) | threadSize=8 | 22.5 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 38.1 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 26.6 | 14.34 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 21.4 | 12.12 | |
Column-oriented | Write (Fixed Copy) | threadSize=8 | 8.4 | -- |
Global update (Fixed Copy) | threadSize=8 | 6.9 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 3.1 | -- | |
Row-column hybrid | Write (Fixed Copy) | threadSize=8 | 7.6 | -- |
Global update (Fixed Copy) | threadSize=8 | 5.3 | -- | |
Partial update (Fixed Copy) | threadSize=8 | 6.8 | -- | |
Point query (async) | threadSize=8, readThreadSize=32 | 25.0 | 15.66 | |
Point query (sync) | threadSize=100, readThreadSize=100 | 21.4 | 13.79 |
Principais conclusões
Tabelas orientadas a linhas oferecem o maior throughput de gravação — aproximadamente 3x mais rápido que tabelas orientadas a colunas para o mesmo número de colunas.
Atualizações parciais superam as atualizações globais em tabelas orientadas a linhas porque menos colunas são reescritas. Em tabelas orientadas a colunas e híbridas linha-coluna, as atualizações globais podem igualar ou superar o throughput das atualizações parciais.
A latência de consultas pontuais é semelhante entre tabelas orientadas a linhas e híbridas linha-coluna, normalmente abaixo de 10 ms para tabelas de 20 colunas.
Consultas pontuais assíncronas atingem QPS mais alto do que consultas síncronas, porém com latência ligeiramente maior.
O throughput de gravação e atualização diminui conforme o número de colunas aumenta — uma tabela orientada a linhas com 100 colunas atinge cerca de 28% do QPS de gravação de uma tabela com 20 colunas. O throughput de consultas pontuais é menos afetado, mantendo de 50% a 60% do QPS com 100 colunas em comparação com 20 colunas.
Solução de problemas
O cliente ECS se torna o gargalo
Sintoma: O QPS atinge um platô mesmo com baixa utilização de CPU na instância Hologres.
Causa: A instância ECS que executa a ferramenta de teste atingiu o limite de CPU ou de largura de banda de rede.
Solução: Monitore as métricas de CPU e rede da ECS durante o teste. Se alguma estiver saturada, faça upgrade para um tipo de instância ECS maior ou reduza o threadSize.
QPS abaixo do esperado
Sintoma: O QPS é significativamente inferior aos resultados de benchmark listados acima.
Possíveis causas e soluções:
Concorrência insuficiente — Se a utilização de CPU do Hologres estiver baixa, aumente o
threadSize(para gravações e atualizações) ou oreadThreadSize(para consultas pontuais).Instância passou por upgrade ou downgrade — As características de desempenho diferem entre instâncias novas e redimensionadas. Crie uma nova instância para executar os benchmarks.
Latência de rede — Confirme que a instância ECS e a instância Hologres estão no mesmo VPC e na mesma zona.
Distorção de dados — Ao usar dados personalizados, valores desbalanceados na chave de distribuição podem concentrar a carga em um subconjunto de shards.
Erros de conexão
Sintoma: A ferramenta de teste falha com exceções relacionadas à conexão.
Solução: Verifique a string de conexão JDBC, o AccessKey ID e o segredo do AccessKey. Confirme que a instância Hologres permite conexões originadas do VPC da instância ECS.