O Hologres é um mecanismo de data warehouse em tempo real compatível com o protocolo PostgreSQL. Ele oferece suporte a gravações e atualizações em tempo real, além de Processamento Analítico Online (OLAP) em petabytes de dados, juntamente com serviços de dados online de alta concorrência e baixa latência.
Este tópico explica como executar testes de desempenho para gravação, atualização e consultas pontuais de dados usando o holo-e2e-performance-tool, e fornece 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 linhas, colunas 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 orientada a linhas e híbrida (linha-coluna) |
Tabelas orientadas a colunas não são adequadas para consultas pontuais e estão excluídas desse cenário.
Como funciona
Os três cenários de teste se complementam:
Teste de gravação -- Preencha uma tabela com dados de teste.
Teste de atualização -- Reutilize a mesma tabela para medir o throughput de atualização (mantenha a tabela da etapa 1).
Teste de consulta pontual -- Consulte a mesma tabela pela chave primária.
Mecânica de gravação e atualização
A ferramenta suporta dois modos de gravação:
Modo Fixed Copy -- Utiliza a instrução
COPYdo PostgreSQL, otimizada com o Fixed Plan para execução mais rápida de SQL.Modo Insert -- Usa instruções
INSERTpadrão, também otimizadas com o 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 incrementa a cada linha |
|
|
Chave de segmento |
Definida com o timestamp atual em cada gravação |
Para cada coluna TEXT configurada, a ferramenta grava uma string do comprimento especificado com o valor de id anexado. O teste termina quando a contagem de linhas alvo ou a duração é atingida.
Durante as atualizações, o mesmo padrão de incremento de id é utilizado. Para atualizações parciais, apenas um subconjunto de colunas TEXT é reescrito.
Mecânica de consulta pontual
A ferramenta suporta dois modos de consulta:
Modo assíncrono -- A API de consulta pontual é não bloqueante. Várias solicitações são agrupadas em uma única instrução SQL, maximizando o throughput. Ideal 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 solicitação corresponde a uma instrução SQL e é concluída antes que a próxima comece. Mais indicado 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 termina quando a duração alvo é atingida.
Pré-requisitos
Antes de começar, prepare o seguinte:
Uma instância Hologres (dedicada, pagamento conforme o uso). Os resultados de benchmark neste tópico usam uma instância com 64 vCPUs e 256 GB de memória. Utilize uma instância recém-criada em vez de uma que tenha sido atualizada ou reduzida, para minimizar variáveis que afetam os resultados.
-
Uma instância Elastic Compute Service (ECS) para servir como cliente de teste:
Tipo de instância recomendado:
ecs.g6.4xlargeSistema operacional: Alibaba Cloud Linux 3.2104 LTS 64 bits
Armazenamento: SSD empresarial (ESSD)
A instância ECS deve estar na mesma região, Virtual Private Cloud (VPC) e zona que a instância Hologres
Um banco de dados criado na instância Hologres. Para detalhes, consulte Criar um banco de dados.
Java Development Kit (JDK) 11 instalado na instância ECS. Para detalhes, consulte Implantar OpenJDK manualmente.
O arquivo JAR holo-e2e-performance-tool, carregado na instância ECS. Para instruções de upload, consulte Usar o Workbench.
As especificações de ECS acima são recomendações, não requisitos. Durante os testes, monitore a CPU e a largura de banda de rede da ECS para confirmar que o cliente não é um gargalo.
Sobre a ferramenta de teste
O holo-e2e-performance-tool é uma ferramenta de código aberto 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, eliminando a necessidade de preparar dados de teste separadamente. A chave primária dos dados gerados é uma série de inteiros consecutivos, o que garante taxas de acerto totais durante os testes de atualização e consulta pontual.
Executar um teste de gravação de dados
Etapa 1: Criar 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 linhas. Para testar uma tabela orientada a colunas ou híbrida (linha-coluna), altereorientationparacolumnourow,column.
Substitua os espaços reservados pelos seus valores reais:
|
Espaço reservado |
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 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 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 usa 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 = |
| Controla se o teste executa por uma duração fixa ou um número fixo de linhas |
| |
| Contagem de linhas alvo. Aplica-se apenas quando | ||
| Duração alvo em milissegundos. Aplica-se apenas quando | ||
Tabela |
| Nome da tabela de teste | |
| Número de colunas TEXT na tabela | ||
| Comprimento de caracteres de cada coluna TEXT | ||
| Formato de armazenamento da tabela |
| |
Outros |
| Se deve criar a tabela antes do início do teste |
|
| Se deve excluir a tabela após a conclusão do teste | Defina como | |
| Se deve executar |
|
Etapa 2: Executar 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
Etapa 3: Visualizar os resultados
cat result.csv
Consulte Campos de resultado para ver 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 preenchida 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, mas alterecreateTableBeforeRunparafalse:A única mudança 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
Uma 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 da tabela:writeColumnCount=10atualiza 10 das 20 colunas TEXT (50%). Ajuste essa proporção para corresponder à 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
Etapa 1: Criar 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 linhas. Para testar consultas síncronas, definaget.async=falsee ajustethreadSizeereadThreadSizeadequadamente (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-4x |
Teste |
| Número de threads gerando solicitações de consulta | Modo assíncrono: 8 é um bom padrão em uma instância de 64 vCPUs. Modo síncrono: aumente para 500 para obter maior throughput. |
| Duração do teste em milissegundos | ||
| Nome da tabela alvo | ||
| Se deve usar consultas pontuais assíncronas |
| |
| Se deve executar | Executar | |
| Intervalo de chave primária para consultas. Formato: |
| |
Inicialização da tabela (apenas modo PREPARE_GET_DATA) |
| Linhas a gerar | |
| Formato de armazenamento |
| |
| Número de colunas TEXT | ||
| Comprimento de caracteres por coluna |
Etapa 2: Executar o teste
Se a tabela já tiver 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 seus próprios dados de negócios em vez de dados gerados, a tabela deve ter uma chave primária de coluna única do tipo INT ou BIGINT com valores consecutivos.
Etapa 3: Visualizar os resultados
cat result.csv
Campos de resultado
Todos os modos de teste gravam resultados em result.csv no diretório atual. O arquivo contém os seguintes campos:
|
Campo |
Descrição |
|
|
Hora de início do teste |
|
|
Hora de término do teste |
|
|
Total de linhas processadas |
|
|
QPS médio no último 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, usando JDK 11 e modo Fixed Copy. Cada cenário usou 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. Contagens de colunas testadas: 20, 50 e 100. Os valores de QPS são obtidos 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 afetam significativamente o desempenho. Use esses números como linha de base e ajuste a concorrência em várias execuções de teste para sua configuração específica. Se a utilização da CPU não estiver totalmente saturada após uma execução de teste, aumente a concorrência para encontrar o throughput ideal.
Escolher um formato de armazenamento
Antes de revisar os números, use este guia para selecionar o formato de armazenamento adequado para sua carga de trabalho:
|
Carga de trabalho |
Formato recomendado |
Motivo |
|
Foco em gravação, 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 o throughput de gravação é menor |
|
Atualizações parciais de colunas |
Orientado a linhas |
Atualizações parciais em tabelas orientadas a linhas alcançam o maior QPS |
20 colunas
Formato de armazenamento | Cenário | Concorrência | QPS (x 10.000) | Latência (ms) |
Orientado a linhas | Gravação (Fixed Copy) | threadSize=8 | 88,3 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 91,1 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 136,7 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 43,6 | 8,60 | |
Consulta pontual (síncrona) | threadSize=100, readThreadSize=100 | 26,1 | 7,88 | |
Orientado a colunas | Gravação (Fixed Copy) | threadSize=8 | 29,9 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 18,5 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 12,8 | -- | |
Híbrido (linha-coluna) | Gravação (Fixed Copy) | threadSize=8 | 25,0 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 17,3 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 17,5 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 40,4 | 8,75 | |
Consulta pontual (síncrona) | threadSize=100, readThreadSize=100 | 27,0 | 8,12 |
50 colunas
Formato de armazenamento | Cenário | Concorrência | QPS (x 10.000) | Latência (ms) |
Orientado a linhas | Gravação (Fixed Copy) | threadSize=8 | 41,9 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 38,2 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 69,8 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 35,7 | 10,20 | |
Consulta pontual (síncrona) | threadSize=100, readThreadSize=100 | 24,0 | 9,28 | |
Orientado a colunas | Gravação (Fixed Copy) | threadSize=8 | 15,5 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 11,7 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 6,4 | -- | |
Híbrido (linha-coluna) | Gravação (Fixed Copy) | threadSize=8 | 13,7 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 10,5 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 11,6 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 31,5 | 12,29 | |
Consulta pontual (síncrona) | threadSize=100, readThreadSize=100 | 24,2 | 10,00 |
100 colunas
Formato de armazenamento | Cenário | Concorrência | QPS (x 10.000) | Latência (ms) |
Orientado a linhas | Gravação (Fixed Copy) | threadSize=8 | 24,4 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 22,5 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 38,1 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 26,6 | 14,34 | |
Consulta pontual (síncrona) | threadSize=100, readThreadSize=100 | 21,4 | 12,12 | |
Orientado a colunas | Gravação (Fixed Copy) | threadSize=8 | 8,4 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 6,9 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 3,1 | -- | |
Híbrido (linha-coluna) | Gravação (Fixed Copy) | threadSize=8 | 7,6 | -- |
Atualização global (Fixed Copy) | threadSize=8 | 5,3 | -- | |
Atualização parcial (Fixed Copy) | threadSize=8 | 6,8 | -- | |
Consulta pontual (assíncrona) | threadSize=8, readThreadSize=32 | 25,0 | 15,66 | |
Consulta pontual (síncrona) | 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 a mesma contagem de colunas.
Atualizações parciais superam atualizações globais em tabelas orientadas a linhas porque menos colunas são reescritas. Em tabelas orientadas a colunas e híbridas (linha-coluna), atualizações globais podem igualar ou superar o throughput de atualizações parciais.
A latência de consulta pontual é semelhante entre tabelas orientadas a linhas e híbridas (linha-coluna), tipicamente abaixo de 10 ms para tabelas de 20 colunas.
Consultas pontuais assíncronas alcançam QPS mais alto que consultas síncronas, mas com latência ligeiramente maior.
O throughput de gravação e atualização diminui à medida que a contagem de colunas aumenta -- uma tabela orientada a linhas com 100 colunas atinge aproximadamente 28% do QPS de gravação de uma tabela de 20 colunas. O throughput de consulta pontual é menos afetado, retendo 50-60% do QPS em 100 colunas comparado a 20 colunas.
Solução de problemas
Cliente ECS torna-se o gargalo
Sintoma: O QPS estabiliza apesar da baixa utilização da CPU na instância Hologres.
Causa: A instância ECS executando a ferramenta de teste atingiu seu limite de CPU ou largura de banda de rede.
Solução: Monitore as métricas de CPU e rede da ECS durante o teste. Se qualquer uma estiver saturada, atualize para um tipo de instância ECS maior ou reduza threadSize.
QPS abaixo do esperado
Sintoma: O QPS está significativamente menor que os resultados de benchmark listados acima.
Possíveis causas e soluções:
Concorrência insuficiente -- Se a utilização da CPU do Hologres estiver baixa, aumente
threadSize(para gravações e atualizações) oureadThreadSize(para consultas pontuais).Instância foi atualizada ou reduzida -- As características de desempenho diferem entre instâncias novas e redimensionadas. Crie uma nova instância para benchmarking.
Latência de rede -- Confirme se a instância ECS e a instância Hologres estão na mesma VPC e zona.
Skew de dados -- Se estiver usando dados personalizados, valores de chave de distribuição desiguais 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 AccessKey secret. Confirme se a instância Hologres permite conexões da VPC da instância ECS.