赞
踩
去年到现在一直在做的传感器数据管理框架中使用到了mmap实现多个进程间的数据共享,为了更快的实现传感器数据写入到mmap中,同时便于查看和调试写入的数据,我们没有使用传统的文件来进行mmap映射,而是使用了/dev/shm目录作为临时文件充当mmap的源,这样将/dev/shm/a.dat文件进行mmap映射,可以加快写入速度和共享效率。原因就是/dev/shm虽然可以看做一个文件目录,但是它都是放在内存中的,重启后会消失,所以作为临时存储,效率会非常高,并且里面只存储了最新的一帧数据,内存消耗量不大。最好用的是,你可以使用相关的软件直接打开它,查看它的内容。
当时很早就想深入了解一下/dev/shm的啥原理,但是因为事情比较多给忘记了,前几天看了个帖子发现介绍了/dev/shm,说的还不错,就搬过来了。
一、/dev/shm理论
默认的Linux发行版中的内核配置都会开启tmpfs,映射到了/dev/下的shm目录。可以通过df 命令查看结果.
/dev/shm/是linux下一个非常有用的目录,因为这个目录不在硬盘上,而是在内存里。因此在linux下,就不需要大费周折去建ramdisk,直接使用/dev/shm/就可达到很好的优化效果。默认系统就会加载/dev/shm ,它就是所谓的tmpfs,有人说跟ramdisk(虚拟磁盘),但不一样(后面给出区别)。象虚拟磁盘一样,tmpfs 可以使用您的 RAM,但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备,并需要一个 mkfs 之类的命令才能真正地使用它,tmpfs 是一个文件系统,而不是块设备;您只是安装它,它就可以使用了。
tmpfs有以下优势:
二、修改/dev/shm大小
默认的最大一半内存大小在某些场合可能不够用,并且默认的inode数量很低一般都要调高些,这时可以用mount命令来管理它。
#mount -o size=1500M -o nr_inodes=1000000 -o noatime,nodiratime -o remount /dev/shm
在2G的机器上,将最大容量调到1.5G,并且inode数量调到1000000,这意味着大致可存入最多一百万个小文件。
如果需要永久修改/dev/shm的值,需要修改/etc/fstab
代码如下:
tmpfs /dev/shm tmpfs defaults,size=1.5G 0 0
mount -o remount /dev/shm
三、/dev/shm应用
首先在/dev/shm建个tmp文件夹,然后与实际/tmp绑定
代码如下:
#mkdir /dev/shm/tmp
#chmod 1777 /dev/shm/tmp
#mount –bind /dev/shm/tmp /tmp(–bind )
在使用mount –bind olderdir newerdir命令来挂载一个目录到另一个目录后,newerdir的权限和所有者等所有信息会发生变化。挂载后的目录继承了被挂载目录的所有属性,除了名称。
三、tmpfs和ramfs的区别
ramfs和tmpfs是在内存上建立的文件系统(Filesystem)。其优点是读写速度很快,但存在掉电丢失的风险。如果一个进程的性能瓶颈是硬盘的读写,那么可以考虑在ramfs或tmpfs上进行大文件的读写操作。
ramfs和tmpfs之间的区别:
特性 | tmpfs | ramfs |
达到空间上限时继续写入 | 提示错误信息并终止 | 可以继续写尚未分配的空间 |
是否固定大小 | 是 | 否 |
是否使用swap | 是 | 否 |
具有易失性 | 是 | 是 |
通过下面的方法可以查看系统中的tmpfs和ramfs:
ok@linux:~$ df -h | grep -E "(tmpfs|ramfs)" devtmpfs 1.9G 16K 1.9G 1% /dev tmpfs 1.9G 27M 1.9G 2% /dev/shm tmpfs 1.9G 4.3M 1.9G 1% /run tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup tmpfs 1.9G 4.3M 1.9G 1% /var/lock tmpfs 1.9G 4.3M 1.9G 1% /var/run
我的系统(Ubuntu 20.04,)中,使用的都是tmpfs。我想原因可能是,当存在写溢出时,tmpfs比ramfs更加安全,因为前者会给出错误提示并禁止写操作。
创建tmpfs:
ok@linux:~ # mkdir -p /mnt/tmp ok@linux:~ # mount -t tmpfs -o size=20m tmpfs /mnt/tmp/ ok@linux:~ # df -h | grep "/mnt/tmp" tmpfs 20M 0 20M 0% /mnt/tmp
创建ramfs:
ok@linux:~ # mkdir -p /mnt/ram ok@linux:~ # mount -t ramfs -o size=20m ramfs /mnt/ram/ ok@linux:~ # df -ah | grep "/mnt/ram" ramfs 0 0 0 - /mnt/ram
这里df只使用h选项是无法显示ramfs的内容的。tmpfs会对内存进行accounting(统计内存的使用情况),而ramfs被设计为尽可能的简单,所以不会进行accounting。因此,针对ramfs,在较新的内核中,使用df不会返回ramfs的信息。
ramfs是Linux下一种基于RAM做存储的文件系统。在使用过程中你就可以把ramfs理解为在普通的HDD上建立了一个文件系统,而现在HDD被替换成了RAM,因为是RAM做存储所以会有很高的存储效率。由于ramfs的实现就相当于把RAM作为最后一层的存储,所以在ramfs中不会使用swap。你什么时候听过会把HDD上的文件swap到哪里去吗?平常说的swap都是针对内存来说的,而ramfs底层的存储是RAM,虽然不是HDD,但是在Linux看来它就跟HDD一样。但是ramfs有一个很大的缺陷就是它会吃光系统所有的内存,即使你mount的时候指定了大小,同时它也只能被root用户访问。测试方法很简单:
sudo mount -t ramfs -o size=10M ramfs ./ramfs/
sudo dd if=/dev/zero of=./ramfs/test.file bs=1M count=20
测试时你会发现上面这个操作是能成功的,或者你再自己虚拟机上干脆做狠点,直接写一个比内存更大的文件,你会发现瞬间系统就卡主了。另外在dd命令如果不以root用户执行就会权限不够:
dd: opening `./ramfs/test.file': Permission denied
tmpfs也是Linux下的一个文件系统,它将所有的文件都保存在虚拟内存中,umount tmpfs后所有的数据也会丢失,tmpfs就是ramfs的衍生品。tmpfs使用了虚拟内存的机制,它会进行swap,但是它有一个相比ramfs的好处:mount时指定的size参数是起作用的,这样就能保证系统的安全,而不是像ramfs那样,一不留心因为写入数据太大吃光系统所有内存导致系统被hang住。在我文章最开始的那个例子中就是mount了一个10M大小的tmpfs,然后执行sql 命令(它需要创建的临时表大于10M),因为tmpfs限制了大小,因此也就报错。那么tmpfs适用的场景有哪些呢?在官方文档上主要有如下几点:
kernel 内部需要用到它,而我们是无法看到的
glibc 2.2以上的版本,必须有一个tmpfs被mount在/dev/shm用做POSIX shared memory
还有很多包括现在还不知道的用途
总结来说ramfs与tmpfs有如下几点异同:
两者都是用来提升效率,但是tmpfs比ramfs的性能更好(结果是对的,原理有待进一步探究)
参考链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。