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/

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安装

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

posted @ 2023-11-28 09:55  redrobot  阅读(14)  评论(0编辑  收藏  举报