Woodpecker
Woodpecker ist die Standard-Nachrichtenwarteschlange (Write-Ahead-Log, WAL) in Milvus 3.x. Es handelt sich um ein cloud-natives WAL, das für den Objektspeicher entwickelt wurde und einen hohen Durchsatz, geringen Betriebsaufwand sowie nahtlose Skalierbarkeit bietet. Details zur Architektur und zu Benchmarks finden Sie unter Woodpecker.
Übersicht
- In Milvus 3.x ist Woodpecker die Standard- WAL/Nachrichtenwarteschlange, die als Protokollierungsdienst geordnete Schreibvorgänge und Wiederherstellung ermöglicht. Ein externer Nachrichtenwarteschlangendienst (wie Pulsar oder Kafka) ist nicht erforderlich.
- Woodpecker kann eingebettet im Milvus-/Streaming-Knoten (Standard) oder als dedizierter Dienst mit eigenen Pods (nur verteilt/Cluster) ausgeführt werden.
- Er unterstützt drei „
storage.type“-Modi: Objektspeicher (minio, Standard), lokales Dateisystem (local) und den dedizierten „service“. Siehe Bereitstellungsmodi.
Schnellstart
Um Woodpecker zu aktivieren, setzen Sie den MQ-Typ auf „Woodpecker“:
mq:
type: woodpecker
Hinweis: Das Umschalten auf „ mq.type “ bei einem laufenden Cluster ist ein Upgrade-Vorgang. Befolgen Sie die Upgrade-Anleitung sorgfältig und testen Sie die Konfiguration zunächst auf einem neuen Cluster, bevor Sie die Umstellung in der Produktionsumgebung vornehmen.
Konfiguration
Nachfolgend finden Sie den vollständigen Woodpecker-Konfigurationsblock (bearbeiten Sie „ milvus.yaml “ oder überschreiben Sie die Einstellungen in „ user.yaml “):
# Related configuration of woodpecker, used to manage Milvus logs of recent mutation operations, output streaming log, and provide embedded log sequential read and write.
woodpecker:
meta:
type: etcd # The Type of the metadata provider. currently only support etcd.
prefix: woodpecker # The Prefix of the metadata provider. default is woodpecker.
client:
segmentAppend:
queueSize: 10000 # The size of the queue for pending messages to be sent of each log.
maxRetries: 3 # Maximum number of retries for segment append operations.
segmentRollingPolicy:
maxSize: 256M # Maximum size of a segment.
maxInterval: 10m # Maximum interval between two segments, default is 10 minutes.
maxBlocks: 1000 # Maximum number of blocks in a segment
auditor:
maxInterval: 10s # Maximum interval between two auditing operations, default is 10 seconds.
logstore:
segmentSyncPolicy:
maxInterval: 200ms # Maximum interval between two sync operations, default is 200 milliseconds.
maxIntervalForLocalStorage: 10ms # Maximum interval between two sync operations local storage backend, default is 10 milliseconds.
maxBytes: 256M # Maximum size of write buffer in bytes.
maxEntries: 10000 # Maximum entries number of write buffer.
maxFlushRetries: 5 # Maximum number of flush retries.
retryInterval: 1000ms # Maximum interval between two retries. default is 1000 milliseconds.
maxFlushSize: 2M # Maximum size of a fragment in bytes to flush.
maxFlushThreads: 32 # Maximum number of threads to flush data
segmentCompactionPolicy:
maxSize: 2M # The maximum size of the merged files.
maxParallelUploads: 4 # The maximum number of parallel upload threads for compaction.
maxParallelReads: 8 # The maximum number of parallel read threads for compaction.
segmentReadPolicy:
maxBatchSize: 16M # Maximum size of a batch in bytes.
maxFetchThreads: 32 # Maximum number of threads to fetch data.
storage:
type: minio # The Type of the storage provider. Valid values: [minio, local]
rootPath: /var/lib/milvus/woodpecker # The root path of the storage provider.
Wichtige Hinweise:
woodpecker.meta- type: Derzeit wird nur „
etcd“ unterstützt. Verwenden Sie denselben etcd wie für Milvus, um leichtgewichtige Metadaten zu speichern. - prefix: Das Schlüsselpräfix für Metadaten. Standard:
woodpecker.
- type: Derzeit wird nur „
woodpecker.client- Steuert das Verhalten beim Anhängen, Rollieren und Überwachen von Segmenten auf der Client-Seite, um einen Ausgleich zwischen Durchsatz und End-to-End-Latenz zu schaffen.
woodpecker.logstore- Steuert die Richtlinien für Synchronisierung, Flush, Komprimierung und Lesevorgänge bei Log-Segmenten. Dies sind die wichtigsten Einstellmöglichkeiten zur Optimierung von Durchsatz und Latenz.
woodpecker.storage- type: „
minio“ für MinIO-/S3-kompatiblen Objektspeicher (MinIO/S3/GCS/OSS usw.); „local“ für lokale/gemeinsam genutzte Dateisysteme. - rootPath: Stammpfad für das Speicher-Backend (gilt für
local; beiminiowerden die Pfade durch Bucket/Präfix vorgegeben).
- type: „
Bereitstellungsmodi
Woodpecker unterstützt drei storage.type -Modi:
storage.type | So funktioniert Woodpecker | WAL-Backend | Milvus Standalone | Milvus Distributed (Cluster) |
|---|---|---|---|---|
minio (Standard) | In den Milvus-/Streaming-Knoten eingebettet | Objektspeicher (MinIO/S3-kompatibel) | Unterstützt | Unterstützt |
local | In den Milvus-/Streaming-Knoten integriert | Lokales Dateisystem | Unterstützt | Eingeschränkt (alle Knoten benötigen ein gemeinsames Dateisystem, z. B. NFS) |
service | Dedizierter Woodpecker-Dienst (eigene Pods) | Objektspeicher (MinIO/S3-kompatibel) | Nicht unterstützt | Unterstützt |
Hinweise:
- Bei „
minio“ nutzt Woodpecker denselben Objektspeicher wie Milvus (MinIO/S3/GCS/OSS usw.). - Bei „
local“ ist eine lokale Festplatte mit einem einzigen Knoten nur für den Standalone-Modus geeignet. Wenn alle Pods auf ein gemeinsames Dateisystem (z. B. NFS) zugreifen können, kann im Cluster-Modus auch „local“ verwendet werden. serviceIn diesem Modus wird Woodpecker als separater, unabhängig skalierbarer Dienst ausgeführt und ist nur für verteilte/Cluster-Bereitstellungen verfügbar. Standalone-Bereitstellungen nutzen die eingebetteten Modi (miniooderlocal).
Kompatibilität mit Objektspeichern für storage.type=minio
Die folgende Matrix fasst die derzeit bekannte Kompatibilität von Objektspeicher-Backends zusammen, wenn Woodpecker mit „ storage.type=minio “ konfiguriert ist. Diese Informationen basieren auf der GitHub-Diskussion Nr. 150.
| Anbieter / Dienst | Status | Anmerkungen |
|---|---|---|
| Azure Blob Storage | Unterstützt | Verwendet das native Azure-SDK. |
| AWS S3 | Unterstützt | Natives S3 mit vollständiger Unterstützung für bedingtes Schreiben. |
MinIO (>= 2024-12) | Unterstützt | Volle Unterstützung für bedingtes Schreiben in S3. |
| Aliyun OSS | Unterstützt | Wird über die S3-kompatible Schnittstelle unterstützt. |
| Tencent COS | Unterstützt | Wird über die S3-kompatible Schnittstelle unterstützt. |
| Google Cloud Storage (GCS) | Unterstützt | Wird über den S3-Interoperabilitätsmodus unterstützt. |
| Huawei Cloud OBS | Nicht unterstützt | Die erforderliche Semantik für bedingtes Schreiben fehlt. |
| VAST Data | Unterstützt | Von der Community verifiziert; funktioniert nur mit nicht versionierten Buckets. |
| Andere S3-kompatible Speicher | Teilweise | Hängt von der vollständigen Unterstützung der S3-Semantik für bedingtes Schreiben ab. |
Hinweise:
- Die Kompatibilität hängt von der nativen SDK-Unterstützung oder der Unterstützung der S3-Semantik für bedingtes Schreiben ab.
- Wenn Sie MinIO für Woodpecker selbst hosten, verwenden Sie „
RELEASE.2024-12-18T13-15-44Z“ oder eine neuere Version. - Diese Matrix spiegelt den aktuellen Stand der Diskussion wider und kann sich weiterentwickeln, sobald die Backend-Unterstützung weiter validiert wird.
Bereitstellungsanleitungen
Woodpecker für einen Milvus-Cluster auf Kubernetes aktivieren (Milvus Operator, storage=minio)
Starten Sie nach der Installation des Milvus Operators einen Milvus-Cluster mit aktiviertem Woodpecker anhand des offiziellen Beispiels:
kubectl apply -f https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_cluster_woodpecker.yaml
Dieses Beispiel konfiguriert Woodpecker als Nachrichtenwarteschlange und aktiviert den Streaming-Knoten. Der erste Start kann einige Zeit in Anspruch nehmen, da Images abgerufen werden müssen; warten Sie, bis alle Pods bereit sind:
kubectl get pods
kubectl get milvus my-release -o yaml | grep -A2 status
Sobald alles bereit ist, sollten Sie Pods sehen, die in etwa wie folgt aussehen:
NAME READY STATUS RESTARTS AGE
my-release-etcd-0 1/1 Running 0 17m
my-release-etcd-1 1/1 Running 0 17m
my-release-etcd-2 1/1 Running 0 17m
my-release-milvus-datanode-7f8f88499d-kc66r 1/1 Running 0 16m
my-release-milvus-mixcoord-7cd7998d-x59kg 1/1 Running 0 16m
my-release-milvus-proxy-5b56cf8446-pbnjm 1/1 Running 0 16m
my-release-milvus-querynode-0-558d9cdd57-sgbfx 1/1 Running 0 16m
my-release-milvus-streamingnode-58fbfdfdd8-vtxfd 1/1 Running 0 16m
my-release-minio-0 1/1 Running 0 17m
my-release-minio-1 1/1 Running 0 17m
my-release-minio-2 1/1 Running 0 17m
my-release-minio-3 1/1 Running 0 17m
Führen Sie den folgenden Befehl aus, um den Milvus-Cluster zu deinstallieren.
kubectl delete milvus my-release
Wenn Sie die Woodpecker-Parameter anpassen müssen, befolgen Sie die unter „Konfiguration“ beschriebenen Einstellungen.
Woodpecker für einen Milvus-Cluster auf Kubernetes aktivieren (Helm-Chart, storage=minio)
Fügen Sie zunächst das Milvus-Helm-Chart hinzu und aktualisieren Sie es, wie unter „Milvus in Kubernetes mit Helm ausführen“ beschrieben.
Führen Sie anschließend die Bereitstellung anhand eines der folgenden Beispiele durch:
– Cluster-Bereitstellung (empfohlene Einstellungen mit aktiviertem Woodpecker und Streaming Node):
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.0 \
--set pulsarv3.enabled=false \
--set woodpecker.enabled=true \
--set streaming.enabled=true \
--set indexNode.enabled=false
– Standalone-Bereitstellung (Woodpecker aktiviert):
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.0 \
--set cluster.enabled=false \
--set pulsarv3.enabled=false \
--set standalone.messageQueue=woodpecker \
--set woodpecker.enabled=true \
--set streaming.enabled=true
Befolgen Sie nach der Bereitstellung die Anweisungen in der Dokumentation zur Portweiterleitung und zum Herstellen einer Verbindung. Um die Woodpecker-Parameter anzupassen, befolgen Sie die unter „Konfiguration“ beschriebenen Einstellungen.
Woodpecker für Milvus Standalone in Docker aktivieren (storage=local)
In Milvus 3.x verwendet die Docker-Standalone-Bereitstellung standardmäßig Woodpecker mit dem lokalen Dateisystem als WAL-Backend – es ist keine zusätzliche Konfiguration erforderlich. Befolgen Sie die Anweisungen unter „Milvus in Docker ausführen“:
mkdir milvus-wp && cd milvus-wp
curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.sh
bash standalone_embed.sh start
Um Woodpecker anzupassen, bearbeiten Sie nach dem ersten Start die generierte Datei „ user.yaml “ und führen Sie „ bash standalone_embed.sh restart “ aus, um die Änderungen zu übernehmen (ein neuer „ start “-Befehl generiert „ user.yaml “ neu, wenden Sie die Änderungen daher mit „ restart “ an):
# user.yaml
woodpecker:
logstore:
segmentSyncPolicy:
maxFlushThreads: 16
Woodpecker für Milvus Standalone mit Docker Compose aktivieren (storage=minio)
Befolgen Sie die Anleitung „Milvus mit Docker Compose ausführen“. Beispiel:
mkdir milvus-wp-compose && cd milvus-wp-compose
wget https://github.com/milvus-io/milvus/releases/download/v3.0.0/milvus-standalone-docker-compose.yml -O docker-compose.yml
# By default, the Docker Compose standalone uses Woodpecker
sudo docker compose up -d
# If you need to change Woodpecker parameters further, write an override:
docker exec -it milvus-standalone bash -lc 'cat > /milvus/configs/user.yaml <<EOF
mq:
type: woodpecker
woodpecker:
logstore:
segmentSyncPolicy:
maxFlushThreads: 16
storage:
type: minio
EOF'
# Restart the container to apply the changes
docker restart milvus-standalone
Woodpecker im Dienstmodus für einen Milvus-Cluster (Helm) aktivieren
Für den Woodpecker-Dienstmodus empfehlen wir die Verwendung der kommenden Version Milvus 3.0.1 oder einer späteren Version mit Woodpecker v0.1.37 oder höher, um Optimierungen bei der Komprimierungsbereinigung und beim Group Commit zu nutzen.
Der Woodpecker-Dienstmodus ist eine Funktion von Milvus 3.0. Bei verteilten/Cluster-Bereitstellungen können Sie Woodpecker als dedizierten Dienst (separate Pods) ausführen, anstatt ihn in den Streaming-Knoten einzubetten, indem Sie „ streaming.woodpecker.embedded=false “ wie folgt einstellen:
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.0 \
--set woodpecker.enabled=true \
--set woodpecker.image.tag=v0.1.37 \
--set streaming.enabled=true \
--set streaming.woodpecker.embedded=false
Dadurch wird Woodpecker als dediziertes StatefulSet (my-release-milvus-woodpecker, standardmäßig 4 Replikate) bereitgestellt, das von einem Headless-Service angeführt wird und über Gossip-Clustering auf den Ports 18080 (Service), 17946 (Gossip) und 9091 (Metriken) läuft, wobei MinIO als Speicher-Backend dient. Der Dienst benötigt ein Quorum von 3 Knoten; die Standardeinstellung von 4 Replikaten gewährleistet das Quorum und toleriert gleichzeitig den Ausfall eines einzelnen Knotens. Stellen Sie „ woodpecker.replicaCount “ daher nicht auf einen Wert unter 3 ein. Der Cluster umfasst dann einen separaten Satz von „ woodpecker “-Pods:
my-release-milvus-woodpecker-0
my-release-milvus-woodpecker-1
my-release-milvus-woodpecker-2
my-release-milvus-woodpecker-3
Der „ service “-Modus von Woodpecker ist ausschließlich für verteilte/Cluster- Bereitstellungen vorgesehen – bei eigenständigen Bereitstellungen wird Woodpecker eingebettet ausgeführt (minio oder local). Der Milvus Operator unterstützt den „ “-Modus von Woodpecker noch nicht.
Tipps zur Durchsatzoptimierung
Das Durchsatz- und Latenzprofil von Woodpecker unterscheidet sich zwischen dem Embedded-Modus und dem Service-Modus (eine Funktion von Milvus 3.0). Die folgenden Hinweise sind nach Modus gegliedert.
Embedded-Modus
Optimieren Sie den End-to-End-Schreibdurchsatz auf der Grundlage der Benchmarks und Backend-Grenzwerte in Woodpecker unter Berücksichtigung der folgenden Aspekte:
- Speicherseitig
- Objektspeicher (MinIO/S3-kompatibel): Erhöhen Sie die Parallelität und die Objektgröße (vermeiden Sie sehr kleine Objekte). Achten Sie auf die Bandbreitenbeschränkungen des Netzwerks und der Buckets. Ein einzelner MinIO-Knoten auf SSD erreicht lokal oft eine Obergrenze von etwa 100 MB/s; eine einzelne Verbindung von EC2 zu S3 kann GB/s erreichen.
- Lokale/gemeinsam genutzte Dateisysteme (lokal): Bevorzugen Sie NVMe- oder schnelle Festplatten. Stellen Sie sicher, dass das Dateisystem kleine Schreibvorgänge und die fsync-Latenz gut bewältigt.
- Woodpecker-Einstellungen
- Erhöhen Sie „
logstore.segmentSyncPolicy.maxFlushSize“ und „maxFlushThreads“, um größere Flush-Vorgänge und eine höhere Parallelität zu erzielen. - Passen Sie „
maxInterval“ entsprechend den Medieneigenschaften an (tauschen Sie Latenz gegen Durchsatz bei längerer Aggregation ein). - Bei Objektspeichern sollten Sie erwägen, „
segmentRollingPolicy.maxSize“ zu erhöhen, um Segmentwechsel zu reduzieren.
- Erhöhen Sie „
- Client-/Anwendungsseite
- Verwenden Sie größere Batch-Größen und mehr gleichzeitige Schreiber/Clients.
- Steuern Sie den Zeitpunkt der Aktualisierung/des Indexaufbaus (Batch-Zusammenfassung vor dem Auslösen), um häufige kleine Schreibvorgänge zu vermeiden.
Dienstmodus (Milvus 3.0+)
Der Dienstmodus bewahrt den hohen Schreibdurchsatz eines auf Objektspeicher basierenden WAL bei und bietet gleichzeitig eine geringe Latenz (siehe „Latenz“). Die oben genannten optimierungsmaßnahmen auf Speicher- und Client-Seite gelten weiterhin; da Woodpecker zudem als eigener Dienst läuft, skalieren Sie die Schreibkapazität horizontal durch Hinzufügen von Replikaten (woodpecker.replicaCount, Standardwert 4), und Schreibvorgänge profitieren von einer Quorum-Replikation mit einer RTT sowie von topologiebewussten Lesevorgängen, die die Weiterleitung durch den Broker vermeiden.
Demo zur Batch-Einfügung – verwenden Sie Folgendes, um den Schreibdurchsatz zu messen:
from pymilvus import MilvusClient
import random
import time
# 1. Set up a Milvus client
client = MilvusClient(
uri="http://<Proxy Pod IP>:19530",
)
# 2. Create a collection
res = client.create_collection(
collection_name="test_milvus_wp",
dimension=512,
metric_type="IP",
shards_num=2,
)
print(res)
# 3. Insert randomly generated vectors
colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []
batch_size = 1000
batch_count = 2000
for j in range(batch_count):
start_time = time.time()
print(f"Inserting {j}th vectors {j * batch_size} startTime{start_time}")
for i in range(batch_size):
current_color = random.choice(colors)
data.append({
"id": (j*batch_size + i),
"vector": [ random.uniform(-1, 1) for _ in range(512) ],
"color": current_color,
"color_tag": f"{current_color}_{str(random.randint(1000, 9999))}"
})
res = client.insert(
collection_name="test_milvus_wp",
data=data
)
data = []
print(f"Inserted {j}th vectors endTime:{time.time()} costTime:{time.time() - start_time}")
Latenz
Embedded-Modus
Woodpecker ist ein cloud-natives WAL, das für Objektspeicher entwickelt wurde und Kompromisse zwischen Durchsatz, Kosten und Latenz eingeht. Der leichtgewichtige eingebettete Modus legt den Schwerpunkt auf Kosten- und Durchsatzoptimierung, da in den meisten Szenarien lediglich gefordert wird, dass Daten innerhalb einer bestimmten Zeit geschrieben werden, anstatt eine niedrige Latenz für einzelne Schreibanfragen zu verlangen. Daher nutzt Woodpecker Batch-Schreibvorgänge mit Standardintervallen von 10 ms für lokale Dateisystem-Speicher-Backends und 200 ms für MinIO-ähnliche Speicher-Backends. Bei langsamen Schreibvorgängen entspricht die maximale Latenz der Intervallzeit zuzüglich der Flush-Zeit.
Beachten Sie, dass das Einfügen von Batches nicht nur durch Zeitintervalle, sondern auch durch die Batchgröße ausgelöst wird, die standardmäßig 2 MB beträgt.
Service-Modus (Milvus 3.0+)
Der Service-Modus bietet eine Schreiblatenz im Millisekundenbereich – in derselben Größenordnung wie ein herkömmliches WAL mit drei Replikaten auf lokalen Festplatten – bei gleichzeitig geringen Kosten. In einer typischen Bereitstellung mit drei Replikaten über mehrere AZs hinweg bleibt die Schreiblatenz im Millisekundenbereich. Dies wird erreicht durch:
- Quorum-Schreibvorgänge mit einer RTT – die clientgesteuerte Replikation schließt einen Quorum-Schreibvorgang innerhalb einer einzigen Round-Trip-Zeit ab, wobei der AZ-übergreifende Datenverkehr auf das Datenvolumen von zwei Replikaten begrenzt ist (im Gegensatz zu dem zusätzlichen AZ-übergreifenden Datenverkehr von etwa einem Drittel, der für Broker-/Leader-basierte Replikation typisch ist).
- Topologiebewusste Single-Hop-Lesevorgänge – Jeder Lesevorgang erfolgt direkt bei der nächstgelegenen Replik, anstatt über einen Broker weitergeleitet zu werden, wodurch die zufälligen Lesevorgänge über AZ-Grenzen hinweg (≈2/3 des Leseverkehrs über AZ-Grenzen hinweg) von Broker-basierten Systemen vermieden werden.
- Sofortiges Hochladen in den Objektspeicher nach Segment-Rollover – jedes Segment verfolgt seinen gesamten Lebenszyklus und wird sofort nach dem Rollover in den Objektspeicher hochgeladen, wodurch der Speicherbedarf auf der lokalen Festplatte und die Speicherkosten niedrig gehalten werden, ohne dass dabei Kompromisse bei der Latenz eingegangen werden müssen.
- Keine kontinuierliche Replikation von Knoten zu Knoten – Protokolle werden im Objektspeicher als gemeinsamer Speicher persistiert, sodass beim Failover nur die überlebenden Replikate erneut hochgeladen werden (keine Kopie des gesamten Knotens); die Skalierung ist nicht an die Bandbreite der Replikation zwischen den Knoten gebunden, und der Austausch zahlreicher Knoten verursacht keine Replikationsstürme.
Bei bereichsübergreifenden Bereitstellungen spart der Servicemodus im Vergleich zu Broker-basierten Protokollsystemen zudem etwa 1/3 des Schreib- und 2/3 des Lese-Netzwerkverkehrs zwischen den Verfügbarkeitszonen ein. Die vollständige Design- und Kostenanalyse finden Sie unter „Woodpecker-Architektur“.
Einzelheiten zur Architektur, zu den Bereitstellungsmodi (MemoryBuffer / QuorumBuffer) und zur Leistung finden Sie unter „Woodpecker-Architektur“.
Weitere Informationen zu den Parametern finden Sie im Woodpecker -GitHub-Repository.