Temos um servidor com 64 GB de RAM total, os aplicativos estão usando normalmente no máximo 30 GB dessa RAM disponível. Um desses aplicativos lida com muitos arquivos simples e estamos tendo problemas de taxa de transferência, ou seja, aguardando a E/S do disco. Ao explorar possíveis soluções, surgiu a ideia de um disco RAM. O problema que tenho com um disco RAM é a volatilidade inerente.
Encontrei documentação separada sobre discos RAM, configuração RAID 1 e volumes espelhados lógicos para agrupar discos físicos , mas não consigo encontrar nenhuma documentação que sugira se qualquer uma dessas soluções de replicação de disco pode ser usada com um disco RAM. Mais importante, já que a ideia é ter o disco RAM disponível para leitura/gravação e ter o disco físico "sombreando" o disco RAM, alcançando as gravações, gostaríamos que o disco RAM fosse o disco "primário" para todos lê/escreve.
Para observar, gostaríamos de evitar apenas o cache de arquivos da RAM com o sistema operacional, mas se pudermos obter o mesmo desempenho de um disco RAM autônomo, isso pode funcionar. Inicialmente, evitamos isso, pois muitas vezes determinados arquivos não são acessados por longos períodos de tempo, mas ainda precisam da velocidade de leitura/gravação sob demanda.
Você poderia usar
vmtouch
para resolver seu problema. Este é um utilitário que permite que você fixe certos arquivos ou mesmo diretórios inteiros e tudo sob eles no cache da página para que não sejam despejados, mesmo que não sejam acessados por longos períodos de tempo (que foi seu motivo inicial para não simplesmente contando com o cache da página). Isso requer no máximo a mesma quantidade de memória que seu disco RAM, ou menos na prática. Você ainda estará usando o cache de página, mas resultará em desempenho semelhante ao uso de um disco RAM para tudo (na verdade, desempenho superior, pois o driver MD não estará envolvido).Isso pode ser hackeado em conjunto, mas é uma má ideia e provavelmente tem vários problemas de confiabilidade e manutenção.
Acho que um RAID1 de RAMdisk e disco físico seria limitado ao desempenho do disco físico, já que parte da funcionalidade do RAID1 é garantir que ambas as cópias estejam sincronizadas.
Para leituras, pode haver algum benefício, porque o driver MD pode distribuir leituras entre diferentes dispositivos.
Possíveis etapas para criar isso:
losetup
para criar um dispositivo de bloco a partir do arquivo.mdadm
para criar a matriz com o dispositivo de bloco recém-criado e a partição de disco rígido correspondente.Eu não tentei isso sozinho, então é apenas um exemplo teórico de como isso poderia ser feito.
Em primeiro lugar, um disco RAM quase nunca é a resposta correta no Linux. Por ser um dispositivo de bloco, você acaba com qualquer leitura tendo que passar pela camada de bloco, pelo sistema de arquivos e pela camada VFS regular, e os dados acabam armazenados em cache na RAM, além de serem armazenados no disco RAM. Essa duplicação de dados, bem como o número de camadas adicionais envolvidas, é o motivo pelo qual o tmpfs existe no Linux, em vez de envolver a camada de blocos, um sistema de arquivos tmpfs apenas armazena dados diretamente no cache da página, ignorando toda a complexidade extra. Também ocorre o dimensionamento automático com base na quantidade de dados armazenados nele (em vez de ter que ter o tamanho definido antecipadamente) e pode até aproveitar o espaço de troca. Se você acha que precisa de um ramdisk, então 99% do tempo você realmente deveria estar usando o tmpfs.
Agora, no que diz respeito às soluções reais...
Se todos os seus dados realmente couberem na RAM, é muito melhor fixá-los todos na RAM, usando uma ferramenta como vmtouch ou fazendo com que o aplicativo mapeie todos os arquivos e chame mlock em todas as regiões mapeadas.
Se seus dados não couberem na RAM, você tem duas opções realistas:
Se você precisa de persistência, um RAMDISK não é a solução correta.
Eu sugiro fortemente investir em um par de disco NVMe rápido (leia-se: nível empresarial, com proteção contra perda de energia) para colocar em uma matriz RAID1 clássica (espelhado).
Eu fiz algo assim usando discos efêmeros da AWS, que são muito rápidos, mas não sobrevivem a um ciclo de ligar/desligar.
Tínhamos um "disco semente" que era um volume EBS barato normal de GP2 (GP3 agora) e estava em um RAID1 com os discos efêmeros rápidos
Eu criei um script bash para rc.local para descobrir com a
nvme list
saída do comando se havia um disco efêmero e juntá-lo ao ataque quando apropriado.No seu caso, algo na inicialização teria que criar o ramdisk, juntá-lo ao array degradado existente.
Os dois últimos são discos efêmeros de 900G cada.
O bom é que as gravações no dispositivo mdX persistirão por meio de reinicializações e desligamentos ordenados. É possível que desligamentos inesperados possam causar a perda de gravações.
Portanto, este é um substituto ruim para um backup - você ainda deve fazer backups usando qualquer método que funcione para você.
Se você tem tanto RAM livre (que pode conter a maioria desses arquivos e seus metadados), é provável que eles residam principalmente no cache de RAM e seu fator limitante não seja ler, mas escrevê-los.
Se for esse o caso, espelhar à força esse volume na RAM não trará nenhum desempenho.
No possível caso em que outra atividade de i/o constantemente expulsa seus arquivos da RAM, bloquear essa quantidade de RAM para sua solução semelhante a um disco provavelmente afetará esses outros processos de i/o.
Memcached, Redis
Você basicamente descreveu o Memcached e um pouco o Redis. Ambos são bons em cache, o Redis tem melhor suporte para persistência.
Observe que você só pode obter "todo" o desempenho se esses arquivos simples tiverem menos de 30 GB de tamanho total (em sua máquina), caso contrário, algum mecanismo de despejo deve ser empregado. Mesmo assim, se este aplicativo usa alguns arquivos com muita frequência, uma solução Redis/Memcached aumentaria o desempenho.
Esses produtos são bem suportados pelos fornecedores, então você pode usar servidores Memcached/Redis hospedados externos para isolar completamente sua máquina das especificidades do cache.
A questão é sobre a velocidade e persistência do disco RAM . Isso é possível desde que se permita gravações assíncronas (mantenha o disco "acompanhando as gravações").
Desde que o aplicativo evite usar
sync
oufsync
, ele roda mais rápido e é mais fácil de configurar usando o cache regular sem usar um disco RAM e uma configuração de volume espelhado.Para manter o aplicativo em execução, mesmo que ele grave grandes quantidades de dados que sujam grandes quantidades de memória, é necessário permitir 32 GB de memória suja no caso desta questão. Isso mantém todas as gravações de disco nos threads de liberação do kernel longe do processo do aplicativo e é configurado por
sysctl vm.dirty_bytes=$((32*1024*1024*1024)) # 32 GB
(O padrão é
sysctl vm.dirty_ratio=20
que não permite que mais de 20% da memória "disponível" fique suja, afogando o aplicativo se esse limite for atingido, o que acontece muito antes de 32 GB de memória ficarem sujos.)Como o aplicativo "lida com muitos arquivos simples", suspeito que ele tenha um comportamento de leitura linear, de modo que a pré-busca explícita dos dados não seria útil. Mas se tivesse um comportamento de leitura aleatório, o cache deveria ser aquecido antes de iniciar o aplicativo.