Preparação
Neste artigo, iremos descrever principalmente a forma como os dados vectoriais são registados na memória do Milvus, e como estes registos são mantidos.
Abaixo estão os nossos principais objectivos de conceção:
- A eficiência da importação de dados deve ser elevada.
- Os dados podem ser vistos o mais rapidamente possível após a sua importação.
- Evitar a fragmentação dos ficheiros de dados.
Por conseguinte, criámos uma memória intermédia (memória intermédia de inserção) para inserir os dados, a fim de reduzir o número de comutações de contexto de E/S aleatórias no disco e no sistema operativo para melhorar o desempenho da inserção de dados. A arquitetura de armazenamento em memória baseada em MemTable e MemTableFile permite-nos gerir e serializar os dados de forma mais conveniente. O estado do buffer é dividido em Mutável e Imutável, o que permite que os dados sejam persistidos no disco, mantendo os serviços externos disponíveis.
Preparação
Quando o utilizador está pronto para inserir um vetor no Milvus, precisa primeiro de criar uma Collection (* O Milvus renomeia Table para Collection na versão 0.7.0). A coleção é a unidade mais básica para registar e pesquisar vectores no Milvus.
Cada coleção tem um nome único e algumas propriedades que podem ser definidas, e os vectores são inseridos ou pesquisados com base no nome da coleção. Ao criar uma nova coleção, o Milvus regista a informação dessa coleção nos metadados.
Inserção de dados
Quando o utilizador envia um pedido de inserção de dados, os dados são serializados e desserializados para chegar ao servidor Milvus. Os dados são agora escritos em memória. A escrita em memória divide-se, grosso modo, nas seguintes etapas:
2-data-insertion-milvus.png
- No MemManager, localize ou crie uma nova MemTable correspondente ao nome da coleção. Cada MemTable corresponde a um buffer da Coleção na memória.
- Uma MemTable conterá um ou mais MemTableFile. Sempre que criamos um novo MemTableFile, registamos essa informação no Meta ao mesmo tempo. Dividimos os MemTableFile em dois estados: Mutável e Imutável. Quando o tamanho do MemTableFile atinge o limite, torna-se Imutável. Cada MemTable só pode ter um MemTableFile Mutável a ser escrito em qualquer altura.
- Os dados de cada MemTableFile serão finalmente registados na memória no formato do tipo de índice definido. A MemTableFile é a unidade mais básica para gerir dados em memória.
- Em qualquer altura, a utilização de memória dos dados inseridos não excederá o valor predefinido (insert_buffer_size). Isto porque, a cada pedido de inserção de dados, o MemManager pode facilmente calcular a memória ocupada pelo MemTableFile contido em cada MemTable e, em seguida, coordenar o pedido de inserção de acordo com a memória atual.
Através da arquitetura multi-nível do MemManager, MemTable e MemTableFile, a inserção de dados pode ser melhor gerida e mantida. Naturalmente, eles podem fazer muito mais do que isso.
Consultas quase em tempo real
No Milvus, só é necessário esperar um segundo, no máximo, para que os dados inseridos passem da memória para o disco. Todo esse processo pode ser resumido na figura a seguir:
2-near-real-time-query-milvus.png
Primeiro, os dados inseridos entrarão num buffer de inserção na memória. O buffer mudará periodicamente do estado Mutável inicial para o estado Imutável em preparação para a serialização. Em seguida, esses buffers imutáveis serão serializados para o disco periodicamente pelo thread de serialização em segundo plano. Depois de os dados serem colocados, a informação da ordem será registada nos metadados. Neste ponto, os dados podem ser pesquisados!
Agora, vamos descrever os passos da figura em pormenor.
Já conhecemos o processo de inserção de dados no buffer mutável. O próximo passo é mudar do buffer mutável para o buffer imutável:
3-mutable-buffer-immutable-buffer-milvus.png
A fila imutável fornecerá à thread de serialização em segundo plano o estado imutável e o MemTableFile que está pronto para ser serializado. Cada MemTable gerencia sua própria fila imutável, e quando o tamanho do único MemTableFile mutável da MemTable atinge o limite, ele entra na fila imutável. Uma thread em segundo plano responsável por ToImmutable irá periodicamente puxar todos os MemTableFiles na fila imutável gerenciada por MemTable e enviá-los para a fila total Immutable. É de notar que as duas operações de escrita de dados na memória e de alteração dos dados na memória para um estado que não pode ser escrito não podem ocorrer ao mesmo tempo, sendo necessário um bloqueio comum. No entanto, a operação de ToImmutable é muito simples e quase não causa qualquer atraso, pelo que o impacto no desempenho dos dados inseridos é mínimo.
O próximo passo é serializar o MemTableFile na fila de serialização para o disco. Isso é dividido principalmente em três etapas:
4-serialize-memtablefile-milvus.png
Primeiro, a thread de serialização em segundo plano puxa periodicamente o MemTableFile da fila imutável. Em seguida, eles são serializados em arquivos brutos de tamanho fixo (Raw TableFiles). Por fim, registamos esta informação nos metadados. Quando efectuarmos uma pesquisa vetorial, consultaremos o TableFile correspondente nos metadados. A partir daqui, estes dados podem ser pesquisados!
Além disso, de acordo com o conjunto index_file_size, depois de o thread de serialização completar um ciclo de serialização, irá fundir alguns TableFiles de tamanho fixo num TableFile e também registar estas informações nos metadados. Neste momento, o TableFile pode ser indexado. A construção do índice também é assíncrona. Outro thread em segundo plano responsável pela construção do índice lerá periodicamente o TableFile no estado ToIndex dos metadados para executar a construção do índice correspondente.
Pesquisa vetorial
De facto, verificará que, com a ajuda do TableFile e dos metadados, a pesquisa vetorial se torna mais intuitiva e conveniente. Em geral, precisamos de obter os TableFiles correspondentes à coleção consultada a partir dos metadados, pesquisar em cada TableFile e, por fim, fundir. Neste artigo, não nos aprofundamos na implementação específica da pesquisa.
Se quiser saber mais, pode ler o nosso código fonte, ou ler os nossos outros artigos técnicos sobre o Milvus!
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word