milvus 简介

milvus是干什么的?通俗的讲,milvus可以让你在海量向量库中快速检索到和目标向量最相似的若干个向量,这里相似度量标准可以是内积或者欧式距离等。借用官方的话说就是:

Milvus 是一款开源的、针对海量特征向量的相似性搜索引擎。基于异构众核计算框架设计,成本更低,性能更好。 在有限的计算资源下,十亿向量搜索仅毫秒响应。

说白了就是速度快,先不说十亿向量,自己写代码去完成对100万300维向量的余弦相似度计算并排序就需要不小的响应时间吧,就本人测试而言,即便使用scipy库计算速度依然要比milvus慢很多。

milvus和Faiss的对比

其实在milvus开源之前,也存在高性能向量相似性搜索引擎(库),这个引擎就是Facebook的Faiss,它的功能和milvus是一样的,所以就不再做过多介绍,具体可以参考官网

就我个人而言,我是推荐使用milvus的,主要是在我个人看来,milvus有如下几个好处:

  • 多平台通用,mac,windows和linux都是支持的,因为milvus可以通过docker部署,因此平台通用性好了不少。
  • 支持编程语言多,Java,c,c++和python都支持,要知道Faiss是不支持java的,这一点简直让人抓狂,github上好几个项目就是关于把Faiss转成java的,因为我Java和python都是要使用的,我把github上关于faiss转java的项目都试了个遍,结论就是非常难安装,只要Faiss版本更新了,必须要重来一遍,即便最后java可以用了,也不敢保证其稳定性。所以想在Java上用Faiss还是放弃吧。
  • 在速度方面,就我自己测试而言,milvus不输Faiss,但是我没有使用GPU测试,有兴趣的小伙伴可以试一下。

当然milvus也有难用的地方,我自己发现了两点,如果是我自己使用不当造成的,还请各位朋友在评论指出:

  • milvus的向量格式不支持numpy,要用列表的形式存储向量,而列表占用内存要远远大于ndarray的,这对于小内存主机简直是个天灾,我16GB内存情况下,把500000*768的矩阵转成list,电脑直接卡死。
  • milvus在第一次search时速度会慢,之后机会快起来了,这应该是个小bug,有人在github提出了,应该很快就可以修复,所以你们在测试milvus的速度时千万别算第一次的时间。

milvus 安装及常见问题

milvus 一共有两种安装方式:自己编译安装和使用docker安装。这里推荐大家使用docker安装,docker安装方便快捷,可在Windows上使用。自己编译安装,由于每个人环境不同,很容易出问题。本文只介绍基于docker的安装,另外因为我比较穷,所以只介绍cpu版本的安装,不过gpu安装也是大同小异。

基于docker安装milvus CPU版本

简言之安装比较简单,毕竟大佬们已经把milvus部署在了docker里,我们只要启动起来就行了

安装docker

首先就是要安装docker,还不了解docker可以了解一波,非常好用的虚拟机工具,直接去官网下载对应平台的安装文件即可。

下载相应版本镜像

安装好docker后,要去pull对应的镜像(image),首先进到dockerhub官网中,然后搜索milvus,第一个结果就是。因为我们安装的是CPU版本,所以在tags里找cpu-latest,然后pull下来就可以了,即在你的命令行窗口输入

docker pull milvusdb/milvus:cpu-latest注意:随着版本迭代更新,这一条命令在未来可能会失效,建议先去dockerhub搜索一下,去看一下应该用什么tag。

设置工作目录和配置文件

在创建启动容器之前,我们要先设置好工作目录和配置文件。

一共要设置三个目录,分别是数据库存储目录,日志存储目录和配置文件目录。其中配置文件目录就存放着我说的配置文件。配置文件一共有两个,分别是服务器设置文件和日志设置文件。

所以我们要想好这三个文件夹放在哪里,比如我们可以在当前用户目录下建立一个milvus文件夹,然后在这里面存储上述三个目录。下面我们需要设置两个配置文件,记得要把服务器配置文件名改为server_config.yaml,把日志配置文件改为log_config.conf

两个配置文件的内容:服务器配置文件 日志配置文件。配置文件也可以到官网下载

下面是我的文件目录结构,共大家参考:

  milvus

├─conf //配置文件目录
│ log_config.conf //服务器配置文件
│ server_config.yaml //日志配置文件

├─db //数据库存储目录

└─logs //日志存储目录

启动docker服务

设置好工作目录后,就可以使用镜像创建容器了,我的工作目录是C:\Users\Zhdun\milvus,所以我的创建命令是:

docker run -td --name mymilvus -e "TZ=Asia/Shanghai" -p 19530:19530 -p 8080:8080 -v C:\Users\Zhdun\milvus\db:/var/lib/milvus/db -v C:\Users\Zhdun\milvus\conf:/var/lib/milvus/conf -v C:\Users\Zhdun\milvus\logs:/var/lib/milvus/logs milvusdb/milvus:cpu-latest

命令看起来有点长, 我稍微解释下,-td是后台运行,--name是给自己的容器起个名字,-p是端口映射,不想用默认的话,可以去服务器配置文件里改,-v就是为了映射三个工作目录。具体可以参考docker的run命令

执行完命令后,运行docker ps -a,如果发现自己创建的容器excited的了,那就docker logs一下,看出了什么问题。如果发现容器在运行了,就代表基本没问题了。

接下来我会说一下常见的安装问题,以及如何去使用milvus。

安装时的常见问题及解决

Config check fail: Invalid config version: . Expected config version: 0.1 遇到这种问题就在服务器的配置文件第一行加上version: 0.1

Config check fail: Invalid cpu cache capacity: 1. Possible reason: sum of cache_config.cpu_cache_capacity and db_config.insert_buffer_size exceeds system memory.

这种问题就说明内存超出了限制,首先检查服务器配置里的 cpu_cache_capacity 和 insert_buffer_size 是不是过大了。

然后再检查给定docker设定的内存是多少,可以通过docker info来检查。

milvus 基本使用

安装完成后,终于可以开始使用milvus了,milvus支持python,java和c++。在这里我只介绍python的使用。

首先安装 pymilvus库:pip install pymilvus,然后就可以使用这个库来写代码了,接下来我会直接把自己写的范例代码贴上去,其中每一步的具体含义以及可能的扩展我会直接在注释里告诉大家,如有错误还请各位指出。

# -*- coding: utf-8 -*-

#导入相应的包
import numpy as np
from milvus import Milvus, IndexType, MetricType # 初始化一个Milvus类,以后所有的操作都是通过milvus来的
milvus = Milvus() # 连接到服务器,注意端口映射,要和启动docker时设置的端口一致
milvus.connect(host='localhost', port='19530') # 向量个数
num_vec = 5000
# 向量维度
vec_dim = 768 # 创建表
# 参数含义
# table_name: 表名
# dimension: 向量维度
# metric_type: 向量相似度度量标准, MetricType.IP是向量内积; MetricType.L2是欧式距离
table_param = {'table_name': 'mytable', 'dimension':vec_dim, 'index_file_size':1024, 'metric_type':MetricType.IP}
milvus.create_table(table_param) # 随机生成一批向量数据
vectors_array = np.random.rand(num_vec,vec_dim)
vectors_list = vectors_array.tolist() # 官方建议在插入向量之前,建议先使用 milvus.create_index 以便系统自动增量创建索引
# 索引类型有:FLAT / IVFLAT / IVF_SQ8 / IVF_SQ8H,其中FLAT是精确索引,速度慢,但是有100%的召回率
index_param = {'index_type': IndexType.FLAT, 'nlist': 128}
milvus.create_index('mytable', index_param) # 把向量添加到刚才建立的表格中
# ids可以为None,使用自动生成的id
status, ids = milvus.add_vectors(table_name="mytable",records=vectors_list,ids=None) # 返回这一组向量的ID # 官方建议 向量插入结束后,相同的索引需要手动再创建一次
milvus.create_index('mytable', index_param) # 输出一些统计信息
status, tables = milvus.show_tables()
print("所有的表格:",tables)
print("表格的数据量(行):{}".format((milvus.count_table('mytable')[1])))
print("mytable表格是否存在:",milvus.has_table("mytable")[1]) # 加载表格到内存
milvus.preload_table('mytable') # 创建查询向量
query_vec_array = np.random.rand(1,vec_dim)
query_vec_list = query_vec_array.tolist()
# 进行查询, 注意这里的参数nprobe和建立索引时的参数nlist 会因为索引类型不同而影响到查询性能和查询准确率
# 对于 FLAT类型索引,两个参数对结果和速度没有影响
status, results = milvus.search(table_name='mytable', query_records=query_vec_list, top_k=4, nprobe=16)
print(status)
print(results) # 删除表格和索引, 不删除的话,下一次还可以继续使用
milvus.drop_index(table_name="mytable")
milvus.delete_table(table_name="mytable") # 断开连接
milvus.disconnect()

milvus 多进程使用

写这一章的主要目的是为了进行并发测试,以及多进程能否节省时间,官方说明在使用多进程时需要满足下面两个条件:

  • 程序执行时主进程中没有创建 client
  • 每个子进程分别创建 client 进行操作

下面是我的测试代码:

# -*- coding: utf-8 -*-
import time
from multiprocessing import Pool
import numpy as np
import random
from milvus import Milvus, IndexType, MetricType def create_data(host,port,num_vec,vec_dim):
""" 创建一些表格和索引用来做多进程测试 """
milvus = Milvus()
milvus.connect(host=host, port=port)
# 创建2个表
table_param = {'table_name': 'table1', 'dimension':vec_dim, 'index_file_size':1024, 'metric_type':MetricType.IP}
milvus.create_table(table_param)
table_param = {'table_name': 'table2', 'dimension':vec_dim, 'index_file_size':1024, 'metric_type':MetricType.L2}
milvus.create_table(table_param)
# 随机生成一批向量数据
vectors_array = np.random.rand(num_vec,vec_dim)
vectors_list = vectors_array.tolist()
# 创建索引
index_param = {'index_type': IndexType.FLAT, 'nlist': 128}
milvus.create_index('table1', index_param)
milvus.create_index('table2', index_param) # 添加数据
milvus.add_vectors(table_name="table1",records=vectors_list,ids=None)
milvus.add_vectors(table_name="table2",records=vectors_list,ids=None) # 创建索引
milvus.create_index('table1', index_param)
milvus.create_index('table2', index_param)
print(milvus.show_tables())
# 断开连接
milvus.disconnect()
def clear_table(host,port):
""" 清空表格和索引 """
milvus = Milvus()
milvus.connect(host=host, port=port)
for table_name in milvus.show_tables()[1]:
milvus.drop_index(table_name=table_name)
milvus.delete_table(table_name=table_name)
milvus.disconnect()
def milvus_search(host,port,table_name,query_vec,search_time=10):
""" 测试查询, 返回查询的秒数"""
milvus = Milvus()
milvus.connect(host=host, port=port)
# 因为bug的原因,要先搜索一次
milvus.search(table_name,4,8,query_vec)
# 开始测试
for _ in range(search_time):
query_vec[0][0] = random.random() # 稍微随机化一下
milvus.search(table_name, 4, 8, query_vec) if __name__ == "__main__":
host = "localhost"
port = "19530"
num_vec = 100000
vec_dim = 768
num_proc = 3 # 进程数
search_time = 2000 # 搜索次数
####### Step1 先创建用于测试的数据 运行一次就行了
# create_data(host=host,port=port,num_vec=num_vec,vec_dim=vec_dim)
# clear_table(host,port)
# exit(0) ####### Step2 测试依次执行的时间
start_time = time.time()
for _ in range(num_proc):
query_vec = np.random.rand(1,vec_dim).tolist()
milvus_search(host,port,"table1",query_vec,search_time)
end_time = time.time()
print("顺序执行milvus_search的时间总和是:",end_time-start_time) ####### Step3 测试多进程时间
pool = Pool(num_proc)
start_time = time.time()
for _ in range(num_proc):
query_vec = np.random.rand(1,vec_dim).tolist()
pool.apply_async(milvus_search,args=(host,port,"table1",query_vec,search_time))
pool.close()
pool.join()
end_time = time.time()
print("并行执行milvus_search的时间总和是:",end_time-start_time)

结论就是对于search操作,依次search100次,和10个进程同时开,每个进程search10次,开多进程速度是会变快的。

感谢阅读,如有问题,烦请指出。

文章可以随意转载,但请务必注明出处:

milvus安装及其使用教程的更多相关文章

  1. milvus和faiss安装及其使用教程

    写在前面 高性能向量检索库(milvus & faiss)简介 Milvus和Faiss都是高性能向量检索库,可以让你在海量向量库中快速检索到和目标向量最相似的若干个向量,这里相似度量标准可以 ...

  2. CentOS7下自定义目录安装mono+jexus教程

    一.阅读前须知: 1.本文属于安装完Centos7之后的步骤 2.如果还不了解mono,请点击mono 3.本篇主要内容是使用自定义目录安装mono+jexus教程,使用默认目录请查看使用默认目录安装 ...

  3. 【转】真正从零开始,TensorFlow详细安装入门图文教程!(帮你完成那个最难的从0到1)

    AI这个概念好像突然就火起来了,年初大比分战胜李世石的AlphaGo成功的吸引了大量的关注,但其实看看你的手机上的语音助手,相机上的人脸识别,今日头条上帮你自动筛选出来的新闻,还有各大音乐软件的歌曲& ...

  4. CentOS7下默认目录安装mono+jexus教程

    一.阅读前须知: 1.本文属于安装完Centos7之后的步骤 2.如果还不了解mono,请点击mono 3.本篇主要内容是使用默认目录安装mono+jexus教程,使用自定义目录请查看使用自定义目录安 ...

  5. << CocoaPods安装和使用教程 >>github code4app以及cocoachina 苹果官方文档

    developer.apple.com 英文搜索各个技术的官方介绍文档, 前提是英文过关 cocoachina ios最新新闻, 信息 code4app上有许多组件 http://www.code4a ...

  6. webpack安装配置使用教程详解

    webpack安装配置使用教程详解 www.111cn.net 更新:2015-09-01 编辑:swteen 来源:转载 本文章来为各位详细的介绍一下关于webpack安装配置使用教程吧,这篇文章对 ...

  7. NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者

    NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者 作者: raindy 来源:http://bbs.hanzify.org/index.php?showtopic=30029 时间: ...

  8. 安装WordPress详细教程指南

    最近准备自己建一个个人博客,以便分享一些自己工作生活中的一些观点及经验,建博客当然选wordpress,毕竟wordpress是为博客而生的嘛.下边记录一下自己安装WordPress的详细过程指南,亦 ...

  9. 纯windows下制作变色龙引导安装U盘教程

    原创教程:纯windows下制作变色龙引导安装U盘教程 支持Mavericks和Yosemite 支持白苹果 目标:windows下制作带 Chamelon变色龙引导的黑苹果安装U盘,支持PC机引导安 ...

随机推荐

  1. CSP-S 46 题解

    改完题了,就稍写一下题解,顺便反思一下! 其实这次考试挺水的,然而我也挺水的,看了考试结束后的成绩,就吃-*了! T1 set 这个我考试的时候实在是没有想到如何去判断-1,然后我就觉得这神仙题没法解 ...

  2. 『题解』洛谷P2357 守墓人

    Portal Portal1: Luogu Description 在一个荒凉的墓地上有一个令人尊敬的守墓人,他看守的墓地从来没有被盗过, 所以人们很放心的把自己的先人的墓安顿在他那守墓人能看好这片墓 ...

  3. 『题解』UVa11324 The Largest Clique

    原文地址 Problem Portal Portal1:UVa Portal2:Luogu Portal3:Vjudge Description Given a directed graph \(\t ...

  4. CSS尺寸样式属性

    尺寸样式属性介绍 属性 值 含义 height auto:自动,浏览器会自动计算高度length:使用px定义高度%:基于包含它的块级对象的百分比高度 设置元素高度 width 同上 设置元素的宽度 ...

  5. linux 打包 | autoconf 使用方法

    面试题 嵌入式 0x10道题目 宏定义 #define 宏体 宏体 (大写) #define SECOND_OF_YEAR (365*24*3600)UL 可移植性 数据声明 一个存有10个指针的数组 ...

  6. acm经验(转)

    先简单介绍一下自己: 高中在OI打过一段时间酱油,大一后暑假进入ACM集训队,到大三寒假,总共一年半的ACM生涯. 总共参加了四场比赛:区域赛一银(2013长春)一铜(2013杭州)一铁(2012金华 ...

  7. PHP实现开发者模式出现该公众号提供的服务出现故障 请稍后再试解决方法

    PHP实现开发者模式出现该公众号提供的服务出现故障 请稍后再试解决方法 仔细检查下有没有echo等输出的代码  echo没有输出东西 就是报这个信息  所以调试信息都必须写入日记

  8. MQ基本应用场景

    简介 消息队列 MQ 既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积.高吞吐.可靠重试等特性. 应用场景 削峰填谷:诸如秒杀.抢红包.企业开门红等大型活动时皆 ...

  9. mysql里面的时间获取(格式年月日)

    1.当前日期 select DATE_SUB(curdate(),INTERVAL 0 DAY) ; 2.明天日期 select DATE_SUB(curdate(),INTERVAL -1 DAY) ...

  10. Conda/Miniconda/Anaconda 常用命令整理及介绍

    作者:HELO 出处:http://www.cnblogs.com/HELO-K 欢迎转载, 转载时请保留此声明, 谢谢! 在这里整理一份全一点的 Conda 常用命令, 方便大家日常使用时参考, 一 ...