Building a Real-Time File Sync System with Rsync and Inotify
Why Combine Rsync with Inotify?
As infrastructure grows, traditional rsync usage faces limitations. Standard rsync operations require a full directory scan to identify differences, which becomes highly inefficient when dealing with millions of files where only a tiny fraction changes. Furthermore, native rsync lacks true real-time monitoring; it relies on scheduled cron jobs or manual triggers, leaving a window of time where the source and detsination data are out of sync. Combining rsync with inotify solves this by using the Linux kernel's filesystem notification to trigger rsync immediately upon file changes.
Understanding Inotify
Inotify is a kernel subsystem that provides fine-grained, asynchronous monitoring of filesystem events (like creation, deletion, and moidfication). Supported in Linux kernels from 2.6.13 onwards, it allows user-space tools (like inotify-tools) to react instantly to filesystem alterations without scanning the disk.
Infrastructure Setup
| Role | IP Address | OS Version |
|---|---|---|
| Source Node (inotify-master) | 192.168.1.128 | CentOS 6.4 |
| Target Node (inotify-slave) | 192.168.1.160 | CentOS 6.4 |
Configuring the Target Node (Rsync Daemon)
The target machine runs the rsync daemon to receive data.
1. Verify Rsync Instalation
rpm -qa | grep rsync
2. Create User and Directory
Setup a dedicated user and the storage folder.
useradd syncuser -s /sbin/nologin -M
mkdir -p /data/sync_target
chown -R syncuser:syncuser /data/sync_target
3. Rsync Daemon Configuration
Edit /etc/rsyncd.conf:
uid = syncuser
gid = syncuser
use chroot = no
max connections = 100
timeout = 600
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
[sync_module]
path = /data/sync_target
ignore errors
read only = no
list = no
hosts allow = 192.168.1.0/24
auth users = sync_agent
secrets file = /etc/sync_secrets.pass
4. Setup Authentication
Create the password file for the virtual user.
echo "sync_agent:SecurePass123" > /etc/sync_secrets.pass
chmod 600 /etc/sync_secrets.pass
5. Start Service
rsync --daemon
netstat -tulnp | grep 873
6. Initial Push Test
On the source node, configure the client password and test the connection.
echo "SecurePass123" > /etc/sync_client.pass
chmod 600 /etc/sync_client.pass
echo "Test Content" > /tmp/demo.txt
rsync -avz /tmp/demo.txt sync_agent@192.168.1.160::sync_module --password-file=/etc/sync_client.pass
Configuring the Source Node (Inotify + Script)
1. Verify Kernel Support
Check if the inotify interface is available:
ls -l /proc/sys/fs/inotify/
If you see max_queued_events, max_user_instances, and max_user_watches, support is enabled. You may increase the watch limit:
echo 30000000 > /proc/sys/fs/inotify/max_user_watches
2. Install Inotify Tools
wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
tar zxf inotify-tools-3.14.tar.gz
cd inotify-tools-3.14
./configure --prefix=/usr/local/inotify
make && make install
3. Key Inotifywait Parameters
- -m: Monitor continuously.
- -r: Recursive watch.
- -q: Quiet mode (less output).
- -e: Specify events (e.g., modify, create, delete, move).
- --format: Customize output format.
4. Automation Script
Create a script to watch the directory and trigger rsync.
#!/bin/bash
# Configuration Variables
TARGET_IP="192.168.1.160"
LOCAL_DIR="/data/sync_target/"
MODULE_NAME="sync_module"
USER_NAME="sync_agent"
PASS_FILE="/etc/sync_client.pass"
INO_HOME="/usr/local/inotify"
# Pre-flight checks
if [ ! -f "$PASS_FILE" ] || [ ! -e "$LOCAL_DIR" ]; then
echo "Missing config or directory."
exit 1
fi
# Monitoring Loop
$INO_HOME/bin/inotifywait -mrq --format '%w%f' -e modify,delete,create,attrib $LOCAL_DIR | while read CHANGED_FILE
do
rsync -aruz --delete --password-file=$PASS_FILE $LOCAL_DIR $USER_NAME@$TARGET_IP::$MODULE_NAME
done
Run the script in the background:
chmod +x sync_monitor.sh
./sync_monitor.sh &
Validation
On the source node, generate files to verify the sync.
cd /data/sync_target
touch file_{1..50}.txt
Check the target node (192.168.1.160) to confirm the files appear instantly in /data/sync_target.
Firewall Considerations
Ensure port 873 is open on the target node.
iptables -I INPUT -p tcp --dport 873 -j ACCEPT
service iptables save