文件存储之-内存文件系统tmpfs
前言
我们都知道,对于单台服务器来说,除了 CPU ,内存就是我们存储数据最快的设备。如果可以把数据直接存储在内存中,对于性能的提升就不言而喻了。那么我们先来讲讲如何使用内存来存储文件。
首先,我们先来看看操作系统,在你的系统中执行 df –h 查看系统的磁盘使用。
[root@test conf]#netstat -na | grep 192.168.99.159:80
tcp 0 0 192.168.99.159:80 192.168.99.50:24584 ESTABLISHED
你会发现除了我们正常的磁盘分区挂载点外,系统还有一种叫做 devtmpfs 的文件系统,和多个 tmpfs。那么什么是 tmpfs 呢?
tmpfs 简介
tmpfs 是 Linux/Unix 系统上的一种基于内存的文件系统。 tmpfs 可以使用您的内存或 swap 分区来存储文件。在 Redhat/CentOS 等 linux 发行版中默认大小为物理内存的一半。例如上面的案例中,我执行 df -h 的服务器是 64G 内存。
首先我们要说明, tmpfs 既可以使用物理内存,也可以使用交换分区,因为 tmpfs 使用的是 “ 虚拟内存 ” 。 Linux 内核的虚拟内存同时来源于物理内存和交换分区,主要由内核中的 VM 子系统进行调度,进行内存页和 SWAP 的换入和换出操作, tmpfs 自己并不知道这些页面是在交换分区还是在物理内存中。
tmpfs 使用
如果你想使用 tmpfs ,那么最简单的办法就是直接将文件存放在 /dev/shm 下,虽然这并不是推荐的方案,因为 /dev/shm 是给共享内存分配的,共享内存是进程间通信的一种方式。
下面我们来做一个小实验,检验下 tmpfs 的特性,首先我们可以看到我目前的系统 /dev/shm 的使用是 12K ,可用的内存为 62237 。
[root@linux-node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 1.1T 2.8G 1.1T 1% /
devtmpfs 32G 0 32G 0% /dev
tmpfs 32G 12K 32G 1% /dev/shm
**省略部分输出**
[root@test conf]#netstat -na | grep 192.168.99.159:80
tcp 0 0 192.168.99.159:80 192.168.99.50:24584 ESTABLISHED
这里我准备了一个 81M 的文件,我准备把它放入到 tmpfs 中。
# ls -lh /usr/local/src/
total 81M
-rw-r--r-- 1 root root 81M Apr 14 22:46go1.6.1.linux-amd64.tar.gz
# cp/usr/local/src/go1.6.1.linux-amd64.tar.gz /dev/shm/
下面我们再来看磁盘大小和内存大小。可以发现 /dev/shm 的大小变成了 81M ,可用内存变成了62156 。
[root@linux-node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 1.1T 2.8G 1.1T 1% /
devtmpfs 32G 0 32G 0% /dev
tmpfs 32G 81M 32G 1% /dev/shm
**省略部分输出**
[root@linux-node1 ~]# free -m
total used free shared buff/cache available
Mem: 64152 1445 60386 123 2320 62156
Swap: 16383 0 16383
我们来做一个小学数学题
-
可用内存: 62237-62156=81 ,证明我们放置的 81M 的文件是使用了内存空间。
-
共享内存: 123-42=81 ,证明 /dev/shm 是 Linux 给共享内存使用的
好的,现在你可以将这个 81M 的文件移动走,会发现内存使用率恢复如初,可以证明 tmpfs 是动态变化的,数据被移除后,所占用的虚拟内存也会被释放,这里我不在截图了,大家可以自行实验。
tmpfs 挂载
与其他文件系统不同, tmpfs 无需要建立或格式化,只需要直接使用 mount 挂载就会自动被建立:
# mount -t tmpfs tmpfs /mnt/tmp
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 1.1T 2.7G 1.1T 1% /
**省略部分输出**
tmpfs 32G 0 32G 0% /mnt/tmp
现在我们就挂载了一个 tmpfs 文件系统到 /mnt/tmp 目录下,默认它是系统内存的一半,你可以自由的使用它,那么我们第一个问题就是,如何能够自定义分配的内存大小, tmpfs 支持相关的选项来让用户自定义
Linux 上的 tmpfs 支援三个挂载选项:
-
size - 设定分配给此 tmpfs 文件系统的内存上限,默认是内存的一半。也可以在尾加上百分比 (%) 表示占用内存的百分比, 0 表示没有上限。
-
nr_blocks - 和 size 一样设定分配内存上限,但单位为 PAGE_CACHE_SIZE ( 默认为 4 KiB) 。
-
nr_inodes - 设定此 tmpfs 文件系统的 inode 上限,也就是限制可以存放文件的总数。
以上三个选项都可以在数值后面加上 k 、 m 、 g 来表示单位。
你可以在挂载的时候直接使用这些选项
# mount-t tmpfs -o size=1G tmpfs /mnt/mytmpfs
也可以在挂载后,重新挂载 (remount) tmpfs 即可改变内存上限:
# mount -o remount,size=512m/mnt/tmp
tmpfs 的优势
下面我们来总结一下 tmpfs 的优势,其实我们已经证明过了。
1.存储空间动态变化
在 tmpfs 存放的文件是动态占用内存空间的,随着文件占用空间的增大而增大文件系统,文件被删除时,动态地减小文件系统空间并释放内存。这一切都是 tmpf 自动处理的。
2.速度
天下武功,唯快不破。 tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在内存中,读写几乎可以是瞬间的。即使用了一些交换分区,性能仍然是非常快的。
3.没有持久性
当你喜欢一个东西的时候,它的缺点在你眼里也会是优点,没有持久性其实是 tmpfs 的缺点,所以一定不要把系统关机或者重启后还需要保存的数据放入 tmpfs 。因为虚拟内存本质上就是易失的,但正是这种特性,实际上可能不是一件坏事。它让 tmpfs 成为一个保存您不想在系统重启后保留的数据的卓越的文件系统。
tmpfs 应用案例
以下是使用 tmpfs 文件系统的一些应用示例,一般 tmpfs 内存文件系统在做 web 缓存, cache,临时文件存储时会对 web 访问有很好的加速作用,从而提高网站访问的速度。
1. 反向代理缓存中,缓存目录使用 tmpfs
例如下面是 Nginx 作为反向代理缓存的配置片段,可以将 /data/cdn_cache 目录挂载为 tmpfs 。
proxy_temp_path /data/cdn_cache/proxy_temp_dir;
proxy_cache_path /data/cdn_cache/proxy_cache_dirlevels=1:2 keys_zone=cache_one:50m inactive=1d
2 . 将 php 的 session 文件放在 tmpfs 下
PHP 保存 seesion 的方法很简单 , 只要修改 php.ini 就行了,首先挂载好 tmpfs ,然后修改配置文件如下:
session.save_path = “/data/php_session”
3. 将服务的 socket 文件放在 tmpfs 下
例如在 Web 应用中,我们有 PHP 的 FastCGIsocket 、 MySQL 的 mysql.sock 等等类似的socket 文件,都可以放在 tmpfs 挂载的目录下提高性能。