milvus向量数据库

版本介绍

Milvus Lite

Milvus Lite是一个 Python 库,可导入到您的应用程序中。作为 Milvus 的轻量级版本,它非常适合在 Jupyter 笔记本或资源有限的智能设备上运行快速原型。Milvus Lite 支持与 Milvus 其他部署相同的 API。与 Milvus Lite 交互的客户端代码也能与其他部署模式下的 Milvus 实例协同工作。

要将 Milvus Lite 集成到应用程序中,请运行pip install pymilvus 进行安装,并使用MilvusClient("./demo.db") 语句实例化一个带有本地文件的向量数据库,以持久化所有数据。更多详情,请参阅运行 Milvus Lite

Milvus Lite 目前支持以下环境:

  • Ubuntu >= 20.04(x86_64 和 arm64)
  • MacOS >= 11.0(苹果硅 M1/M2 和 x86_64)

Milvus 单机版

Milvus Standalone 是单机服务器部署。Milvus Standalone 的所有组件都打包到一个Docker 镜像中,部署起来非常方便。如果你有生产工作负载,但又不想使用 Kubernetes,那么在内存充足的单机上运行 Milvus Standalone 是一个不错的选择。此外,Milvus Standalone 通过主从复制支持高可用性。

分布式 Milvus

Milvus Distributed 可部署在Kubernetes集群上。这种部署采用云原生架构,摄取负载和搜索查询分别由独立节点处理,允许关键组件冗余。它具有最高的可扩展性和可用性,并能灵活定制每个组件中分配的资源。Milvus Distributed 是在生产中运行大规模向量搜索系统的企业用户的首选。

Milvus 单机版部署

使用Docker Compose安装 Milvus standalone(即单机版),进行一个快速milvus的体验。

前提条件:

1.系统可以使用centos或者ubuntu,这里使用的是Ubuntu 20.04.6 LTS

2.系统已经安装docker和docker-compose

3.milvus版本这里使用2.3.12

启动etcd、minio、milvus

由于milvus依赖etcd和minio,因此需要先启动这2个组件。同样也使用docker进行启动。

etcd:用来存储milvus的元数据。

minio:用来存储milvus的向量数据和索引数据。

下载milvus-standalone-docker-compose.yml 文件,保存为docker-compose.yml:

bash 复制代码
wget https://github.com/milvus-io/milvus/releases/download/v2.3.12/milvusstandalone-docker-compose.yml -O docker-compose.yml

这里经过了一定修改,让其更加方便使用。 这个yml文件里面定义了etcd、minio、milvus的启动参数。 修改后的docker-compose.yml文件内容如下

bash 复制代码
version: '3.5'

services:
  etcd:
    container_name: milvus-etcd
    image: quay.io/coreos/etcd:v3.5.5
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/etcd:/etcd
    ports:
      - "2379:2379"
    command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls=http://0.0.0.0:2379 --data-dir /etcd
    healthcheck:
      test: ["CMD", "etcdctl", "endpoint", "health"]
      interval: 5s
      timeout: 3s
      retries: 10

  minio:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    ports:
      - "9001:9001"
      - "9000:9000"
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
    command: minio server /minio_data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 5s
      timeout: 3s
      retries: 10

  standalone:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.3.12
    command: ["milvus", "run", "standalone"]
    security_opt:
      - seccomp:unconfined
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/milvus:/var/lib/milvus
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
      interval: 30s
      start_period: 90s
      timeout: 20s
      retries: 3
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - etcd
      - minio  

  attu:
    image: zilliz/attu:v2.3.8
    container_name: milvus-attu
    environment:
      MILVUS_URL: standalone:19530
    ports:
      - "8000:3000"
    depends_on:
      - standalone

networks:
  default:
    name: milvus

启动

bash 复制代码
docker-compose up -d
-d 代表后台启动

其他命令
docker-compose ps 查看容器
docker-compose stop 停止容器
docker-compose start 启动容器
docker-compose down 停止并删除容器(特别注意以免误删容器)

启动attu可视化

bash 复制代码
docker run -d \
--name=attu \
-p 8000:3000 \
-e MILVUS_URL=101.126.141.93:19530 \
zilliz/attu:v2.3.9

http://101.126.141.93:8000/

整合springbootcrud

https://gitee.com/zhang-hai-fei/ollama-deep-seek-milvus-test.git

pom
xml 复制代码
        <dependency>
            <groupId>io.milvus</groupId>
            <artifactId>milvus-sdk-java</artifactId>
            <version>2.5.4</version>
        </dependency>
config
java 复制代码
package org.caizhi.corporation.config;

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class MilvusConfig {
 
    @Value("${milvus.host}")
    private String host;
    @Value("${milvus.port}")
    private Integer port;
    @Value("${milvus.db}")
    private String DATABASE_NAME; // 指定数据库名称
    @Value("${milvus.username}")
    private String username;
    @Value("${milvus.password}")
    private String password;

    @Bean
    public MilvusClientV2 milvusClientV2() {
 
        String uri = "http://"+host+":"+port;
        ConnectConfig connectConfig = ConnectConfig.builder()
                .uri(uri)
                .username(username)
                .password(password)
                .dbName(DATABASE_NAME)
                .build();
       return new MilvusClientV2(connectConfig);
    }
}
yaml
yaml 复制代码
server:
  port: 8080
milvus:
  host: 101.126.141.93
  port: 19530
  db: test
  password: admin123
  username: admin
service
java 复制代码
package org.caizhi.corporation.service;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import io.milvus.v2.service.vector.request.GetReq;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.GetResp;
import io.milvus.v2.service.vector.response.InsertResp;
import io.milvus.v2.service.vector.response.SearchResp;
import org.caizhi.corporation.entity.TestRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
@Component
public class MilvusDemoService {
 
    private static final Logger log = LoggerFactory.getLogger(MilvusDemoService.class);
 
    //类似于mysql中的表,定义一个名称为collection_01的集合
    private static final String COLLECTION_NAME = "collection_test";
    //为了测试验证方便,向量维度定义2
    private static final int VECTOR_DIM = 2;


    private final MilvusClientV2 client;
 
    public MilvusDemoService(MilvusClientV2 client) {
        this.client = client;
    }
 
    /**
     * 创建一个Collection
     */
    public void createCollection() {
 
        CreateCollectionReq.CollectionSchema schema = client.createSchema();
 
        schema.addField(AddFieldReq.builder()
                .fieldName("id")
                .dataType(DataType.VarChar)
                .isPrimaryKey(true)
                .autoID(false)
                .build());
 
        schema.addField(AddFieldReq.builder()
                .fieldName("title")
                .dataType(DataType.VarChar)
                .maxLength(10000)
                .build());
 
        schema.addField(AddFieldReq.builder()
                .fieldName("title_vector")
                .dataType(DataType.FloatVector)
                .dimension(VECTOR_DIM)
                .build());
 
        IndexParam indexParam = IndexParam.builder()
                .fieldName("title_vector")
                .metricType(IndexParam.MetricType.COSINE)
                .build();
 
        CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
                .collectionName(COLLECTION_NAME)
                .collectionSchema(schema)
                .indexParams(Collections.singletonList(indexParam))
                .build();
 
        client.createCollection(createCollectionReq);
    }
 
    /**
     * 往collection中插入一条数据
     */
    public void insertRecord(TestRecord record) {
        JsonObject vector = new JsonObject();
        vector.addProperty("id", record.getId());
        vector.addProperty("title", record.getTitle());
        List<Float> vectorList = new ArrayList<>();
        //为了模拟测试,向量写死2个
        vectorList.add(2.8f);
        vectorList.add(3.9f);
        Gson gson = new Gson();
        vector.add("title_vector", gson.toJsonTree(vectorList));
 
        InsertReq insertReq = InsertReq.builder()
                .collectionName(COLLECTION_NAME)
                .data(Collections.singletonList(vector))
                .build();
        InsertResp resp = client.insert(insertReq);
 
    }
 
    /**
     * 通过ID获取记录
     */
    public GetResp getRecord(String id) {
        GetReq getReq = GetReq.builder()
                .collectionName(COLLECTION_NAME)
                .ids(Collections.singletonList(id))
                .build();
        GetResp resp = client.get(getReq);
        return resp;
    }
 
    /**
     * 按照向量检索,找到相似度最近的topK
     */
    public List<List<SearchResp.SearchResult>>  queryVector() {
        SearchResp searchR = client.search(SearchReq.builder()
                .collectionName(COLLECTION_NAME)
                .data(Collections.singletonList(new FloatVec(new float[]{0.9f, 2.1f})))
                .topK(3)
                .outputFields(Collections.singletonList("*"))
                .build());
        List<List<SearchResp.SearchResult>> searchResults = searchR.getSearchResults();
        for (List<SearchResp.SearchResult> results : searchResults) {
            for (SearchResp.SearchResult result : results) {
                log.info("ID="+(String)result.getId() + ",Score="+result.getScore() + ",Result="+result.getEntity().toString());
            }
        }
        return searchResults;
    }
 
 
}
controller
java 复制代码
package org.caizhi.corporation.controller;

import io.milvus.v2.service.vector.response.GetResp;
import io.milvus.v2.service.vector.response.SearchResp;
import org.caizhi.corporation.entity.TestRecord;
import org.caizhi.corporation.service.MilvusDemoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
 
import java.io.IOException;
import java.util.List;
 
 
@RestController
@RequestMapping("/milvus")
public class MilvusController {
    private static final Logger log = LoggerFactory.getLogger(MilvusController.class);
 
    @Autowired
    private MilvusDemoService milvusDemoService;
 
 
    @GetMapping("/createCollection")
    public void createCollection() {
        milvusDemoService.createCollection();
    }
 
    @GetMapping("/insertRecord")
    public void insertRecord() throws IOException {
        TestRecord record = new TestRecord();
        record.setId("6");
        record.setTitle("上海不是中国的首都,人口有3000多万人");
        milvusDemoService.insertRecord(record);
    }
 
    @GetMapping("/getRecord")
    public GetResp getRecord(@RequestParam(name = "id") String id){
        GetResp resp = milvusDemoService.getRecord(id);
        log.info("resp = " +  resp.getResults);
        return resp;
    }
 
    @GetMapping("/queryVector")
    public List<List<SearchResp.SearchResult>> queryVector() {
        List<List<SearchResp.SearchResult>> searchResults = milvusDemoService.queryVector();
        return searchResults;
    }
 
}
相关推荐
chushiyunen2 小时前
langgraph笔记
数据库·人工智能·笔记
切糕师学AI2 小时前
PostgreSQL 中的 pg_trgm GIN 索引详解
数据库·postgresql·gin·索引·pg_grgm
爱丽_2 小时前
MySQL 锁与死锁:行锁、间隙锁、Next-Key Lock 与排查手册
数据库·mysql
皙然2 小时前
Redis 持久化机制超详细详解(RDB+AOF 双方案 + 生产实战)
数据库·redis·bootstrap
Magic--2 小时前
进程间通信(IPC):原理、场景与选型
java·服务器·数据库
xhuiting3 小时前
MySQL专题总结(三)—— 补充篇
数据库·mysql
智象科技3 小时前
告警自动化赋能运维:意义与价值解析
网络·数据库·人工智能·自动化·告警·一体化运维·ai运维
源远流长jerry3 小时前
在云环境中部署 NFV:OpenStack 讲解
数据库·openstack
※DX3906※3 小时前
SpringBoot之旅4: MyBatis 操作数据库(进阶) 动态SQL+MyBatis-Plus实战,从入门到熟练,再也不踩绑定异常、SQL拼接坑
java·数据库·spring boot·spring·java-ee·maven·mybatis