Lsyncd (Live Syncing Daemon) synchronisiert Verzeichnisse in Echtzeit. Es nutzt Inotify zur Erkennung von Änderungen und rsync für die Übertragung.

Installation

# Debian/Ubuntu
apt install lsyncd

# RHEL/CentOS
dnf install lsyncd

# Verzeichnisse erstellen
mkdir -p /etc/lsyncd
mkdir -p /var/log/lsyncd

Grundkonfiguration

Einfache Synchronisation

-- /etc/lsyncd/lsyncd.conf.lua

settings {
    logfile = "/var/log/lsyncd/lsyncd.log",
    statusFile = "/var/log/lsyncd/lsyncd.status",
    statusInterval = 10,
    nodaemon = false,
}

sync {
    default.rsync,
    source = "/var/www/html",
    target = "user@remote-server:/var/www/html",
    delay = 1,
    rsync = {
        archive = true,
        compress = true,
        rsh = "/usr/bin/ssh -o StrictHostKeyChecking=no"
    }
}

Lokale Synchronisation

sync {
    default.rsync,
    source = "/data/source",
    target = "/data/backup",
    delay = 5,
}

SSH-Keys einrichten

# Schlüsselpaar generieren (ohne Passwort)
ssh-keygen -t ed25519 -f /root/.ssh/lsyncd_key -N ""

# Auf Remote-Server kopieren
ssh-copy-id -i /root/.ssh/lsyncd_key.pub user@remote-server

# In Config verwenden
rsync = {
    rsh = "/usr/bin/ssh -i /root/.ssh/lsyncd_key -o StrictHostKeyChecking=no"
}

Mehrere Ziele

Zu mehreren Servern

settings {
    logfile = "/var/log/lsyncd/lsyncd.log",
    statusFile = "/var/log/lsyncd/lsyncd.status",
}

-- Server 1
sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@server1:/var/www/html",
    delay = 1,
    rsync = {
        archive = true,
        compress = true,
        rsh = "/usr/bin/ssh -i /root/.ssh/lsyncd_key"
    }
}

-- Server 2
sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@server2:/var/www/html",
    delay = 1,
    rsync = {
        archive = true,
        compress = true,
        rsh = "/usr/bin/ssh -i /root/.ssh/lsyncd_key"
    }
}

Mehrere Verzeichnisse

local sources = {
    "/var/www/site1",
    "/var/www/site2",
    "/var/www/site3",
}

for _, source in ipairs(sources) do
    sync {
        default.rsync,
        source = source,
        target = "root@remote:" .. source,
        rsync = { archive = true }
    }
end

Ausschlüsse

sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@remote:/var/www/html",

    exclude = {
        "*.tmp",
        "*.log",
        ".git",
        "cache/",
        "node_modules/",
        "vendor/",
    },

    rsync = {
        archive = true,
    }
}

Ausschluss-Datei

rsync = {
    archive = true,
    exclude_from = "/etc/lsyncd/excludes.txt",
}
# /etc/lsyncd/excludes.txt
*.tmp
*.log
.git
cache/
node_modules/

Rsync-Optionen

rsync = {
    archive = true,
    compress = true,
    verbose = true,
    delete = true,           -- Gelöschte Dateien auch auf Ziel löschen
    perms = true,            -- Berechtigungen beibehalten
    owner = true,            -- Eigentümer beibehalten
    group = true,            -- Gruppe beibehalten
    _extra = {
        "--bwlimit=10000",   -- Bandbreite begrenzen (KB/s)
        "--timeout=60",      -- Timeout
    },
}

Delay-Einstellungen

settings {
    maxProcesses = 4,        -- Parallele Prozesse
    maxDelays = 10,          -- Max. gesammelte Änderungen
}

sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@remote:/var/www/html",
    delay = 5,               -- Sekunden warten vor Sync
    init = true,             -- Initial-Sync beim Start
}

Rsyncssh-Modus

-- Effizienter für viele kleine Dateien
sync {
    default.rsyncssh,
    source = "/var/www/html",
    host = "remote-server",
    targetdir = "/var/www/html",
    delay = 1,
    rsync = {
        archive = true,
        compress = true,
    },
    ssh = {
        identityFile = "/root/.ssh/lsyncd_key",
    },
}

Hooks und Scripts

Pre/Post-Sync

sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@remote:/var/www/html",

    -- Vor dem Sync
    prepare = function(config, level, maxlevel)
        os.execute("touch /tmp/sync-started")
    end,

    -- Nach dem Sync
    finalize = function(config)
        os.execute("ssh root@remote 'systemctl reload nginx'")
    end,
}

Auf Ereignisse reagieren

sync {
    default.rsync,
    source = "/var/www/html",
    target = "root@remote:/var/www/html",

    onCreate = function(event)
        log("Normal", "File created: " .. event.pathname)
    end,

    onDelete = function(event)
        log("Normal", "File deleted: " .. event.pathname)
    end,

    onModify = function(event)
        log("Normal", "File modified: " .. event.pathname)
    end,
}

Service-Management

# Starten
systemctl start lsyncd
systemctl enable lsyncd

# Status
systemctl status lsyncd

# Logs
tail -f /var/log/lsyncd/lsyncd.log

# Status-Datei
cat /var/log/lsyncd/lsyncd.status

Manueller Test

# Im Vordergrund mit Debug
lsyncd -nodaemon -log all /etc/lsyncd/lsyncd.conf.lua

Monitoring

Status-Datei

settings {
    statusFile = "/var/log/lsyncd/lsyncd.status",
    statusInterval = 20,
}
# Inhalt anzeigen
cat /var/log/lsyncd/lsyncd.status

# Automatisch überwachen
watch -n 5 cat /var/log/lsyncd/lsyncd.status

Log-Levels

settings {
    logfile = "/var/log/lsyncd/lsyncd.log",
    logfacility = daemon,
    logident = "lsyncd",

    -- all, scarce, normal
    -- Oder einzeln: Exec, Error, Warning, Activity
}

Inotify-Limits

# Limits prüfen
cat /proc/sys/fs/inotify/max_user_watches

# Erhöhen für viele Dateien
echo "fs.inotify.max_user_watches=524288" >> /etc/sysctl.conf
sysctl -p

Troubleshooting

Häufige Probleme

# "Too many open files"
# → Inotify-Limit erhöhen

# "Permission denied"
# → SSH-Key prüfen
# → Berechtigungen auf Ziel

# Sync startet nicht
# → Logs prüfen
# → Konfiguration validieren
lsyncd -nodaemon /etc/lsyncd/lsyncd.conf.lua

Debug-Modus

# Maximales Logging
lsyncd -nodaemon -log all /etc/lsyncd/lsyncd.conf.lua

# Nur rsync-Befehle
lsyncd -nodaemon -log Exec /etc/lsyncd/lsyncd.conf.lua

Praktisches Beispiel

Web-Cluster Sync

-- /etc/lsyncd/lsyncd.conf.lua

settings {
    logfile = "/var/log/lsyncd/lsyncd.log",
    statusFile = "/var/log/lsyncd/lsyncd.status",
    statusInterval = 10,
    maxProcesses = 4,
}

-- Ziel-Server
local targets = {
    "root@web2",
    "root@web3",
    "root@web4",
}

-- Synchronisation für jeden Server
for _, target in ipairs(targets) do
    sync {
        default.rsync,
        source = "/var/www/html",
        target = target .. ":/var/www/html",
        delay = 2,
        delete = true,
        exclude = {
            "*.log",
            "cache/*",
            "temp/*",
            ".git",
        },
        rsync = {
            archive = true,
            compress = true,
            rsh = "/usr/bin/ssh -i /root/.ssh/lsyncd_key -o StrictHostKeyChecking=no"
        },
    }
end

Backup-Szenario

sync {
    default.rsync,
    source = "/data/important",
    target = "backup@backup-server:/backup/daily",
    delay = 60,   -- Alle 60 Sekunden
    rsync = {
        archive = true,
        compress = true,
        _extra = {
            "--backup",
            "--backup-dir=/backup/incremental",
            "--suffix=.$(date +%Y%m%d)",
        },
    },
}

Zusammenfassung

| Parameter | Beschreibung | |-----------|--------------| | source | Quellverzeichnis | | target | Ziel (lokal oder remote) | | delay | Wartezeit vor Sync (Sek.) | | delete | Gelöschte Dateien synchen | | exclude | Ausschluss-Pattern |

| Modus | Verwendung | |-------|------------| | default.rsync | Standard | | default.rsyncssh | Viele kleine Dateien | | default.direct | Lokal ohne rsync |

| Datei | Zweck | |-------|-------| | /etc/lsyncd/lsyncd.conf.lua | Konfiguration | | /var/log/lsyncd/lsyncd.log | Log-Datei | | /var/log/lsyncd/lsyncd.status | Status-Datei |

Fazit

Lsyncd ist ideal für Echtzeit-Replikation von Webservern und Daten. Die Lua-Konfiguration ermöglicht flexible Setups. Inotify sorgt für minimale Verzögerung. Für große Datenmengen oder bidirektionale Syncs sind andere Lösungen wie Unison oder GlusterFS besser geeignet.