Armazenando Arquivos Na Memória RAM Com tmpfs

Introdução

Você provavelmente já ouviu falar que a memória RAM é mais rápida que o disco. Podemos utilizar esse fato para agilizarmos operações de I/O em grandes arquivos em disco, apenas mudando o local de armazenamento para a memória principal. Além desse quesito velocidade, a memória RAM também é volátil, isto é, os dados ali presentes serão perdidos caso o sistema seja desligado ou reiniciado. Esse fato implica que a RAM pode ser usada para armazenamento temporário, como arquivos de sessões do PHP, arquivos temporários do servidor e do navegador WEB (ex: cache do firefox).

Essa mágica toda é feita com o formato de arquivos tmpfs, suportado por alguns sistemas, inclusive o Linux.

No post de hoje iremos aprender como criar partições na memória RAM, e também como redimensioná-las e usá-las como armazenamento temporário.

O tmpfs (Temporary File System)

RAM disk [1] nada mais é que uma área na memória RAM que simula uma partição do disco. Desse modo, podemos armazenar, apagar e editar arquivos nessa área, como fazemos em disco. Muitos sistemas operacionais dão suporte a RAM disk, e no Linux, temos algo similar, que é oferecido pelo tmpfs.

O tmpfs é um sistema de arquivos temporário usado em partições na memória principal. Numa abordagem mais técnica, o tmpfs nada mais é que uma interface entre você e o gerenciador de memória virtual do kernel. Quando o tmpfs precisa de espaço para armazenar um arquivo, ele requisita páginas de memória a esse gerenciador, que pode liberar tanto páginas da RAM quanto do disco (partição swap). A medida que espaços são liberados na partição, as páginas de memória utilizadas também são liberadas pelo gerenciador.

Como as páginas requisitadas do tmpfs podem vir tanto da RAM quanto do disco, alguém pode argumentar que o desempenho nessas partições não é maior que  nas partições em disco. Embora isso seja verdade, na maioria das vezes as partições tmpfs ocupam boa parte da memória RAM, e o desempenho nessas partes aumenta bastante o desempenho geral.

Listando partições na memória

É bem possível que seu sistema já tenha algumas partições na memória principal. Para verificar isso, digite:

$ mount | grep tmpfs
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,seclabel)
tmpfs on /run type tmpfs (rw,nosuid,nodev,seclabel,mode=755)
tmpfs on /sys/fs/cgroup type tmpfs (rw,nosuid,nodev,noexec,relatime,seclabel,mode=755)
tmpfs on /media type tmpfs (rw,nosuid,nodev,noexec,relatime,seclabel,mode=755)

A minha máquina tem algumas partições. A primeira delas, a /dev/shm, tem as mesmas permissões do diretório /tmp, inclusive com a flag t ativada:

$ ls -lad /dev/shm
drwxrwxrwt. 2 root root 280 Aug  3 22:18 /dev/shm/

É interessante notar que o tamanho dessas partições é metade de sua memória RAM. Isto é, se sua memória é de 4GB, então cada uma dessas partições terá 2GB de memória.

$ df -h /dev/shm /sys/fs/cgroup /run
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           2.0G  126M  1.9G   7% /dev/shm
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
tmpfs           2.0G  2.5M  2.0G   1% /run

Esse valor de 2GB é o tamanho máximo que a partição pode chegar. Esse valor pode ser mudado, como veremos adiante.

Usando o /dev/shm

Essa partição já vem montada por padrão e pode ser acessada por qualquer usuário, pois ela tem permissões iguais a do diretório /tmp.

$ cp /etc/passwd /dev/shm
$ ls -la /dev/shm/passwd
-rw-r--r--. 1 daemonio daemonio 2396 Aug  3 22:08 /dev/shm/passwd

Redimensionando partições

Utilizando o mount, podemos redimensionar o tamanho dessas partições:

$ sudo mount -o remount,size=3GB /dev/shm

O tamanho da partição agora é de 3GB. Quando você for alterar o tamanho de uma partição, tome muito cuidado, pois a partição realmente pode crescer até esse valor, e usar boa parte de sua RAM que poderia ser usada em outros processos. Em [2], há um meio seguro de se calcular esse valor.

Criando sua própria partição tmpfs

Usando o tipo tmpfs no comando mount, podemos criar uma partição na memória secundária.

$ mkdir ~/particao # Ponto de montagem
$ sudo mount -t tmpfs -o size=100M,mode=0755 tmpfs ~/particao
$ mount | grep particao
tmpfs on /home/daemonio/particao type tmpfs (rw,relatime,seclabel,size=102400k,mode=755)

Basta agora acessar a sua nova partição através do diretório ~/particao. A permissão 755 garante que só o root poderá modificar e criar arquivos nessa partição. Altere a permissão para mode=1777 para que as permissões semelhantes àquelas do diretório /tmp sejam usadas.

Vantagens de se usar tmpfs

Essa idéia de partição na memória parece interessante, mas será que nos traz benefícios? A seguir, listarei alguns deles. [2]

1) Tamanho dinâmico

O tmpfs, como disse bem no início, utiliza o sistema de memória virtual do kernel. Assim, quando mais espaço for necessário na partição, o tmpfs requisitará uma nova página para o gerenciador de VM (Virtual Memory). Quando espaços forem liberados no tmpfs, as páginas usadas por ele também serão liberadas no VM. Assim, partições tmpfs começam com um tamanho mínimo e vão crescendo quando necessário. Esse comportamento evita ocupação de espaços fixos na RAM, permitindo um melhor compartilhamento de memória.

2) Velocidade

Como a RAM é bem superior que o disco em questão de velocidade, as operações de I/O em partições tmpfs são executadas bem mais rápidas. Embora o gerenciador de VM possa armazenar algumas páginas do disco, a velocidade total é ainda melhor, pois algumas páginas estarão na RAM.

Se você precisa de realizar operações que utilizam muito o disco, como extração de texto e ordenação de arquivos, é bem mais prático você copiar esses arquivos para uma partição tmpfs, realizar as operações lá, e por fim, copiar o resultado final de volta para o disco. Isso diminuirá o tempo total das operações significantemente.

3) Sem persistência

Dados persistentes são aqueles que continuam a existir mesmo quando o sistema é desligado. O tmpfs oferece uma não persistência de dados, isto é, tudo armazenado nele será destruído quando o sistema for desligado, ou quando a partição for desmontada. A primeira vista isso não parece interessante, mas é bem útil naquelas situações em que os dados não precisam ser guardados (ex: seu diretório /tmp está cheio de arquivos não utilizados, e estão ocupando espaço).

Outra coisa legal sobre isso é algo que li na phrack [3], e na verdade foi isso que me motivou a criar esse post. Após entrar num sistema, por exemplo, um atacante pode muito bem criar uma partição tmpfs e armazenar seus arquivos lá. Ele, então, faz o que tem que fazer: compilar programas, executá-los, etc. Em seguida, ele desmonta a partição e os arquivos serão apagados automaticamente. Desse modo, se o administrador do sistema perceber a invasão, ele enfrentará problemas em recuperar os arquivos usados pelo atacante, pois eles não foram armazenados em disco.

Conclusão

O tmpfs é um recurso bastante interessante, pois nos permite criar partições na memória principal. Esse fato nos oferece alguns benefícios, como por exemplo, um maior desempenho nas operações de I/O em relação ao disco. Por não ser persistente, partições tmpfs podem ser usadas para armazenamento temporário, como cache de servidores e navegadores WEB, sessões PHP e podem até mesmo substituir o diretório físico /tmp, como jáa acontece em muitas distribuições atuais.

Referências

[1] RAM disk by wikipedia (Acessado em: Agosto/2012)
http://en.wikipedia.org/wiki/RAM_disk

[2] Using the virtual memory (VM) filesystem and bind mounts by Daniel Robbins (Acessado em: Agosto/2012)
http://www.ibm.com/developerworks/library/l-fs3/index.html

[3] A brief history of the Underground scene by The Circle of Lost Hackers (Acessado em: Agosto/2012)
http://www.phrack.org/issues.html?issue=64&id=4#article

[4] tmpfs by wikipedia (Acessado em: Agosto/2012)
http://en.wikipedia.org/wiki/Tmpfs

[5] Storing Files/Directories In Memory With tmpfs by Falko Timme (Acessado em: Agosto/2012)
http://www.howtoforge.com/storing-files-directories-in-memory-with-tmpfs