Nota do tradutor.: este artigo é uma síntese de uma mini-pesquisa realizada pelos engenheiros da IBM Cloud em busca de uma solução para um problema real relacionado à operação do banco de dados etcd. A nós, era pertinente uma tarefa semelhante, porém o raciocínio e as ações dos autores podem ser interessantes em um contexto mais amplo.

Resumo curto de todo o artigo: fio e etcd
O desempenho do cluster etcd depende fortemente da velocidade do armazenamento subjacente. Para monitorar o desempenho, o etcd exporta várias métricas do Prometheus. Uma delas é wal_fsync_duration_seconds. Na documentação do etcd , que o armazenamento pode ser considerado suficientemente rápido se o 99º percentil dessa métrica não ultrapassar 10 ms…
Se você está considerando organizar um cluster etcd em máquinas que rodam Linux e deseja verificar se os seus dispositivos de armazenamento (por exemplo, SSDs) são suficientemente rápidos, recomendamos usar um testador de I/O popular chamado . Basta executar o seguinte comando (o diretório test-data deve estar localizado na partição montada do dispositivo que está sendo testado):
fio --rw=write --ioengine=sync --fdatasync=1 --directory=test-data --size=22m --bs=2300 --name=mytestAgora, basta observar a saída e verificar se o 99º percentil está dentro de 10 ms. Se assim for, seu dispositivo está funcionando rapidamente o suficiente. Aqui está um exemplo de saída:
fsync/fdatasync/sync_file_range:
sync (usec): min=534, max=15766, avg=1273.08, stdev=1084.70
sync percentiles (usec):
| 1.00th=[ 553], 5.00th=[ 578], 10.00th=[ 594], 20.00th=[ 627],
| 30.00th=[ 709], 40.00th=[ 750], 50.00th=[ 783], 60.00th=[ 1549],
| 70.00th=[ 1729], 80.00th=[ 1991], 90.00th=[ 2180], 95.00th=[ 2278],
| 99.00th=[ 2376], 99.50th=[ 9634], 99.90th=[15795], 99.95th=[15795],
| 99.99th=[15795]Algumas observações:
- No exemplo acima, ajustamos os parâmetros
--sizee--bsde acordo com o caso específico. Para obter um resultado significativo defio, forneça valores que sejam adequados para o seu cenário de uso. Como escolher esses valores será abordado a seguir. - Durante o teste, apenas
fiocarrega o subsistema de disco. Na vida real, é bem provável que outros processos também estejam escrevendo no disco (além dos relacionados awal_fsync_duration_seconds). Essa carga adicional pode levar a um aumento emwal_fsync_duration_seconds. Em outras palavras, se o 99º percentil obtido ao final dos testes comfio, apenas um pouco menos de 10 ms, há uma grande probabilidade de que o desempenho do armazenamento seja insuficiente. - Para o teste, você precisará da versão
fionão inferior a 3.5, pois versões mais antigas não agregam resultadosfdatasyncem forma de percentis. - A saída acima é apenas um pequeno trecho da saída total
fio.
Detalhes sobre fio e etcd
Algumas palavras sobre WALs do etcd
Normalmente, bancos de dados utilizam (write-ahead logging, WAL). Isso também se aplica ao etcd. A discussão sobre WAL vai além do escopo deste artigo, no entanto, para nossos propósitos, é importante saber o seguinte: cada membro do cluster etcd armazena o WAL em um armazenamento persistente. O etcd registra algumas operações com o armazenamento key-value (por exemplo, atualizações) no WAL antes de executá-las. Se um nó falhar e reiniciar entre os snapshots, o etcd poderá recuperar as transações que ocorreram desde o último snapshot, com base no conteúdo do WAL.
Assim, toda vez que um cliente adiciona uma chave ao armazenamento KV ou atualiza o valor de uma chave existente, o etcd adiciona uma descrição da operação no WAL, que é um arquivo regular no armazenamento persistente. Antes de continuar o trabalho, o etcd DEVE ter 100% de certeza de que a gravação no WAL foi realmente salva. Para conseguir isso no Linux, não basta usar a chamada de sistema , pois a própria operação de gravação no meio físico pode ser adiada. Por exemplo, o Linux pode manter a gravação do WAL no cache do kernel na memória (por exemplo, no cache de páginas) por algum tempo. Para garantir que os dados sejam gravados no meio, após a gravação deve-se acionar a chamada de sistema fdatasync — é assim que o etcd procede (como pode ser visto no exemplo da próxima saída ; aqui 8 — o descritor de arquivo do WAL):
21:23:09.894875 lseek(8, 0, SEEK_CUR) = 12808
21:23:09.894911 write(8, ". 20210220361223255266632$10 20103026"34"rn3fo"..., 2296) = 2296
21:23:09.895041 fdatasync(8) = 0 Infelizmente, a gravação no armazenamento persistente leva algum tempo. A execução prolongada da chamada fdatasync pode afetar o desempenho do etcd. Na documentação do armazenamento , que para um desempenho adequado, o 99º percentil da duração de todas as chamadas deve fdatasync O tempo para registrar no arquivo WAL foi inferior a 10 ms. Existem outras métricas relacionadas ao armazenamento, mas este artigo focará especificamente nesta.
Avaliando o armazenamento com fio
Para avaliar se um determinado armazenamento é adequado para uso com etcd, pode-se utilizar a ferramenta — um testador de I/O popular. Tenha em mente que a entrada e saída de disco podem ocorrer de várias maneiras: sync/async, múltiplas classes de chamadas do sistema, etc. O lado negativo é que fio é extremamente complexa de usar. A ferramenta possui muitos parâmetros, e diferentes combinações de valores podem levar a resultados completamente diferentes. Para obter uma avaliação razoável no caso do etcd, você deve garantir que a carga de gravação gerada pelo fio se assemelhe ao máximo à carga do etcd ao gravar nos arquivos WAL:
- Isso significa que a carga gerada
fiodeve, pelo menos, se representar como uma série de gravações sequenciais em um arquivo, onde cada operação de gravação consiste em uma chamada de sistema , seguida porfdatasync. - Para habilitar a gravação sequencial, é necessário especificar a flag
--rw=write. - Para
fioescreveu usando chamadasexit(e não outras chamadas do sistema — por exemplo, ), use a flag--ioengine=sync. - Por fim, a flag
--fdatasync=1garante que após cadaexitdevefdatasync. - Outros dois parâmetros no nosso exemplo:
--sizee--bs— podem variar dependendo do cenário de uso específico. Na próxima seção, descreveremos como configurá-los.
Por que escolhemos fio e como aprendemos a configurá-lo
Esta nota surgiu de um caso real com o qual nos deparamos. Tivemos um cluster no Kubernetes v1.13 com monitoramento no Prometheus. Os discos de estado sólido foram utilizados como armazenamento para o etcd v3.2.24. As métricas do etcd mostravam latências muito altas fdatasync, mesmo quando o cluster estava ocioso. Essas métricas nos pareciam bastante duvidosas, e não estávamos certos sobre o que exatamente elas representavam. Além disso, o cluster consistia em máquinas virtuais, por isso não conseguíamos afirmar se a latência estava relacionada à virtualização ou se os SSD eram os culpados.
Além disso, consideramos várias alterações na configuração de hardware e software, portanto, precisávamos de uma maneira de avaliá-las. Claro, poderíamos executar o etcd em cada configuração e observar as respectivas métricas do Prometheus, mas isso exigiria um esforço considerável. Precisávamos de uma maneira simples de avaliar uma configuração específica. Queríamos verificar nossa compreensão das métricas do Prometheus recebidas do etcd.
Para isso, era necessário resolver dois problemas:
- Primeiro, como se parece a carga de I/O gerada pelo etcd ao gravar nos arquivos WAL? Quais chamadas de sistema são usadas? Qual é o tamanho dos blocos de gravação?
- Em segundo lugar, suponha que temos as respostas para as perguntas acima. Como reproduzir a carga correspondente com
fio? Ведьfio— uma ferramenta extremamente flexível com uma abundância de parâmetros (é fácil de verificar, por exemplo, — nota do tradutor).
Resolvemos ambos os problemas com a mesma abordagem, baseada em comandos e :
- Com
lsofpode-se ver todos os descritores de arquivo utilizados pelo processo, bem como os arquivos a que se referem. - Com
stracepode-se analisar um processo já em execução ou iniciar um processo e observá-lo. O comando exibe todas as chamadas de sistema realizadas por esse processo e, se necessário, seus descendentes. O último é importante para processos que fazem fork, e o etcd é um desses processos.
A primeira coisa que fizemos foi usar strace para examinar o servidor etcd no cluster Kubernetes enquanto estava ocioso.
Assim, foi descoberto que os blocos de gravação no WAL estão muito intimamente agrupados, a maioria tinha um tamanho na faixa de 2200-2400 bytes. É por isso que o comando no início deste artigo usa a flag --bs=2300 (bs — o tamanho em bytes de cada bloco de gravação em fio).
Observe que o tamanho dos blocos de gravação do etcd pode variar dependendo da versão, do deployment, dos valores dos parâmetros etc. — isso afeta a duração fdatasync. Se você tem um cenário de uso semelhante, analise com strace seus processos etcd para obter valores atualizados.
Em seguida, para obter uma visão clara e abrangente do funcionamento do etcd com o sistema de arquivos, nós o executamos com strace com as flags -ffttT. Isso permitiu abranger processos filhos e gravar a saída de cada um em um arquivo separado. Além disso, foram obtidas informações detalhadas sobre o momento de início e a duração de cada chamada de sistema.
Também utilizamos o comando lsof, para confirmar nossa compreensão da saída strace no que diz respeito a qual descritor de arquivo foi usado para qual finalidade. A saída resultante strace, foi semelhante àquela apresentada acima. As manipulações estatísticas sobre os tempos de sincronização confirmaram que a métrica wal_fsync_duration_seconds do etcd corresponde às chamadas fdatasync com os descritores de arquivos WAL.
Para gerar usando fio uma carga de trabalho semelhante à carga do etcd, a documentação da ferramenta foi estudada e os parâmetros adequados para nossa tarefa foram escolhidos. Certificamo-nos de que as chamadas de sistema necessárias estavam em uso e confirmamos sua duração, executando fio do strace (como foi feito no caso do etcd).
Uma atenção especial foi dada à definição do valor do parâmetro --size. Ele representa a carga total de I/O gerada pela ferramenta fio. Em nosso caso, é o total de bytes gravados no meio. É diretamente proporcional ao número de chamadas exit (e fdatasync). Para um certo bs número de chamadas fdatasync for igual a size / bs.
Como estávamos interessados no percentil, buscamos que o número de amostras fosse grande o suficiente para significância estatística. E decidimos que 10^4 o que corresponde a um tamanho de 22 MB seria suficiente. Valores menores do parâmetro --size geravam um ruído mais pronunciado (por exemplo, chamadas fdatasync, que levam muito mais tempo do que o habitual e afetam o 99º percentil).
Agora é sua vez
O artigo mostra como usar fio para avaliar se um meio destinado ao uso com o etcd é rápido o suficiente. Agora é sua vez! Explorar máquinas virtuais com armazenamento baseado em SSD pode ser feito no serviço .
P.S. do tradutor
Com exemplos prontos de uso fio para resolver outras tarefas, você pode consultar ou diretamente em (muito mais exemplos estão apresentados lá do que menciona a documentação).
P.P.S. do tradutor
Confira também em nosso blog:
- «»;
- «»;
- «».
Fonte: habr.com
