Linux IO知识集锦
参考:
在UNIX的世界里,Terminal、TTY、Console这些术语是紧密相关的,一般可以认为Terminal就是TTY,Console则是指物理存在的Terminal。
终端(Terminal)起源于大型主机的时代,由于昂贵的造价,多名工作人员必须共享主机——通过一根电缆线,一端连接着主机,另外一端连接着电传打字机(TTY),这个TTY就是终端——基于文本的输入/输出环境。
Linux中某些TTY是内核专门用于特定硬件的,例如:
- 键盘输入 + 文本模式显示器输出
- 通过串口线进行的输入输出
其它的一些TTY,被称为伪(不存在对应的硬件)终端(pseudo-ttys),这类终端由一类称为终端仿真器(terminal emulators)的应用程序(例如 Xterm、 Screen、SSH)提供。伪终端常常关联到一个Shell会话。
控制台(Console)通常是指直接连接到机器的主终端(primary terminal)。
在Linux、FreeBSD之类的系统中,控制台对应了多个TTYs,例如Ubuntu会自动创建虚拟控制台(virtual console ),tty1-tty6,它们都可以通过控制台键盘快捷键启用。
系统主控制台,内核代码 printk()总是向此控制台写入消息。第一个非内核进程,也就是init,也将/dev/console作为标准输入、输出、错误。
/dev/console是一个可以通过内核参数进行重定向的虚拟设备集。你可以在grub.conf中配置 console=ttyS0,这样/dev/console就重定向到了/dev/ttyS0。你还可以在grub.conf中多次配置console参数,这样内核主控制台的输出被传播到多个设备。
这是一个别名,对应打开/dev/tty的那个进程所关联的(物理,虚拟,伪)控制台。打开/dev/tty进行读写,不需要root权限。
需要注意,cron之类批处理服务启动的进程,没有关联的控制台,因而也就没有可用的/dev/tty。这类进程的 ps -ef输出的TTY列显示为 ?。
原本含义是连接到服务器的串口终端设备。现在/dev/tty0总是表示当前控制台,而/dev/tty1…对应Ctrl + Alt + F1…切换到的那些虚拟控制台。
代表连接到服务器的串口终端设备。有段时间串口设备被称为终端设备,因为那时串口设备的主要用途就是用作终端。
在top输出中,IOWait,也就是%wa,是CPU空闲时间的子类别(不包含在%idle),它是由于等待IO完成导致的。
精确的说,IOWait是消耗在接收、处理硬件中断的时间 —— 以占据处理器tick的百分比计算。
解决高IOWait的方法:
- 更好的硬件
- 保证系统有足够的缓存,作为页缓存
- 保证磁盘利用率小于80%,避免碎片化
- 编程时使用缓冲
如果没有IO调度器,内核只能简单的将请求转发给磁盘,这会导致磁头反复移动,性能非常差。从2.6版本开始,Linux内核支持选择IO调度器,以便基于不同的工作负载来优化IO性能。
IO调度器通过以下技术来优化磁盘访问性能:
- 请求合并:将相邻(磁道)的请求合并,减少寻道
- 电梯:根据请求针对的物理位置,进行排序,尽可能单个方向进行寻道
- 优先级:优先请求重要请求
IO调度器必须要考虑请求饿死的情况,确保任何请求最终能得到处理。
执行下面的命令,查看当前使用何种IO调度器:
1 |
cat /sys/block/sda/queue/scheduler |
1 |
echo noop > /sys/block/hda/queue/scheduler |
编辑/boot/grub/grub.conf文件,在内核命令行添加 elevator=noop,表示默认使用noop调度器。
IO调度器 | 说明 |
noop | 仅仅实现请求合并功能 |
as |
老版本2.6内核的默认调度器。实现请求合并、单向电梯、读写请求批处理,并且尝试进行一些预测性读 对于数据库、存储系统来说,可能导致性能的不稳定 |
deadline |
实现请求合并、单向电梯,并且为所有IO操作强加了一个deadline,避免了饿死现象 由于在Linux中写操作立即返回(使用Page cache),因此该调度器更加优先考虑读请求 —— 只要写请求的deadline尚未到达 对于数据库系统、TCQ感知磁盘、高性能磁盘,可以选择该调度器 |
cfq |
实现请求合并、电梯。倾向于在一段时间内,服务特定设备的所有用户相同的IO请求次数 对于多用户系统更加高效 |
- 依据POSIX标准,文件系统至少维护文件的以下属性:文件类型、硬链接计数、长度(字节)、设备ID、inode、文件所有者UID、文件所属GID、若干时间戳
- Inode:索引节点。内核为每个文件分配的符号,具有唯一标识符,存放在文件系统特殊的数据块中。文件元数据(创建日期、修改日期、访问权限文件大小、文件位置等)存放于其中。删除文件时,系统会将指向目标Inode的计数减1,如果计数为0,则表示该节点及其指向的数据不再被使用,磁盘上相应的位置会被标记为可用空间
- 硬链接:一个指向其他文件(不能目录)的指针,不能跨文件系统。与原文件Inode一致,本质上是等同的关系,相当于别名
- 软链接(符号链接):具有独立的Inode。目标文件移走了则无法访问。可以跨文件系统、可以指向目录
- 交换分区:swap分区,虚拟内存专用的单独分区
Linux对文件的定义与Windows很不相同,在Linux中,设备、进程等概念均映射到文件。这个特性和JNDI等目录服务比较类似,相当于任何资源均使用一个URI表示。实际上,在Linux中任何支持通过文件API操作的事物,都被作为文件看待,包括网络服务、内核组件、基于内存的虚拟磁盘等。
Linux甚至还有一个“环回(Loopback)”文件系统,允许把单个文件当作文件系统,挂载到目录树中:
1 |
mount -o loop /home/alex/unbunt-14.02.iso /mnt/cdrom |
1 |
mount --bind /proc/self/ns/net mynetns |
绑定挂载具有打开被绑定者的文件描述符的效果,你甚至可以绑定挂载到自己,这种情况下,文件既是挂载目标,也是挂载点。尝试删除会提示Device or resource busy,需要先umount,再删除。
绑定挂载后,你可以删除掉目标,此时挂载点的内容保持不变,底层文件依然存在。
配置文件/etc/fstab包含了静态文件系统信息,用于自动化磁盘分区的挂载过程。
所谓挂载,就是准备好物理分区,并将其分配到文件系统目录树中的某个节点(挂载点)的过程。
fstab具有一下特点:
- fstab文件一般可以用于:内部设备、光驱设备、网络共享设备(例如:samba、nfs、sshfs)。可拔插设备(例如U盘)通常不编写在fstab
- fstab可以在启动时自动挂载某个分区
- 如果设备或者分区没有在fstab中列出,那么只有ROOT才能进行mount
fstab中每行可以具有以下列(以Ubuntu为例说明):
列 | 说明 |
file system |
包含文件系统的/设备/分区,支持以下形式: Ubuntu中,默认使用UUID识别分区,例如UUID=xxx.yyy.zzz,可以使用sudo blkid命令列出UUID |
mount point |
挂载点,根文件系统中的一个节点。交换分区(swap)没有挂载点。挂载点名称中不得有空格。 默认挂载点是/media,其它任何位置都是可以的,例如/mnt。挂载点必须首先使用mkdir创建 |
type |
文件系统的类型,例如: auto、vfat(FAT分区)、ntfs, ntfs-3g(NTFS分区)、ext4, ext3, ext2,、udf,iso9660(光盘分区)、swap(交换分区) |
options |
对应mount命令的挂载选项 可以使用默认选项(defaults = rw, suid, dev, exec, auto, nouser, and async) 常用选项: sync/async 所有的I/O应当同/异步完成 |
dump | 是否启用分区备份,一般否0 |
pass | 系统启动时检查分区错误的顺序,根设备应该是1,其它2,0禁止检查 |
fstab示例内容如下:
1 2 3 4 5 6 7 8 9 10 |
root@localhost:~# cat /etc/fstab # proc /proc proc defaults 0 0 /dev/xvda / ext4 noatime,errors=remount-ro 0 1 /dev/xvdb none swap sw 0 0 # / was on /dev/sda1 during installation UUID=66f7abf6-d861-4e46-a255-e6b8094c8c42 / ext4 errors=remount-ro 0 1 # swap was on /dev/sda5 during installation UUID=a7122024-5385-48c3-b536-b9fefb25cd73 none swap sw 0 0 /dev/fd0 /media/floppy0 auto rw,user,noauto,exec,utf8 0 0 |
在Ubuntu默认配色方案中:
蓝色表示:目录
绿色表示:可执行文件
红色表示:压缩文件
淡蓝色表示:链接文件
灰色表示:其它文件
红色黑背景表示:链接存在问题
黄色表示:设备文件
绿色背景表示:权限大开
使用 ls -l命令,以列表形式显示当前目录下的文件时,首列将显示每个文件的属性,如下图:
可以看到,文件属性显示为10位字母,其结构如下:
{1位文件类型标记} {3位所有者访问权限} {3位文件所在组用户的访问权限} {3位所有其它用户访问权限}
符号 | 含义 |
- | 普通文件 |
d | 目录 |
l | 符号链接 |
c | 字符设备节点。设备文件和I/O设备、集成到内核的设备驱动有关,程序访问设备文件,则直接访问其关联的设备 |
b | 块设备节点 |
p | 命名管道。管道和套接字用于进程间通信 |
s | 套接字 |
所谓文件模式(Mode),是指9个控制读、写、执行的位,附加3个影响可执行文件运行方式的标记位组成的文件访问权限描述符。
w: 修改文件
x: 如同命令一样执行文件
w: 在目录中增删文件
x: 访问目录中的文件(查看目录下文件名、文件大小、修改时间等)
注意:挂载文件系统时,可以禁用setuid、setgid,这种情况下即使设置了这些位,也没有效果。
一般使用8进制的4/2/1分别表示读/写/执行,下表描述的顺序与文件属性中9位权限的排列顺序相同:
分类 | 所有者 | 文件所在组的用户 | 所有其它用户 | ||||||
数值 | 4 | 2 | 1 | 4 | 2 | 1 | 4 | 2 | 1 |
含义 | r | w | x | r | w | x | r | w | x |
对于没有设置的权限位,显示为短横线:“-”。此外,3个附加位为被设置时,执行位的x显示为其它字符:
- 如果setuid位被设置,则所有者的x显示为s
- 如果setgid位被设置,则所属群的x显示为s
- 如果粘滞位被设置,则其它人的x显示为t
- 如果设置了setuid、setgid或者粘滞位,但是对应的x没有设置,则使用大写显示相应的S、T
命令格式: chmod [-vR] mode filename
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#给文件所有者增加执行权限 chmod u+x filename #设置为:所有者可以读写,其他人没有任何权限 chmod 600 filename # 设置setuid位 chmod u+s /usr/bin/qemu-ifup # 设置setgid位 chmod g+s /usr/bin/qemu-ifup # 同时设置setuid setgid位 chmod a+s /usr/bin/qemu-ifup # 设置粘滞位 chmod o+t tmp |
就像每个用户都归属于一个主要组,任何Linux文件都具有一个所有者和关联的组。
命令格式: chown [-vR] [user] [:group] filename
举例:
1 2 3 4 |
#把blog目录及其子目录、文件的所有者改为root,所属群组改为www-data chown -vR root:www-data blog #把www目录的所有者改为www-data chown www-data www |
命令格式: chown [-vR] group filename
举例:
1 2 |
#把www目录的所属群组改为www-data chgrp www-data www |
逻辑分卷管理器(Logical Volume Manager)是一种可用在Linux内核的分卷管理器,支持管理硬盘驱动器或者其它大容量存储设备。
LVM简化了存储管理,它利用Linux内核的device-mapper来实现存储系统的虚拟化(系统分区独立于底层硬件)。你可以基于LVM实现存储空间的抽象化,并在上面建立虚拟分区(virtual partitions)。这样,扩大/缩小分区变得更加简便,增删分区时也不用担心硬盘没有足够的连续空闲空间。
LVM牵涉到以下基本概念:
- 物理卷Physical volume (PV):可以在上面建立卷组的媒介,物理卷可以是硬盘分区,也可以是硬盘本身。物理卷包括一个特殊的header,其余部分被切割为一块块的物理区域(physical extents)
- 卷组Volume group (VG):将一组物理卷收集为一个管理单元。卷组被整体的作为存储卷使用,就像单个磁盘一样。一个卷组可以包含多块硬盘
- 逻辑卷Logical volume (LV):即虚拟分区,由物理区域(physical extents)组成。你可以把逻辑卷看作普通分区
- 物理区域Physical extent (PE):硬盘可供指派给逻辑卷的最小单位(通常为4MB)。物理区域可以分配给任何逻辑卷
LVM的优势是:
- 可以让多个硬盘看起来像是一个大硬盘
- 可以创建跨越多块硬盘的分区
- 可以创建小的逻辑卷,在空间不足时再动态调整它的大小
- 调整逻辑卷大小时可以不用考虑逻辑卷在硬盘上的位置,不用担心没有可用的连续空间
- 可以在线(已挂载)对逻辑卷和卷组进行创建、删除、调整大小等操作
- 无需重新启动服务,就可以将服务中用到的逻辑卷在线、动态迁移至别的硬盘上
- 允许创建快照,可以保存文件系统的备份
这些优势使得LVM对服务器存储的管理非常有用。
独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks)的简写。分为多种类型:
级别 | 冗余盘数 | 空间利用率 | 性能 | 可靠性 | 说明 |
0 | 0 | 100% | 最高 | 最低 | 数据没有副本。同时从N块盘写入、读出 |
1 | N/2 | 50% | 低 | 最高 | 每块数据都有一份副本,读取性能可倍增 |
3 | 1 | ( N - 1 ) / 2 | 较高 | 较低 |
一块磁盘专门存放数据校验信息,N-1块盘做成RAID 0 最多允许坏一块盘。N最少为3 |
5 | 1 | ( N - 1 ) / 2 | 较高 | 较低 |
相当于一块磁盘的容量存放校验信息,但是信息分散存放在所有磁盘上 最多允许坏一块盘。N最少为3 |
6 | 2 | ( N - 2 ) / 2 | 较低 | 较高 | 在RAID 5的基础上,又增加了一种校验码。最多允许坏两块盘 |
对于RAID 1 - 6 ,两个阵列可以再组成RAID0,从而形成RAID 10 、RAID 50 ……其中RAID 50提供了接近RAID 10性能、可用性以及接近RAID 5成本的特性,具有较好的整体性价比优势。
RAID5只能提供一块磁盘的容错率,服务器硬盘的年坏盘率为1.7%-8.6%。这么高的概率,让短时间内坏掉两块盘的情况成为可能。
虽然使用RAID6能容忍两块坏盘,但是RAID 6 需要生成两组校验码,资源耗费比RAID5大不少。
当前磁盘容量越来越大,出现坏盘后,插入新的热备盘进行数据重建,耗时想当长。以SATA 1TB盘为例,单盘速度100MB/s,重建全速进行也要耗费3小时。这3个小时里面,RAID5是没有数据保护能力的。
RAID5对随机IO的处理是它的一大弱势,对于随机读写不仅仅性能会下降,而且由于它的特点会导致写性能额外的损失。
RAID5是把数据划分成一个个条带(Stripe)来处理。只有整个条带数据的写入才能产生校验信息,如果只写条带的一部分,则需要从磁盘把整个条带读取出来以计算校验信息。这导致一次写操作可能需要两次IO才能完成。
Leave a Reply