Schneller Storage ist teuer, langsamer Storage ist günstig. Die Herausforderung: Die meisten Daten werden nach der Erstellung selten wieder gelesen, belegen aber dauerhaft wertvollen SSD-Platz. ZFS Dataset Tiering löst dieses Problem, indem Daten regelbasiert zwischen Performance-Storage (SSD/NVMe) und Kapazitäts-Storage (HDD) verschoben werden — automatisch, ohne manuelle Eingriffe.
Das Konzept: Hot, Warm, Cold
Dataset Tiering klassifiziert Daten anhand ihrer Zugriffsfrequenz:
| Tier | Storage-Typ | Zugriffsfrequenz | Beispieldaten |
|---|---|---|---|
| Hot | NVMe/SSD | Täglich bis stündlich | Aktive Projekte, Datenbanken, VMs |
| Warm | SSD (SATA) | Wöchentlich bis monatlich | Abgeschlossene Projekte, Logs |
| Cold | HDD (Mirror/RAIDZ) | Selten bis nie | Archiv, Compliance-Daten, alte Backups |
Das Ziel: Häufig genutzte Daten liegen automatisch auf dem schnellsten Storage, selten genutzte Daten wandern auf günstigen Kapazitätsspeicher. Die Gesamtkosten pro Terabyte sinken, ohne dass die Performance für aktive Workloads leidet.
ZFS-Grundlagen für Tiering
Pools und Datasets
ZFS organisiert Storage in Pools (physische Datenträger) und Datasets (logische Dateisysteme). Für Tiering benötigen Sie mindestens zwei Pools:
# Performance-Pool (SSD Mirror)
zpool create ssd-pool mirror /dev/nvme0n1 /dev/nvme1n1
# Kapazitäts-Pool (HDD RAIDZ2)
zpool create hdd-pool raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf
Warum nicht einfach ein Pool mit Mixed VDEVs?
ZFS verteilt Writes gleichmäßig über alle VDEVs in einem Pool. Ein Pool mit SSD- und HDD-VDEVs würde Daten zufällig auf beide Typen verteilen — ohne Steuerungsmöglichkeit. Für echtes Tiering brauchen Sie separate Pools und eine Logik, die Daten zwischen ihnen verschiebt.
Die Ausnahme sind Special VDEVs (Metadata-Tiering), die wir weiter unten behandeln.
Metadata-Tracking: Wann wurden Daten zuletzt genutzt?
Die zentrale Frage beim Tiering: Wann wurde eine Datei zuletzt gelesen oder geschrieben? ZFS bietet dafür mehrere Zeitstempel:
- atime: Letzter Lesezugriff (standardmäßig bei jedem
open()aktualisiert) - mtime: Letzte Datenänderung
- crtime: Erstellungszeitpunkt
Problem: atime erzeugt bei jedem Lesezugriff einen Write — das reduziert die SSD-Lebensdauer und verschlechtert die Performance. Die Lösung:
# relatime: atime nur aktualisieren, wenn älter als mtime
zfs set atime=on ssd-pool/active-data
zfs set relatime=on ssd-pool/active-data
Mit relatime wird atime nur aktualisiert, wenn der letzte Zugriff älter als die letzte Änderung ist — deutlich weniger Write-Overhead bei ausreichender Genauigkeit für Tiering-Entscheidungen.
Tiering-Policy implementieren
Ansatz 1: Zeitbasiertes Tiering mit zfs send/receive
Der einfachste Ansatz verschiebt ganze Datasets basierend auf dem Alter:
#!/usr/bin/env python3
"""ZFS Dataset Tiering: Move datasets between SSD and HDD pools."""
import subprocess
import json
from datetime import datetime, timedelta
SSD_POOL = "ssd-pool"
HDD_POOL = "hdd-pool"
TIER_AFTER_DAYS = 90
DRY_RUN = True
def get_datasets(pool):
result = subprocess.run(
["zfs", "list", "-H", "-o", "name,used,creation", "-r", pool],
capture_output=True, text=True
)
datasets = []
for line in result.stdout.strip().split("\n"):
if line:
parts = line.split("\t")
datasets.append({
"name": parts[0],
"used": parts[1],
"creation": parts[2]
})
return datasets
def get_last_access(dataset):
"""Check the most recent file modification in the dataset."""
mountpoint = subprocess.run(
["zfs", "get", "-H", "-o", "value", "mountpoint", dataset],
capture_output=True, text=True
).stdout.strip()
result = subprocess.run(
["find", mountpoint, "-maxdepth", "2", "-type", "f",
"-printf", "%T@\n"],
capture_output=True, text=True
)
if result.stdout.strip():
timestamps = [float(t) for t in result.stdout.strip().split("\n")]
return datetime.fromtimestamp(max(timestamps))
return None
def migrate_dataset(source, target_pool):
"""Migrate dataset from source to target pool using send/receive."""
dataset_name = source.split("/", 1)[1] if "/" in source else source
target = f"{target_pool}/{dataset_name}"
snapshot = f"{source}@tiering-migrate-{datetime.now():%Y%m%d}"
commands = [
f"zfs snapshot -r {snapshot}",
f"zfs send -R {snapshot} | zfs receive -F {target}",
f"zfs destroy -r {source}",
]
for cmd in commands:
if DRY_RUN:
print(f"[DRY RUN] {cmd}")
else:
subprocess.run(cmd, shell=True, check=True)
def main():
cutoff = datetime.now() - timedelta(days=TIER_AFTER_DAYS)
for dataset in get_datasets(SSD_POOL):
if dataset["name"] == SSD_POOL:
continue
last_access = get_last_access(dataset["name"])
if last_access and last_access < cutoff:
print(f"Tiering {dataset['name']} -> {HDD_POOL} "
f"(last access: {last_access:%Y-%m-%d})")
migrate_dataset(dataset["name"], HDD_POOL)
if __name__ == "__main__":
main()
Ansatz 2: Dateibasiertes Tiering
Für granulareres Tiering können Sie einzelne Dateien statt ganzer Datasets verschieben. Das erfordert ein Tracking-System:
#!/bin/bash
# Dateien finden, die seit 90 Tagen nicht zugegriffen wurden
find /mnt/ssd-pool/data -type f -atime +90 -size +1M | while read file; do
# Relativen Pfad berechnen
rel_path="${file#/mnt/ssd-pool/data/}"
target_dir="/mnt/hdd-pool/archive/$(dirname "$rel_path")"
# Zielverzeichnis erstellen und Datei verschieben
mkdir -p "$target_dir"
mv "$file" "$target_dir/"
# Symlink für transparenten Zugriff erstellen
ln -s "/mnt/hdd-pool/archive/$rel_path" "$file"
echo "Moved: $rel_path"
done
Ansatz 3: Policy-basiertes Tiering mit Cron
Kombinieren Sie die Ansätze in einem strukturierten Policy-Framework:
# /etc/cron.d/zfs-tiering
# Täglich um 3:00 Uhr: Daten tiern
0 3 * * * root /opt/scripts/zfs-tiering.py --policy /etc/zfs-tiering/policy.json
# Wöchentlich: Report generieren
0 6 * * 1 root /opt/scripts/zfs-tiering.py --report
Policy-Konfiguration:
{
"policies": [
{
"name": "project-data",
"source_pool": "ssd-pool",
"target_pool": "hdd-pool",
"datasets": ["ssd-pool/projects/*"],
"tier_after_days": 90,
"min_size_mb": 100,
"exclude_patterns": ["*.db", "*.sqlite"]
},
{
"name": "vm-backups",
"source_pool": "ssd-pool",
"target_pool": "hdd-pool",
"datasets": ["ssd-pool/backups/*"],
"tier_after_days": 30,
"min_size_mb": 0
}
]
}
Special VDEV: Metadata-Tiering in ZFS
Seit OpenZFS 2.0 bietet ZFS das Special VDEV — ein dediziertes SSD-VDEV innerhalb eines HDD-Pools, das automatisch Metadaten, kleine Dateien und DDT (Dedup-Tabellen) auf schnellem Storage hält:
# HDD-Pool mit Special VDEV erstellen
zpool create tank \
raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf \
special mirror /dev/nvme0n1 /dev/nvme1n1
# small_blocks Threshold setzen (Dateien bis 128KB auf Special VDEV)
zfs set special_small_blocks=128K tank/dataset
Das Special VDEV beschleunigt Metadaten-Operationen (ls, find, stat) dramatisch, ohne dass der gesamte Pool auf SSDs laufen muss. Für Details siehe unseren Artikel zu TrueNAS Hybrid Storage.
Vergleich mit traditionellem Tiering
| Merkmal | ZFS Dataset Tiering | Enterprise SAN Tiering | Cloud Tiering (S3) |
|---|---|---|---|
| Kosten | Keine (Open Source) | Lizenzkosten ($$$$) | Pay-per-Use |
| Granularität | Dataset oder Datei | Block-Level | Objekt-Level |
| Automatisierung | Skript-basiert | Policy Engine | Lifecycle Rules |
| Transparenz | Symlinks / Mount | Transparent (LUN) | API / Gateway |
| Performance | ZFS ARC Cache hilft | Tiered Cache | Latenz bei Retrieval |
| Komplexität | Mittel | Hoch | Niedrig |
ZFS Dataset Tiering bietet nicht die Block-Level-Transparenz eines Enterprise-SAN, ist aber kostenlos, flexibel und lässt sich mit Standard-Linux-Tools vollständig automatisieren.
Use Cases
Use Case 1: Medienproduktion
Aktive Projekte liegen auf dem NVMe-Pool (schnelle Random-I/O für Videoschnitt). Nach Projektabschluss werden sie auf den HDD-Pool verschoben (hohe Kapazität für Archivierung). Das Tiering-Skript prüft, ob Projektordner seit 60 Tagen unverändert sind.
Use Case 2: Backup-Retention
Tägliche Backups landen auf SSD-Storage für schnelle Restores. Nach 14 Tagen werden sie auf HDD-Storage verschoben, wo sie für 12 Monate aufbewahrt werden. Die SSD-Kapazität bleibt für frische Backups frei.
Use Case 3: Compliance-Archivierung
Geschäftsdokumente mit Aufbewahrungspflicht (10 Jahre) werden nach dem aktiven Nutzungszeitraum automatisch auf Cold-Storage verschoben. ZFS Snapshots sichern die Integrität, Checksummen verhindern unbemerkte Bitfehler.
Monitoring und Reporting
Überwachen Sie Ihr Tiering mit einem einfachen Reporting-Skript:
#!/bin/bash
echo "=== ZFS Tiering Report ==="
echo ""
echo "SSD Pool (Hot Tier):"
zfs list -o name,used,refer,mountpoint -r ssd-pool
echo ""
echo "HDD Pool (Cold Tier):"
zfs list -o name,used,refer,mountpoint -r hdd-pool
echo ""
echo "Pool Capacity:"
zpool list -o name,size,alloc,free,cap
DATAZONE Control bietet erweitertes Tiering-Monitoring: automatische Erkennung von Datasets, die tiering-fähig sind, historische Kapazitätstrends und Kostenberechnung pro Tier.
Häufig gestellte Fragen
Kann ich Daten vom Cold-Tier zurück auf den Hot-Tier verschieben?
Ja. Das gleiche zfs send/receive funktioniert in beide Richtungen. Implementieren Sie einen “Promote”-Mechanismus, der häufig zugegriffene Cold-Daten zurück auf SSDs verschiebt.
Wie groß sollte der SSD-Pool sein?
Als Faustregel: 10-20 % der Gesamtkapazität reichen für die meisten Workloads. Wenn Ihre aktiven Daten mehr als 30 % des Gesamtvolumens ausmachen, ist der SSD-Pool zu klein.
Funktioniert Tiering mit Verschlüsselung?
Ja. ZFS Native Encryption bleibt beim send/receive erhalten. Der Schlüssel muss auf dem Ziel-Pool verfügbar sein.
Sie planen ZFS Dataset Tiering für Ihre TrueNAS-Infrastruktur? Kontaktieren Sie uns — wir entwerfen und implementieren eine maßgeschneiderte Storage-Tiering-Lösung.
Mehr zu diesen Themen:
Weitere Artikel
Backup-Strategie für KMU: Proxmox PBS + TrueNAS als zuverlässiges Backup-Konzept
Backup-Strategie für KMU mit Proxmox PBS und TrueNAS: 3-2-1-Regel umsetzen, PBS als primäres Backup-Target, TrueNAS-Replikation als Offsite-Kopie, Retention Policies und automatisierte Restore-Tests.
TrueNAS mit MCP: KI-gestützte NAS-Verwaltung per natürlicher Sprache
TrueNAS mit MCP (Model Context Protocol) verbinden: KI-Assistenten für NAS-Verwaltung, Status-Abfragen, Snapshot-Erstellung per Chat, Sicherheitsaspekte und Zukunftsausblick.
ZFS SLOG und Special VDEV: Sync Writes beschleunigen und Metadaten optimieren
ZFS SLOG (Separate Intent Log) und Special VDEV erklärt: Sync Writes beschleunigen, SLOG-Sizing, Special VDEV für Metadaten, Hardware-Auswahl mit Optane und Risiken bei Ausfall.