O desempenho de qualquer sistema de banco de dados depende de quatro recursos principais do sistema:
- CPU
- Memória
- Disco de E / S
- Rede
O desempenho aumentará ao ajustar ou dimensionar cada recurso - este blog abordará o recurso da CPU. É importante observar que sempre que liberamos um gargalo no sistema, podemos encontrar outro. Por exemplo, ao melhorar o desempenho da CPU, a carga do banco de dados muda para IO; portanto, a menos que nosso armazenamento seja capaz de oferecer mais IOPS, talvez não possamos realmente ver a melhoria que esperávamos. Mas não desanime, o ajuste de desempenho às vezes é um jogo de pancadaria…
Todos sabemos que quanto mais poder de processamento disponível para o servidor, melhor o desempenho geral do sistema. Especialmente quando a CPU passa a maior parte do tempo no estado do usuário e não no estado do kernel . No Avance Network, lutamos com dois casos que faziam com que o estado do Kernel consumisse muita CPU; seu sistema pode ter os mesmos problemas.
Como coletamos métricas de CPU no Avance Network?
As métricas são coletadas usando Graphite ; os painéis são construídos com o Grafana . O plug-in da CPU Sensu, cpu-metrics.rb, coleta as seguintes métricas da CPU: usuário, bom , sistema , inativo, iowait, irq, softirq, roubar, convidado. Como o processo Vertica é executado em um espaço de usuário da CPU que foi agregado , vamos nos concentrar principalmente nas métricas agradáveis e do sistema.
O sistema chama o impacto da CPU chamando a função Vertica new_time
O que são chamadas de sistema?
As chamadas do sistema são como um programa entra no kernel para executar uma tarefa. Os programas usam chamadas do sistema para executar uma variedade de operações, como: criação de processos, execução de E / S de rede e arquivo e muito mais.
Se uma chamada do sistema é uma interface interna tão básica entre um aplicativo e o kernel do Linux, por que devemos nos preocupar com isso?
- Às vezes, esse é o caso. No entanto, se o sistema chamar 'o uso da CPU permanece alto por longos períodos de tempo, isso pode ser uma indicação de que algo não está certo. Uma possível causa de picos de chamadas do sistema pode ser um problema com um módulo de driver / kernel ou, às vezes, devido à alta simultaneidade
- Para executar uma chamada de sistema, a CPU precisa mudar do modo de usuário para o modo kernel, isso é chamado de alternância de contexto , pois a comutação ontext tem custos de desempenho .
No Avance Network, todos os dados do registro de data e hora são salvos no fuso horário UTC. Os relatórios agregados para tabelas de dados brutos produzem relatórios convertidos no fuso horário do editor (cliente) usando a função " new_time " da Vertica para converter entre fusos horários.
Por exemplo, agregando ações por horas:
1 2 3 4 5 6 7 | SELECT date_trunc('hour', new_time(action_event_time,p.time_zone_name, 'UTC') ), count(action_name) FROM actions a JOIN publishers p ON a.action_publisher_id = p.id WHERE a.action_event_time BETWEEN new_time('2017-04-20 00:00:00.0',p.time_zone_name, 'UTC') AND new_time('2017-04-24 23:59:59.999', p.time_zone_name,'UTC') GROUP BY 1; |
A imagem a seguir representa o uso geral da CPU de um servidor ao longo do tempo, empilhando todos os tipos de métricas de CPU:
Como perfilamos as chamadas de CPU?
O Linux perf é uma ferramenta poderosa para diagnosticar isso, e um FlameGraph pode ser usado para virtualizar o relatório perf, desenhando um gráfico.
Comandos perf úteis:
- perf top - eventos em tempo real
- perf record - execute um comando e registre seu perfil em perf.data
- relatório perf - leia perf.data (criado pelo perf record) e exiba o perfil
A execução dos seguintes comandos registrará e relatará chamadas de CPU por uma duração de 5 minutos:
1 2 3 4 5 6 7 | perf record -F 99 -a -g -- sleep 300 -- Take 99 samples/second for five minutes perf report - -sort cpu /tmp/report.out -- Generate calls reports order by cpu time |
A saída do arquivo /tmp/report.out mostra o seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 67.72% vertica [kernel.kallsyms] [k] __ticket_spin_lock | --- __ticket_spin_lock | |--99.38%-- _raw_spin_lock | | | |--53.12%-- futex_wake | | do_futex | | sys_futex | | | | | |--100.00%--system_call_fastpath | | | | | | | |--99.98%--__lll_unlock_wake | | | | | | | | | |--99.95%-- getTZoffset | | | | | | | | | | | |--35.86%-- _ZN2EE5VEval16ZoneTS_TStz_SkipEPciiPi | | | | | | _ZN2EE5VEval16ZoneTStz_TS_SkipEPciiPi |
Se o gráfico de chama estiver instalado, podemos executar:
1 2 3 | perf script /tmp/script.out FlameGraph-master/stackcollapse-perf.pl /tmp/script.out /tmp/flame_out.folded FlameGraph-master/flamegraph.pl /tmp/flame_out.folded /tmp/kernel.svg |
Cada chamada para a função new_time aciona a chamada do sistema operacional getTZoffset , enquanto muitas chamadas simultâneas estão causando contenção no kernel expressa por bloqueios de rotação .
Solução
Removemos o uso da função new_time e, em vez disso, começamos a juntar nossos dados a "tabelas de conversão".
Criamos duas tabelas de fuso horário que contêm um horário local para cada fuso horário e o horário correspondente no UTC:
1. time_zone_daily_conversion
2. time_zone_hourly_conversion
Definição de tabela diária
1 2 3 4 5 6 | Column | Type | Size | Default ----------------------------+------------------------+---------- time_zone_name | varchar(400) | 400 | day | date | 8 | NULL::date day_starts_at_utc | timestamp | 8 | NULL::timestamp day_ends_at_utc | timestamp | 8 | NULL::timestamp |
Exemplo de Conteúdo
1 2 3 4 5 6 7 | time_zone_name | day | day_starts_at_utc | day_ends_at_utc ---------------------+------------+---------------------+--------------------- Africa/Nairobi | 2017-07-28 | 2017-07-27 21:00:00 | 2017-07-28 20:59:59 America/Bogota | 2017-07-28 | 2017-07-28 05:00:00 | 2017-07-29 04:59:59 America/Mexico_City | 2017-07-28 | 2017-07-28 05:00:00 | 2017-07-29 04:59:59 America/Sao_Paulo | 2017-07-28 | 2017-07-28 03:00:00 | 2017-07-29 02:59:59 Asia/Bangkok | 2017-07-28 | 2017-07-27 17:00:00 | 2017-07-28 16:59:59 |
Definição de tabela horária
1 2 3 4 5 6 | Column | Type | Size | Default ---------------------+--------------+------+-----------------+--- hour_at_utc | timestamp | 8 | NULL::timestamp time_zone_name
মন্তব্য
|