Woodpecker
Woodpecker è la coda di messaggi predefinita (write-ahead log, WAL) in Milvus 3.x. Si tratta di un WAL cloud-native progettato per l'object storage, che offre un elevato throughput, un basso overhead operativo e una scalabilità senza soluzione di continuità. Per i dettagli sull'architettura e sui benchmark, consultare Woodpecker.
Panoramica
- In Milvus 3.x, Woodpecker è il WAL/coda di messaggi predefinito, che fornisce scritture ordinate e funzionalità di ripristino in qualità di servizio di logging. Non è richiesto alcun servizio esterno di coda di messaggi (come Pulsar o Kafka).
- Woodpecker può essere eseguito integrato nel nodo Milvus/streaming (impostazione predefinita) oppure come servizio dedicato con pod propri (solo in modalità distribuita/cluster).
- Supporta tre modalità di "
storage.type": object storage (minio, l’impostazione predefinita), file system locale (local) e il servizio dedicatoservice. Vedere Modalità di distribuzione.
Guida rapida
Per abilitare Woodpecker, impostare il tipo di MQ su Woodpecker:
mq:
type: woodpecker
Nota: il passaggio a mq.type e per un cluster in esecuzione è un'operazione di aggiornamento. Seguire attentamente la procedura di aggiornamento e verificare il funzionamento su un cluster nuovo prima di effettuare il passaggio in produzione.
Configurazione
Di seguito è riportato il blocco di configurazione completo di Woodpecker (modificare milvus.yaml o sovrascrivere 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.
Note importanti:
woodpecker.meta- type: Attualmente è supportato solo
etcd. Riutilizza lo stesso etcd di Milvus per memorizzare metadati leggeri. - prefisso: il prefisso delle chiavi per i metadati. Impostazione predefinita:
woodpecker.
- type: Attualmente è supportato solo
woodpecker.client- Controlla il comportamento di aggiunta/rotazione/controllo dei segmenti sul lato client per bilanciare la velocità di trasmissione e la latenza end-to-end.
woodpecker.logstore- Controlla le politiche di sincronizzazione, svuotamento, compattazione e lettura per i segmenti di log. Queste sono le impostazioni principali per l'ottimizzazione della velocità di trasmissione e della latenza.
woodpecker.storage- tipo:
minioper lo storage a oggetti compatibile con MinIO/S3 (MinIO/S3/GCS/OSS, ecc.);localper i file system locali/condivisi. - rootPath: percorso radice per il backend di archiviazione (efficace per
local; conminio, i percorsi sono determinati dal bucket/prefisso).
- tipo:
Modalità di distribuzione
Woodpecker supporta tre modalità di storage.type:
storage.type | Come funziona Woodpecker | Backend WAL | Milvus Standalone | Milvus distribuito (cluster) |
|---|---|---|---|---|
minio (impostazione predefinita) | Integrato nel nodo Milvus/streaming | Archiviazione a oggetti (compatibile con MinIO/S3) | Supportato | Supportato |
local | Integrato nel nodo Milvus/streaming | File system locale | Supportato | Limitato (tutti i nodi necessitano di un file system condiviso, ad es. NFS) |
service | Servizio Woodpecker dedicato (con pod propri) | Archiviazione a oggetti (compatibile con MinIO/S3) | Non supportato | Supportato |
Note:
- Con la modalità "
minio", Woodpecker condivide lo stesso storage a oggetti con Milvus (MinIO/S3/GCS/OSS, ecc.). - Con la modalità "
local", un disco locale a nodo singolo è adatto solo per la modalità Standalone. Se tutti i pod possono accedere a un file system condiviso (ad es. NFS), anche la modalità Cluster può utilizzare la modalità "local". serviceLa modalità Cluster esegue Woodpecker come servizio separato e scalabile in modo indipendente ed è disponibile solo per le distribuzioni distribuite/in cluster. Le distribuzioni in modalità Standalone utilizzano le modalità integrate (minioolocal).
Compatibilità con l’object storage per storage.type=minio
La seguente tabella riassume la compatibilità attualmente nota dei backend di archiviazione a oggetti quando Woodpecker è configurato con storage.type=minio. Queste informazioni si basano sulla discussione GitHub n. 150.
| Fornitore / servizio | Stato | Note |
|---|---|---|
| Azure Blob Storage | Supportato | Utilizza l'SDK nativo di Azure. |
| AWS S3 | Supportato | S3 nativo con supporto completo per la scrittura condizionale. |
MinIO (>= 2024-12) | Supportato | Supporto completo della scrittura condizionale di S3. |
| Aliyun OSS | Supportato | Supportato tramite la sua interfaccia compatibile con S3. |
| Tencent COS | Supportato | Supportato tramite la sua interfaccia compatibile con S3. |
| Google Cloud Storage (GCS) | Supportato | Supportato tramite la modalità di interoperabilità S3. |
| Huawei Cloud OBS | Non supportato | Manca la semantica di scrittura condizionale richiesta. |
| VAST Data | Supportato | Verificato dalla comunità; funziona solo con bucket non versionati. |
| Altri servizi di archiviazione compatibili con S3 | Parziale | Dipende dal supporto completo della semantica S3 Conditional Write. |
Note:
- La compatibilità dipende dal supporto nativo dell’SDK o dal supporto della semantica della scrittura condizionale di S3.
- Se si esegue l’hosting autonomo di MinIO per Woodpecker, utilizzare la versione
RELEASE.2024-12-18T13-15-44Zo successive. - Questa matrice riflette lo stato attuale della discussione e potrebbe evolversi man mano che il supporto del backend viene ulteriormente convalidato.
Guide alla distribuzione
Abilitare Woodpecker per un cluster Milvus su Kubernetes (Milvus Operator, storage=minio)
Dopo aver installato Milvus Operator, avvia un cluster Milvus con Woodpecker abilitato utilizzando l'esempio ufficiale:
kubectl apply -f https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_cluster_woodpecker.yaml
Questo esempio configura Woodpecker come coda di messaggi e abilita il nodo di streaming. Il primo avvio potrebbe richiedere del tempo per il download delle immagini; attendere fino a quando tutti i pod sono pronti:
kubectl get pods
kubectl get milvus my-release -o yaml | grep -A2 status
Una volta pronti, dovresti vedere pod simili a questi:
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
Eseguire il seguente comando per disinstallare il cluster Milvus.
kubectl delete milvus my-release
Se è necessario modificare i parametri di Woodpecker, seguire le impostazioni descritte nella sezione Configurazione.
Abilitare Woodpecker per un cluster Milvus su Kubernetes (Helm Chart, storage=minio)
Per prima cosa, aggiungi e aggiorna l’Helm Chart di Milvus come descritto nella sezione " Eseguire Milvus su Kubernetes con Helm".
Quindi esegui il deployment utilizzando uno dei seguenti esempi:
– Distribuzione del cluster (impostazioni consigliate con Woodpecker e Streaming Node abilitati):
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.1 \
--set pulsarv3.enabled=false \
--set woodpecker.enabled=true \
--set streaming.enabled=true \
--set indexNode.enabled=false
– Distribuzione standalone (Woodpecker abilitato):
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.1 \
--set cluster.enabled=false \
--set pulsarv3.enabled=false \
--set standalone.messageQueue=woodpecker \
--set woodpecker.enabled=true \
--set streaming.enabled=true
Dopo la distribuzione, seguire la documentazione per il port forwarding e la connessione. Per regolare i parametri di Woodpecker, seguire le impostazioni descritte nella sezione " Configurazione".
Abilitare Woodpecker per Milvus Standalone in Docker (storage=local)
In Milvus 3.x, l’implementazione standalone su Docker utilizza Woodpecker con il filesystem locale come backend WAL per impostazione predefinita — non è richiesta alcuna configurazione aggiuntiva. Seguire la guida «Eseguire Milvus in Docker»:
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
Per ottimizzare Woodpecker, modificare il file generato user.yaml dopo il primo avvio ed eseguire bash standalone_embed.sh restart per applicare le modifiche (un nuovo start rigenera user.yaml, quindi applicare le modifiche con restart):
# user.yaml
woodpecker:
logstore:
segmentSyncPolicy:
maxFlushThreads: 16
Abilitare Woodpecker per Milvus Standalone con Docker Compose (storage=minio)
Seguire la guida " Eseguire Milvus con Docker Compose". Esempio:
mkdir milvus-wp-compose && cd milvus-wp-compose
wget https://github.com/milvus-io/milvus/releases/download/v3.0.1/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
Abilitare la modalità servizio di Woodpecker per un cluster Milvus (Helm)
Per la modalità servizio di Woodpecker, si consiglia di utilizzare la prossima versione Milvus 3.0.1 o una versione successiva con Woodpecker v0.1.37 o successive per la pulizia tramite compattazione e le ottimizzazioni del group commit.
La modalità servizio di Woodpecker è una funzionalità di Milvus 3.0. Per le distribuzioni distribuite/in cluster, è possibile eseguire Woodpecker come servizio dedicato (pod separati) anziché integrato nel nodo di streaming, impostando ` streaming.woodpecker.embedded=false`:
helm install my-release zilliztech/milvus \
--set image.all.tag=v3.0.1 \
--set woodpecker.enabled=true \
--set woodpecker.image.tag=v0.1.37 \
--set streaming.enabled=true \
--set streaming.woodpecker.embedded=false
In questo modo Woodpecker viene distribuito come uno StatefulSet dedicato (my-release-milvus-woodpecker, 4 repliche per impostazione predefinita) supportato da un servizio headless, con cluster gossip sulle porte 18080 (servizio), 17946 (gossip) e 9091 (metriche), utilizzando MinIO come backend di archiviazione. Il servizio richiede un quorum di 3 nodi; l’impostazione predefinita di 4 repliche mantiene il quorum pur tollerando il guasto di un singolo nodo, pertanto non impostare " woodpecker.replicaCount " su un valore inferiore a 3. Il cluster include quindi un insieme separato di pod woodpecker:
my-release-milvus-woodpecker-0
my-release-milvus-woodpecker-1
my-release-milvus-woodpecker-2
my-release-milvus-woodpecker-3
La modalità " service " di Woodpecker è riservata esclusivamente alle distribuzioni distribuite/in cluster; le distribuzioni standalone eseguono Woodpecker in modalità embedded (minio o local). Milvus Operator non supporta ancora la modalità di servizio di Woodpecker.
Suggerimenti per l'ottimizzazione del throughput
Il profilo di throughput e latenza di Woodpecker varia tra la modalità integrata e la modalità di servizio (una funzionalità di Milvus 3.0). Le indicazioni riportate di seguito sono organizzate per modalità.
Modalità incorporata
Sulla base dei benchmark e dei limiti del backend di Woodpecker, ottimizzare il throughput di scrittura end-to-end tenendo conto dei seguenti aspetti:
- Lato storage
- Archiviazione a oggetti (compatibile con MinIO/S3): aumentare la concorrenza e la dimensione degli oggetti (evitare oggetti di piccole dimensioni). Prestare attenzione ai limiti di larghezza di banda della rete e del bucket. Un singolo nodo MinIO su SSD spesso raggiunge un limite massimo di circa 100 MB/s a livello locale; un singolo EC2 verso S3 può raggiungere GB/s.
- File system locali/condivisi (locali): prediligere dischi NVMe o veloci. Assicurarsi che il file system gestisca bene le piccole operazioni di scrittura e la latenza di fsync.
- Regolatori di Woodpecker
- Aumentare i valori di `
logstore.segmentSyncPolicy.maxFlushSize` e `maxFlushThreads` per eseguire operazioni di flush più grandi e ottenere un parallelismo maggiore. - Ottimizzare
maxIntervalin base alle caratteristiche del supporto (scambiare latenza per throughput con un'aggregazione più lunga). - Per l’object storage, valutare di aumentare
segmentRollingPolicy.maxSizeper ridurre i cambi di segmento.
- Aumentare i valori di `
- Lato client/applicazione
- Utilizzare batch di dimensioni maggiori e un numero maggiore di scrittori/client simultanei.
- Controllare i tempi di aggiornamento/creazione dell’indice (preparare il batch prima dell’attivazione) per evitare frequenti scritture di piccole dimensioni.
Modalità di servizio (Milvus 3.0+)
La modalità di servizio mantiene l'elevato throughput di scrittura di un WAL supportato da archiviazione a oggetti, aggiungendo al contempo una bassa latenza (vedere Latenza). Le ottimizzazioni sopra descritte sia sul lato storage che sul lato client rimangono valide; inoltre, poiché Woodpecker viene eseguito come servizio a sé stante, è possibile scalare orizzontalmente la capacità di scrittura aggiungendo repliche (woodpecker.replicaCount, 4 per impostazione predefinita), e le operazioni di scrittura beneficiano della replica con quorum a un RTT e di letture sensibili alla topologia che evitano l’inoltro da parte del broker.
Dimostrazione di inserimento in batch — utilizzare quanto segue per misurare la velocità di scrittura:
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}")
Latenza
Modalità integrata
Woodpecker è un WAL cloud-native progettato per lo storage a oggetti, che presenta un compromesso tra throughput, costo e latenza. La modalità incorporata, leggera, dà priorità all’ottimizzazione dei costi e del throughput, poiché la maggior parte degli scenari richiede solo che i dati vengano scritti entro un determinato tempo, piuttosto che esigere una bassa latenza per le singole richieste di scrittura. Pertanto, Woodpecker impiega scritture in batch, con intervalli predefiniti di 10 ms per i backend di archiviazione del filesystem locale e di 200 ms per i backend di archiviazione di tipo MinIO. Durante le operazioni di scrittura lente, la latenza massima è pari al tempo dell’intervallo più il tempo di flush.
Si noti che l’inserimento in batch viene attivato non solo dagli intervalli di tempo, ma anche dalla dimensione del batch, che per impostazione predefinita è di 2 MB.
Modalità Service (Milvus 3.0+)
La modalità di servizio offre una latenza di scrittura dell’ordine dei millisecondi — dello stesso ordine di grandezza di un WAL tradizionale su disco locale a tre repliche — mantenendo bassi i costi. In una tipica implementazione a tre repliche tra zone (AZ), la latenza di scrittura rimane nell’ordine dei millisecondi. Ciò si ottiene tramite:
- Scritture con quorum a un RTT — la replica guidata dal client completa una scrittura con quorum entro un singolo round trip, con il traffico tra le zone (AZ) limitato al volume di dati corrispondente a due repliche (rispetto al traffico aggiuntivo tra le zone pari a circa 1/3, tipico della replica basata su broker/leader).
- Letture a salto singolo sensibili alla topologia: ogni lettura viene indirizzata direttamente alla replica più vicina invece di essere inoltrata tramite un broker, evitando le letture casuali tra le zone (≈2/3 del traffico di lettura tra le zone) tipiche dei sistemi basati su broker.
- Caricamento immediato nell’object storage dopo il rollover del segmento — ogni segmento tiene traccia del proprio intero ciclo di vita e viene caricato nell’object storage non appena viene sottoposto a rollover, mantenendo basso l’ingombro sul disco locale e i costi di archiviazione senza compromettere la latenza.
- Nessuna replica continua da nodo a nodo — i log vengono persistiti nell’object storage che funge da storage condiviso, quindi il failover ricarica solo le repliche sopravvissute (senza copia dell’intero nodo), lo scaling non è vincolato dalla larghezza di banda della replica inter-nodo e la sostituzione di nodi su larga scala non causa picchi di replica.
Nelle distribuzioni tra zone di disponibilità (AZ), la modalità di servizio consente inoltre di risparmiare circa 1/3 del traffico di rete in scrittura e 2/3 di quello in lettura tra le AZ rispetto ai sistemi di log basati su broker. Per l’analisi completa della progettazione e dei costi, consultare Architettura di Woodpecker.
Per i dettagli sull’architettura, le modalità di distribuzione (MemoryBuffer / QuorumBuffer) e le prestazioni, consultare l’architettura di Woodpecker.
Per ulteriori dettagli sui parametri, consultare il repository GitHub di Woodpecker.