Woodpecker
O Woodpecker é a fila de mensagens predefinida (registo antecipado, WAL) no Milvus 3.x. Trata-se de um WAL nativo da nuvem concebido para armazenamento de objetos, que oferece elevado débito, baixa sobrecarga operacional e escalabilidade sem interrupções. Para obter detalhes sobre a arquitetura e os testes de desempenho, consulte Woodpecker.
Visão geral
- No Milvus 3.x, o Woodpecker é o WAL/fila de mensagens predefinido, proporcionando gravações ordenadas e recuperação enquanto serviço de registo. Não é necessário qualquer serviço externo de fila de mensagens (como o Pulsar ou o Kafka).
- O Woodpecker pode ser executado incorporado no nó Milvus/streaming (por predefinição) ou como um serviço dedicado com os seus próprios pods (apenas em modo distribuído/cluster).
- Suporta três modos de «
storage.type»: armazenamento de objetos (minio, o padrão), sistema de ficheiros local (local) e oservicededicado. Consulte Modos de implementação.
Início rápido
Para ativar o Woodpecker, defina o tipo de MQ como Woodpecker:
mq:
type: woodpecker
Nota: A mudança d mq.type e num cluster em execução é uma operação de atualização. Siga cuidadosamente o procedimento de atualização e valide num cluster novo antes de efetuar a mudança no ambiente de produção.
Configuração
Segue-se o bloco de configuração completo do Woodpecker (edite milvus.yaml ou substitua em 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.
Notas importantes:
woodpecker.meta- type: Atualmente, apenas o
etcdé suportado. Reutilize o mesmo etcd do Milvus para armazenar metadados ligeiros. - prefixo: O prefixo da chave para os metadados. Padrão:
woodpecker.
- type: Atualmente, apenas o
woodpecker.client- Controla o comportamento de acréscimo, rotação e auditoria de segmentos no lado do cliente para equilibrar o débito e a latência de ponta a ponta.
woodpecker.logstore- Controla as políticas de sincronização, esvaziamento, compactação e leitura para segmentos de registo. Estes são os principais parâmetros para o ajuste da taxa de transferência e da latência.
woodpecker.storage- tipo:
miniopara armazenamento de objetos compatível com MinIO/S3 (MinIO/S3/GCS/OSS, etc.);localpara sistemas de ficheiros locais/partilhados. - rootPath: Caminho raiz para o backend de armazenamento (aplicável a
local; comminio, os caminhos são determinados pelo bucket/prefixo).
- tipo:
Modos de implementação
O Woodpecker suporta três modos de storage.type:
storage.type | Como funciona o Woodpecker | Backend WAL | Milvus Autônomo | Milvus Distribuído (cluster) |
|---|---|---|---|---|
minio (padrão) | Incorporado no nó Milvus/streaming | Armazenamento de objetos (compatível com MinIO/S3) | Compatível | Suportado |
local | Incorporado no nó Milvus/streaming | Sistema de ficheiros local | Suportado | Limitado (todos os nós necessitam de um sistema de ficheiros partilhado, por exemplo, NFS) |
service | Serviço Woodpecker dedicado (com os seus próprios pods) | Armazenamento de objetos (compatível com MinIO/S3) | Não suportado | Suportado |
Notas:
- Com o «
minio», o Woodpecker partilha o mesmo armazenamento de objetos com o Milvus (MinIO/S3/GCS/OSS, etc.). - Com o modo «
local», um disco local de nó único só é adequado para o modo «Standalone». Se todos os pods puderem aceder a um sistema de ficheiros partilhado (por exemplo, NFS), o modo «Cluster» também pode utilizar o modo «local». serviceO modo «Cluster» executa o Woodpecker como um serviço separado e escalável de forma independente, estando disponível apenas para implementações distribuídas/em cluster. As implementações «Standalone» utilizam os modos incorporados (miniooulocal).
Compatibilidade com armazenamento de objetos para storage.type=minio
A matriz seguinte resume a compatibilidade atualmente conhecida dos back-ends de armazenamento de objetos quando o Woodpecker está configurado com storage.type=minio. Esta informação baseia-se na Discussão n.º 150 do GitHub.
| Fornecedor/serviço | Estado | Notas |
|---|---|---|
| Armazenamento de Blobs do Azure | Suportado | Utiliza o SDK nativo do Azure. |
| AWS S3 | Compatível | S3 nativo com suporte total à escrita condicional. |
MinIO (>= 2024-12) | Compatível | Suporte total à escrita condicional do S3. |
| Aliyun OSS | Compatível | Compatível através da sua interface compatível com S3. |
| Tencent COS | Compatível | Compatível através da sua interface compatível com S3. |
| Google Cloud Storage (GCS) | Compatível | Compatível através do modo de interoperabilidade S3. |
| Huawei Cloud OBS | Não suportado | Não dispõe da semântica de escrita condicional necessária. |
| VAST Data | Compatível | Verificado pela comunidade; funciona apenas com buckets sem versões. |
| Outros armazenamentos compatíveis com S3 | Parcial | Depende do suporte total à semântica de escrita condicional do S3. |
Notas:
- A compatibilidade depende do suporte nativo do SDK ou do suporte à semântica de escrita condicional do S3.
- Se hospedar o MinIO para o Woodpecker, utilize a versão
RELEASE.2024-12-18T13-15-44Zou posterior. - Esta matriz reflete a discussão atual e poderá evoluir à medida que o suporte do backend for sendo validado.
Guias de implementação
Ativar o Woodpecker num cluster Milvus no Kubernetes (Milvus Operator, storage=minio)
Após instalar o Milvus Operator, inicie um cluster Milvus com o Woodpecker ativado utilizando o exemplo oficial:
kubectl apply -f https://raw.githubusercontent.com/zilliztech/milvus-operator/main/config/samples/milvus_cluster_woodpecker.yaml
Este exemplo configura o Woodpecker como fila de mensagens e ativa o Nodo de Streaming. A primeira inicialização pode demorar algum tempo a descarregar as imagens; aguarde até que todos os pods estejam prontos:
kubectl get pods
kubectl get milvus my-release -o yaml | grep -A2 status
Quando estiver pronto, deverá ver pods semelhantes a:
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
Execute o seguinte comando para desinstalar o cluster Milvus.
kubectl delete milvus my-release
Se precisar de ajustar os parâmetros do Woodpecker, siga as configurações descritas em «Configuração».
Ativar o Woodpecker para um cluster Milvus no Kubernetes (Helm Chart, storage=minio)
Primeiro, adicione e atualize o Helm Chart do Milvus, conforme descrito em Executar o Milvus no Kubernetes com o Helm.
Em seguida, efetue a implementação com um dos seguintes exemplos:
– Implantação em cluster (configurações recomendadas com o Woodpecker e o Streaming Node ativados):
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
– Implantação autónoma (Woodpecker ativado):
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
Após a implementação, siga a documentação para redirecionar portas e estabelecer a ligação. Para ajustar os parâmetros do Woodpecker, siga as configurações descritas em «Configuração».
Ativar o Woodpecker para o Milvus autónomo no Docker (storage=local)
No Milvus 3.x, a implementação autónoma no Docker utiliza o Woodpecker com o sistema de ficheiros local como backend WAL por predefinição — não é necessária qualquer configuração adicional. Siga as instruções em «Executar o Milvus no 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
Para ajustar o Woodpecker, edite o ficheiro « user.yaml » gerado após o primeiro arranque e execute « bash standalone_embed.sh restart » para aplicar as alterações (uma nova execução de « start » regenera o ficheiro « user.yaml », pelo que deve aplicar as edições com « restart »):
# user.yaml
woodpecker:
logstore:
segmentSyncPolicy:
maxFlushThreads: 16
Ativar o Woodpecker para o Milvus Standalone com o Docker Compose (storage=minio)
Siga as instruções de «Executar o Milvus com o Docker Compose». Exemplo:
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
Ativar o modo de serviço do Woodpecker para um cluster Milvus (Helm)
Para o modo de serviço do Woodpecker, recomendamos a utilização da próxima versão do Milvus 3.0.1 ou de uma versão posterior com o Woodpecker v0.1.37 ou posterior, para otimizações de limpeza de compactação e de submissão em grupo.
O modo de serviço do Woodpecker é uma funcionalidade do Milvus 3.0. Para implementações distribuídas/em cluster, pode executar o Woodpecker como um serviço dedicado (pods separados) em vez de incorporado no nó de streaming, definindo ` 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
Isto implementa o Woodpecker como um StatefulSet dedicado (my-release-milvus-woodpecker, 4 réplicas por predefinição) liderado por um serviço sem interface gráfica, agrupado por gossip nas portas 18080 (serviço), 17946 (gossip) e 9091 (métricas), com o MinIO como backend de armazenamento. O serviço necessita de um quórum de 3 nós; o valor predefinido de 4 réplicas mantém o quórum, tolerando a falha de um único nó, pelo que não se deve definir woodpecker.replicaCount abaixo de 3. O cluster inclui então um conjunto separado de pods woodpecker:
my-release-milvus-woodpecker-0
my-release-milvus-woodpecker-1
my-release-milvus-woodpecker-2
my-release-milvus-woodpecker-3
O modo de serviço do Woodpecker ( service ) destina-se apenas a implementações distribuídas/em cluster — as implementações autónomas executam o Woodpecker incorporado (minio ou local). O Milvus Operator ainda não suporta o modo de serviço do Woodpecker.
Dicas de otimização do débito
O perfil de débito e latência do Woodpecker difere entre o modo incorporado e o modo de serviço (uma funcionalidade do Milvus 3.0). As orientações abaixo estão organizadas por modo.
Modo incorporado
Com base nos testes de desempenho e nos limites do backend do Woodpecker, otimize a taxa de transferência de gravação de ponta a ponta a partir dos seguintes aspetos:
- Lado do armazenamento
- Armazenamento de objetos (compatível com MinIO/S3): Aumente a simultaneidade e o tamanho dos objetos (evite objetos muito pequenos). Esteja atento aos limites de largura de banda da rede e dos buckets. Um único nó MinIO em SSD costuma atingir um limite de cerca de 100 MB/s localmente; uma única ligação EC2 para S3 pode atingir GB/s.
- Sistemas de ficheiros locais/partilhados (locais): Dê preferência a NVMe/discos rápidos. Certifique-se de que o sistema de ficheiros lida bem com pequenas gravações e com a latência do fsync.
- Parâmetros do Woodpecker
- Aumente os parâmetros `
logstore.segmentSyncPolicy.maxFlushSize` e `maxFlushThreads` para realizar flushes maiores e obter maior paralelismo. - Ajuste
maxIntervalde acordo com as características do suporte (troque latência por débito com uma agregação mais longa). - Para o armazenamento de objetos, considere aumentar
segmentRollingPolicy.maxSizepara reduzir as trocas de segmentos.
- Aumente os parâmetros `
- Lado do cliente/aplicação
- Utilize lotes de maior dimensão e mais gravadores/clientes simultâneos.
- Controle o momento da atualização/criação do índice (agrupe antes de acionar) para evitar pequenas gravações frequentes.
Modo de serviço (Milvus 3.0+)
O modo de serviço mantém a elevada taxa de transferência de gravação de um WAL suportado por armazenamento de objetos, ao mesmo tempo que adiciona baixa latência (ver Latência). O ajuste do lado do armazenamento e do lado do cliente acima continua a aplicar-se; além disso, como o Woodpecker funciona como um serviço próprio, é possível escalar a capacidade de gravação horizontalmente adicionando réplicas (woodpecker.replicaCount, valor predefinido 4), e as gravações beneficiam da replicação de quórum de um RTT e de leituras sensíveis à topologia que evitam o reencaminhamento pelo broker.
Demonstração de inserção em lote — utilize o seguinte para medir a taxa de transferência de gravação:
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}")
Latência
Modo incorporado
O Woodpecker é um WAL nativo da nuvem concebido para armazenamento de objetos, com compromissos entre débito, custo e latência. O modo incorporado leve dá prioridade à otimização de custo e débito, uma vez que a maioria dos cenários apenas requer que os dados sejam gravados dentro de um determinado prazo, em vez de exigir baixa latência para pedidos de gravação individuais. Por conseguinte, o Woodpecker recorre a gravações em lote, com intervalos predefinidos de 10 ms para back-ends de armazenamento em sistemas de ficheiros locais e de 200 ms para back-ends de armazenamento do tipo MinIO. Durante operações de gravação lentas, a latência máxima é igual ao tempo do intervalo mais o tempo de flush.
Note-se que a inserção em lotes é desencadeada não só por intervalos de tempo, mas também pelo tamanho do lote, cujo valor predefinido é de 2 MB.
Modo de serviço (Milvus 3.0+)
O modo de serviço proporciona uma latência de gravação da ordem dos milissegundos — comparável à de um WAL tradicional em disco local com três réplicas — mantendo os custos baixos. Numa implementação típica com três réplicas e entre zonas de disponibilidade (AZ), a latência de gravação mantém-se na ordem dos milissegundos. Isto é conseguido através de:
- Gravações de quórum em um RTT — a replicação orientada pelo cliente conclui uma gravação de quórum num único round trip, com o tráfego entre zonas fixado no equivalente a dois réplicas de dados (em comparação com o tráfego extra entre zonas de cerca de 1/3, típico da replicação baseada em broker/líder).
- Leituras de salto único sensíveis à topologia — cada leitura vai diretamente para a réplica mais próxima, em vez de ser reencaminhada através de um broker, evitando as leituras aleatórias entre zonas (≈2/3 do tráfego de leitura entre zonas) dos sistemas baseados em broker.
- Carregamento imediato para o armazenamento de objetos após a rotação do segmento — cada segmento acompanha todo o seu ciclo de vida e é carregado para o armazenamento de objetos assim que é rodado, mantendo a ocupação do disco local e os custos de armazenamento baixos, sem comprometer a latência.
- Sem replicação contínua de nó para nó — os registos persistem no armazenamento de objetos, que funciona como armazenamento partilhado; assim, o failover apenas volta a carregar as réplicas sobreviventes (sem cópia do nó inteiro), o escalonamento não é limitado pela largura de banda de replicação entre nós e a substituição de nós em grande escala não provoca picos de replicação.
Em implementações entre zonas de disponibilidade (AZ), o modo de serviço também poupa cerca de 1/3 do tráfego de rede de escrita e 2/3 do tráfego de leitura entre zonas de disponibilidade, em comparação com sistemas de registos baseados em broker. Para a análise completa do design e dos custos, consulte a Arquitetura do Woodpecker.
Para obter detalhes sobre a arquitetura, os modos de implementação (MemoryBuffer / QuorumBuffer) e o desempenho, consulte a Arquitetura do Woodpecker.
Para mais detalhes sobre os parâmetros, consulte o repositório do Woodpecker no GitHub.