inotify Rsync基本应用说明
来自:https://www.xjimmy.com/inotify_rsync.html
一、inotify基础知识
inotify是啥东东?
inotify是Linux内核提供的一种对文件系统的监控机制,而机制是需要我们去实现了,目前实现的有两种方案:inotify本身和sersync。
这两种方案也可以说是两款工具,今天重点介绍inotify这款工具如果实现inotify的机制。
使用inotify的前提条件
请确保内核版本高于2.6.13,且在/proc/sys/fs/inotify目录下有以下三个文件,这表示系统支持inotify监控。
1
2
|
[root@jimmy ~] # uname -r [root@jimmy ~] # ll /proc/sys/fs/inotify/ |
以下是这3个文件分别对应的内核参数的意义。
(1)max_queued_events:调用inotify_init时分配到inotify instance中可排队的event数的最大值,超出值时的事件被丢弃,但会触发队列溢出Q_OVERFLOW事件。
(2)max_user_instances:每一个real user可创建的inotify instances数量的上限。
(3)max_user_watches:每个inotify实例相关联的watches的上限,即每个inotify实例可监控的最大目录、文件数量。如果监控的文件数目巨大,需要根据情况适当增加此值,如
1
|
[root@jimmy ~] #echo 30000000 > /proc/sys/fs/inotify/max_user_watches |
二、Inotify工具安装
inotify由inotify-tools包提供。epel源上提供了inotify-tools工具,可以直接在线安装。
1
|
[root@jimmy ~] # yum -y install inotify-tools |
inotify-tools工具只提供了两个命令。
1
2
3
|
[root@jimmy ~] # rpm -ql inotify-tools |grep bin/ /usr/bin/inotifywait /usr/bin/inotifywatch |
inotifywait:实现监控(watch)文件的功能,该命令是inotify的核心命令,我们用inotify,其实就是用inotifywait这个命令。
inotifywatch:用于收集文件系统的统计数据,例如发生了多少次inotify事件,某文件被访问了多少次等等,一般用不上。
三、inotifywait命令讲解
inotifywait命令的常用选项说明:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
-m:表示始终监控,否则应该是监控到了一次就退出监控了 -r:递归监控,监控目录中的任何文件,包括子目录。递归监控可能会超出max_user_watches的值,需要适当调整该值 -e:指定监控的事件。一般监控的就delete、create、attrib、modify、close_write @<file>:如果是对目录进行递归监控,则该选项用于排除递归目录中不被监控的文件。file是相对路径还是绝对路径由监控目录是相对还是绝对来决定 -q:--quiet的意思,静默监控,这样就不会输出一些无关的信息 --exclude <pattern> :通过模式匹配来指定不被监控的文件,区分大小写 --excludei <pattern>:通过模式匹配来指定不被监控的文件,不区分大小写 --timefmt:监控到事件触发后,输出的时间格式,可指定可不指定该选项,一般设置为[--timefmt '%Y/%m/%d %H:%M:%S' ] --format:用户自定义的输出格式,如[--format '%w%f %e%T' ] %w:产生事件的监控路径,不一定就是发生事件的具体文件,例如递归监控一个目录,该目录下的某文件产生事件,将输出该目录而非其内具体的文件 %f:如果监控的是一个目录,则输出产生事件的具体文件名。其他所有情况都输出空字符串 %e:产生的事件名称 %T:以 "--timefmt" 定义的时间格式输出当前时间,要求同时定义 "--timefmt" |
inotifywait 可监控的事件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
access:文件被访问 modify:文件被写入 attrib:元数据被修改。包括权限、时间戳、扩展属性等等 close_write:打开的文件被关闭,是为了写文件而打开文件,之后被关闭的事件 close_nowrite:read only模式下文件被关闭,即只能是为了读取而打开文件,读取结束后关闭文件的事件 close:是close_write和close_nowrite的结合,无论是何种方式打开文件,只要关闭都属于该事件 open:文件被打开 moved_to:向监控目录下移入了文件或目录,也可以是监控目录内部的移动 moved_from:将监控目录下文件或目录移动到其他地方,也可以是在监控目录内部的移动 move:是moved_to和moved_from的结合 moved_self:被监控的文件或目录发生了移动,移动结束后将不再监控此文件或目录 create:在被监控的目录中创建了文件或目录 delete:删除了被监控目录中的某文件或目录 delete_self:被监控的文件或目录被删除,删除之后不再监控此文件或目录umount:挂载在被监控目录上的文件系统被umount,umount后不再监控此目录 isdir :监控目录相关操作 |
四、inotify监控事件说明
前面提到了非常多的监控事件,但是实际应用中需要设置哪几个监控事件呢?
答案是:close_write、moved_to、moved_from、delete和isdir
其实,对文件的操作动作都会涉及close事件,且大多数情况都是伴随着close_write事件的。所以,大多数情况下在定义监控事件时,其实并不真的需要监控open、modify、close事件。特别是close,只需监控它的分支事件close_write和close_nowrite即可。由于一般情况下inotify都是为了监控文件的增删改,不会监控它的访问,所以一般只需监控close_write即可。
由于很多时候定义触发事件后的操作都是根据文件来判断的,例如a文件被监控到了变化(不管是什么变化),就立即执行操作A,又由于对文件的一个操作行为往往会触发多个事件,这样很可能会因为多个事件被触发而重复执行操作A。
综合以上考虑,建议对监控对象的close_write、moved_to、moved_from、delete和isdir(主要是create,isdir,但无法定义这两个事件的整体,所以仅监控isdir)事件定义对应的操作,因为它们互不重复。如有需要,可以将它们分开定义,再添加需要监控的其他事件。
inotifywait命令常见的使用方法
1
|
[root@jimmy ~] # inotifywait -mrq -e delete,close_write,moved_to,moved_from,isdir --format '%w%f:%e' /www |
五、inotify的缺陷及Bug
inotify+rsync的缺陷:多次触发rsync,造成资源和网络带宽浪费
当我们给监控目录添加文件的时候,inotify会触发事件,就算经过上的简化,已经尽少量的触发事件了,但是如果往一个目录拷贝多个文件的时候,仍然是每个文件触发一个事件,而一个事件就是代表着一次rsync数据同步,如果多个文件,就会多次rsync,而我们如果同步的是目录的话,其实,一次rsync就足够了。
inotify的bug:经常会随机性地遗漏某些文件
当向监控目录下拷贝复杂层次目录(多层次目录中包含文件),或者向其中拷贝大量文件时,inotify经常会随机性地遗漏某些文件。遗漏某些文件的意思是,不会对某些文件触发相关事件,不会触发相关事件的后果就是不会调用rsync进行同步。
但是需要说明的是,只有拷贝多层次包括多文件的目录时才会出现此bug,拷贝单个文件或简单无子目录的时候不会出现此bug。对于inotify+rsync来说,由于触发事件后常使用rsync同步整个目录而非单个文件,所以这个bug对rsync来说并不算严重。
解决方案:设计inotify+rsync脚本时,有以下几个目标应该尽量纳入考虑或达到
(1)每个文件都尽量少地产生监控事件,但又不能遗漏事件。
(2)让rsync同步目录,而不是同步产生事件的单个文件。
(3)一次性操作同步目录下的多个文件会产生多个事件,导致多次触发rsync。如果能让这一批操作只触发一次rsync,则会大幅降低资源的消耗。
(4)rsync同步目录时,考虑好是否要排除某些文件,是否要加上"–delete"选项等。
(5)为了性能,可以考虑对子目录、对不同事件单独设计inotify+rsync脚本。
六、inotify+rsync的最佳实现案例
inotifywait一般不会单独使用,而是利用shell脚本,配合rsync进行数据的实时同步。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[root@jimmy ~] # cat ~/inotify.sh #!/bin/bash watch_dir= /www rsync_dir= /tmp push_to=172.16.10.5 # First to do is initial sync rsync -az --delete --exclude= "*.swp" --exclude= "*.swx" $watch_dir $push_to:${rsync_dir} inotifywait -mrq -e delete,close_write,moved_to,moved_from,isdir --timefmt '%Y-%m-%d %H:%M:%S' -- format '%w%f:%e:%T' --exclude= ".*.swp" $watch_dir >> /tmp/inotifywait .log & while true ; do if [ -s "/tmp/inotifywait.log" ]; then grep -i -E "delete|moved_from" /tmp/inotifywait .log >> /tmp/inotify_away .log rsync -az --delete --exclude= "*.swp" --exclude= "*.swx" $watch_dir $push_to:${rsync_dir} if [ $? - ne 0 ]; then echo "$watch_dir sync to $push_to failed at `date +" %F %T "`,please check it by manual" >> /tmp/inotifyerror .log cat /dev/null > /tmp/inotifywait .log rsync -az --delete --exclude= "*.swp" --exclude= "*.swx" $watch_dir $push_to:${rsync_dir} else sleep 1 fi done |
脚本文件说明:
(1)脚本流程是人的实现方法是将inotifywait触发的事件记录到文件/etc/inotifywait.log中,然后在死循环中判断该文件,如果该文件不为空则调用一次rsync进行同步,同步完后立即清空inotifywait.log文件,防止重复调用rsync。
(2)但需要考虑一种情况,清空inotifywait.log文件的瞬间,又触发了一个事件,那么可能会导致这个事件被遗漏,所以在清空该文件后应该再调用一次rsync进行同步,这也变相地实现了失败重传的错误处理功能。
(3)如果没有监控到事件,inotifywait.log将是空文件,此时循环将睡眠1秒钟,所以该脚本并不是百分百的实时,但1秒钟的误差对于cpu消耗来说是很值得的。
(4)脚本中inotifywait命令中的后台符号"&"绝不能少,否则脚本将一直处于inotifywait命令阶段,不会进入到下一步的循环阶段。
(5)脚本示例中,过滤了两种临时文件(.swp和.swx),这是编辑文件时,产生的临时文件,而这种临时文件是不应该被监控,更不能被同步到远程目标主机的文件。
本文是参考‘骏马金龙’大神的文章进行精简,加了一些个人在学习过程中的理解内容,然后整理成更适合自己的阅读方式,毕竟这位大神讲解的太基础和原理性了,而实际用到更多的应该就是本文总结的重点内容。
下面贴出他这篇文章,一个更加强大和全面的inotify工具的用法,供各位学习:inotify+rsync详细说明和sersync
编译安装
1) 从githu下载inotify-tools源码并解压
wget https://github.com/rvoicilas/inotify-tools/archive/v3.14.tar.gz tar xvfz v3.14.tar.gz |
2) 进入inotify-tools解压目录
cd inotify-tools-3.14 |
3) 生成configure文件
./autogen.sh |
4) 编译安装inotify-tools,依次执行如下命令
./configure make make install |
5) 执行inotifywatch -h, 如果出现下提示表明inotify-tools安装成功
[root@centos_164 mnt]# inotifywatch -h inotifywatch 3.13 Gather filesystem usage statistics using inotify. Usage: inotifywatch [ options ] file1 [ file2 ] [ ... ] Options: ….. 备注:执行过程,可能会遇到“问题一”错误,按处理方式解决
|
以上来自:https://bbs.huaweicloud.com/forum/thread-40621-1-1.html
`--delay-updates` 是 `rsync` 的一个选项,用于推迟在传输期间对目标文件的更新。这个选项在某些情况下可以提高性能,特别是当目标文件正在被读取或写入时。
具体而言,`--delay-updates` 的作用如下:
- **推迟更新:** 在传输期间,`--delay-updates` 会推迟对目标文件的更新,直到整个文件传输完成。这意味着在传输过程中,不会修改目标文件,而是等到传输完成后再进行更新。
- **提高性能:** 当目标文件正在被其他进程读取或写入时,推迟更新可以防止目标文件在传输期间被频繁地修改,从而提高性能。
- **应对并发问题:** 这个选项有助于避免在传输期间产生并发问题,特别是当多个进程尝试同时访问目标文件时。
示例用法:
```bash
rsync --delay-updates source/ destination/
```
请注意,`--delay-updates` 选项通常会影响同步的实时性,因为它将目标文件的更新延迟到传输完成后。在某些情况下,可能需要权衡性能和同步实时性,具体取决于应用场景的需求。
rsync -a
组合相当于以下参数的组合:
-
-r
或--recursive
:递归同步,包括子目录。 -
-l
或--links
:保持软链接。 -
-p
或--perms
:保持文件权限。 -
-t
或--times
:保持文件时间戳。 -
-g
或--group
:保持文件属组信息。 -
-o
或--owner
:保持文件所有者信息。 -
-D
或--devices
:保持设备文件(如果有的话)。 -
-t
或--times
:保持文件时间戳。
因此,rsync -a
用于执行递归同步并保持所有相关属性,确保目标目录与源目录尽可能保持一致
rsync --inplace:
rsync 哪些参数 可以提高传输速率:
`rsync` 提供了一些参数和选项,可以在传输文件时提高速率。以下是一些可以用来优化传输速率的 `rsync` 参数和选项:
1. **--compress/-z:** 压缩传输的数据,以减小传输量,特别是在网络带宽受限的情况下。
```bash
rsync -az source/ destination/
```
2. **--bwlimit:** 限制传输速率,以防止 `rsync` 占用过多的带宽。可以指定速率的上限,例如,`--bwlimit=1000` 表示将速率限制为 1000 KB/s。
```bash
rsync --bwlimit=1000 source/ destination/
```
3. **--partial:** 允许 `rsync` 在传输中断后继续传输文件,而不必重新开始。这对于大文件的增量传输非常有用。
```bash
rsync --partial source/ destination/
```
4. **--progress:** 显示传输进度,以及已传输和剩余的数据量,可以更直观地了解传输的状态。
```bash
rsync --progress source/ destination/
```
5. **--stats:** 在传输完成后显示统计信息,包括传输速率、已传输字节数等。
```bash
rsync --stats source/ destination/
```
请注意,这些参数的实际效果可能因不同的网络条件、文件大小和文件类型而有所不同。在使用这些参数时,建议根据特定的使用情境进行测试和调整,以找到最佳的性能配置。
`rsync --partial` 参数表示允许 `rsync` 在传输文件时,如果传输中断,可以保留部分传输的文件而不必重新开始整个传输过程。这对于大文件的增量传输非常有用,因为它可以减少重新传输的数据量,提高效率。
使用 `--partial` 参数的 `rsync` 命令示例:
```bash
rsync --partial source/ destination/
```
这个命令会将源目录 (`source/`) 同步到目标目录 (`destination/`),并且如果传输过程中断,`rsync` 会保留部分传输的文件,下一次执行同步时,只传输文件的剩余部分而不重新传输整个文件。
在传输大文件时,如果发生中断,使用 `--partial` 可以避免重新传输整个文件,而是继续传输文件的未传输部分。这对于网络不稳定或传输大文件的情况特别有用。
`rsync --inplace` 是 `rsync` 命令的一个选项,用于优化文件同步操作。使用这个选项时,`rsync` 将尝试在目标上直接修改文件而不是使用临时文件夹,以减少磁盘空间的使用和提高同步速度。
具体而言,`--inplace` 选项有以下特点:
1. **减少磁盘空间使用:** 默认情况下,`rsync` 在目标目录中创建一个临时文件夹,将文件同步到该文件夹,然后将文件夹重命名为目标目录。而使用 `--inplace` 选项时,`rsync` 将尝试直接修改目标文件,减少了对额外磁盘空间的需求。
2. **提高同步速度:** 由于 `--inplace` 避免了对临时文件夹的使用,可以减少文件复制和目录重命名的操作,从而提高同步速度,尤其是在某些情况下。
3. **注意事项:** 尽管 `--inplace` 可以提供性能和磁盘空间的优势,但也需要小心使用。这个选项可能会增加一些风险,尤其是在同步期间目标文件正在被读取或写入时。
示例用法:
```bash
rsync --inplace -av source/ destination/
```
上述命令中,`-a` 用于递归和保持文件属性,`-v` 用于显示详细输出,`source/` 是源目录,`destination/` 是目标目录。
请注意,`--inplace` 选项不适用于所有情况,特别是当文件在同步期间可能发生变化时。在某些情况下,仍然可能需要使用临时文件夹以确保同步的原子性。
加快速率:
-I, --ignore-times |
通常,rsync将跳过大小相同且具有相同修改时间戳的文件。此选项会关闭此“快速检查”行为。
|
这个会降低速率。
-v 会增加cpu压力,最终影响速度。
来自:https://www.haxi.cc/archives/rsync%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3.html
-A, --acls | 此选项使rsync将目标ACL更新为与源ACL相同。 |
-X, --xattrs | 此选项使rsync将目标扩展属性更新为与源扩展属性相同。 |
-o, --owner | 此选项使rsync将目标文件的所有者设置为与源文件相同,仅root用户运行时有效。 |
-g, --group |
此选项使rsync将目标文件的所属组设置为与源文件相同,仅root用户运行时有效。
|
rsync -a 要考虑 这些参数。
-X 有哪些扩展属性:
Linux文件系统支持一些扩展属性(Extended Attributes),它们是与传统文件权限以及所有者、组关联的额外信息。这些属性提供了一种扩展文件元数据的方法,使用户能够附加与文件相关的任意键值对信息。以下是一些常见的文件扩展属性:
1. **user属性:**
- `user.key`: 用户自定义的扩展属性,其中 "key" 是用户定义的属性名。
```bash
setfattr -n user.myattribute -v "attribute_value" filename
```
2. **trusted属性:**
- `trusted`: 用于存储安全敏感的文件属性。
```bash
setfattr -n trusted.myattribute -v "attribute_value" filename
```
3. **security属性:**
- `security`: 用于存储SELinux安全标签等安全属性。
```bash
setfattr -n security.selinux -v "s0" filename
```
4. **system属性:**
- `system`: 用于存储文件系统实现相关的信息。
```bash
setfattr -n system.myattribute -v "attribute_value" filename
```
5. **inode属性:**
- `inode`: 包含与文件系统实现相关的底层信息。
```bash
setfattr -n inode.myattribute -v "attribute_value" filename
```
6. **其他属性:**
- 除了上述属性之外,具体支持的属性可能因文件系统类型而异。例如,EXT4文件系统还支持 `user.mime_type` 属性,用于存储文件的MIME类型。
```bash
setfattr -n user.mime_type -v "application/octet-stream" filename
```
**注意:**
- 要使用扩展属性,文件系统必须支持,并且挂载时必须启用扩展属性。
- 使用 `getfattr` 命令可以查看文件的扩展属性。
- 使用 `setfattr` 命令可以设置文件的扩展属性。
- 扩展属性是以键值对的形式存在的,键和值都是字符串。
- 某些属性可能仅在具体的文件系统类型上才有效。
请注意,使用扩展属性时需要小心,以确保不会破坏文件系统的稳定性和一致性。
linux 设置文件 不能删除属性:
在Linux中,文件的删除操作通常涉及到文件的写入和执行权限。如果你想要设置文件不能被删除,可以通过修改文件的权限或者使用特殊的属性来实现。以下是两种方法:
### 方法1: 修改文件权限
你可以通过修改文件的权限来限制删除操作。使用 `chmod` 命令可以修改文件的权限,具体地说,是修改写入权限。例如:
```bash
chmod a-w filename
```
上述命令将文件 `filename` 的写入权限(写入位)禁用,这样任何用户都不能删除这个文件。请注意,如果用户有执行权限和目录写入权限,仍然可以删除文件,所以需要根据具体需求来设置权限。
### 方法2: 使用chattr设置删除保护
`chattr` 命令可以用来设置文件的特殊属性。在这里,你可以使用 `i` 属性,将文件设置为不可修改。这就意味着文件不能被删除、修改、重命名、或链接。例如:
```bash
chattr +i filename
```
要取消这个属性,你可以运行:
```bash
chattr -i filename
```
请注意,使用 `chattr` 命令需要管理员权限。
**注意事项:**
- 将文件设置为不能删除可能会对系统运行产生影响,确保你了解文件的用途,并谨慎设置。
- 如果你在文件系统中设置了删除保护,记得在必要时取消该保护,否则你将无法删除文件。
- 这些方法可以限制普通用户对文件的删除,但如果用户有足够的权限(如`root`用户),仍然可以绕过这些限制。
在使用这些方法时,请确保你知道自己在做什么,以防止不必要的问题。
在Linux系统中,`chattr` 命令用于设置文件或目录的特殊属性。这些特殊属性包括不可更改 (`i` 属性)、不可删除 (`d` 属性)、同步更新 (`s` 属性) 等。以下是 `chattr` 命令的一些用法:
### 查看特殊属性:
```bash
chattr -l filename
```
这将显示文件 `filename` 的特殊属性。如果没有特殊属性,则不会有任何输出。
### 设置或清除特殊属性:
```bash
# 设置不可更改属性
chattr +i filename
# 清除不可更改属性
chattr -i filename
```
```bash
# 设置不可删除属性
chattr +d filename
# 清除不可删除属性
chattr -d filename
```
```bash
# 设置同步更新属性
chattr +s filename
# 清除同步更新属性
chattr -s filename
```
这里,`+` 表示添加属性,`-` 表示删除属性。你可以组合使用这些属性设置。
### 递归设置特殊属性:
如果要对目录中的所有文件及子目录递归地设置特殊属性,可以使用 `-R` 选项:
```bash
# 递归设置不可更改属性
chattr -R +i directory
```
### 特殊属性列表:
以下是一些常见的特殊属性:
- `a`: 只能以追加方式打开文件,不能修改或删除。
- `c`: 允许文件被压缩。
- `d`: 不允许文件被删除或重命名。
- `i`: 不允许文件被修改。
- `s`: 同步更新文件的内容。
- `u`: 当文件被删除,其数据块会被保留在磁盘上,以便恢复。
请注意,使用 `chattr` 命令需要超级用户或具有适当权限的用户。
linux 显示 特殊属性命令:
在Linux系统中,`lsattr` 命令用于显示文件或目录的特殊属性。该命令显示文件或目录的扩展属性,包括不可更改 (`i` 属性)、不可删除 (`d` 属性)、同步更新 (`s` 属性) 等。
以下是 `lsattr` 命令的基本用法:
```bash
lsattr filename
```
这会显示文件 `filename` 的扩展属性。如果你想查看目录的属性,可以将目录名称替换为 `filename`。
例子:
```bash
lsattr myfile.txt
```
这将显示类似于以下的输出:
```bash
----i--------e-- myfile.txt
```
在这个例子中,`i` 表示文件不可更改属性。
如果没有任何输出,表示文件没有特殊属性。
如果你要查看目录中所有文件的属性,可以使用 `-R` 选项:
```bash
lsattr -R directory
```
这会递归地显示目录中所有文件和子目录的属性。
请注意,使用 `lsattr` 命令需要具有对文件或目录的读取权限。
在 lsattr
命令的输出中,e
表示扩展属性 (extended attributes)。这个属性通常表示文件或目录包含了扩展的属性信息。扩展属性允许用户或应用程序向文件或目录添加自定义的元数据
参考:
https://www.haxi.cc/archives/rsync%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3.html