五侯蜡烛网

RediSearch 简介RediSearch 是一个 Redis 模块,为 Redis 提供查询、二级索引和全文搜索功能。要使用 RediSearch 的功能,我们需要要先声明一个 index类似于

Redis官方搜索引擎来了,性能炸裂!

RediSearch 简介

RediSearch 是索引一个 Redis 模块,为 Redis 提供查询、擎性二级索引和全文搜索功能。索引

要使用 RediSearch 的擎性功能,我们需要要先声明一个 index(类似于 Elasticsearch 的索引索引)。然后就可以使用 RediSearch 的擎性查询语言来查询该索引下的数据。

RediSearch 内部使用压缩的索引倒排索引,所以可以用较低的擎性内存占用来实现索引的快速构建。

目前 RediSearch 最新版支持的索引查询功能也比较丰富了,除了基本的擎性文本分词还支持聚合统计、停用词、索引同义词、擎性拼写检查、索引结果排序、擎性标签查询、索引向量相似度查询以及中文分词等。

对比 Elasticsearch

基本硬件

f591b788-d059-11ee-a297-92fbcf53809c.png

数据源

f597dbd6-d059-11ee-a297-92fbcf53809c.png

RediSearch 配置

f59d903a-d059-11ee-a297-92fbcf53809c.png

Elasticsearch 配置

f5a6d76c-d059-11ee-a297-92fbcf53809c.png

版本

f5af12c4-d059-11ee-a297-92fbcf53809c.png

索引构建测试

在官方提供的索引构建测试中,RediSearch 用 221 秒的速度超过了 Elasticsearch 的 349 秒,领先 58%,

f5b4db00-d059-11ee-a297-92fbcf53809c.png

查询性能测试

通过数据集导入索引数据后,官方使用运行在专用负载生成器服务器上的 32 个客户端启动了两个词的搜索查询。

如下图所示,RediSearch 的吞吐量达到了 12.5K ops/sec,而 Elasticsearch 的吞吐量只有了 3.1K ops/sec,快了 4 倍。此外 RediSearch 的延迟稍好一些,平均为 8 毫秒,而 Elasticsearch 为 10 毫秒。(ops/sec 每秒操作数)

f5c08bc6-d059-11ee-a297-92fbcf53809c.png

由此可见,RediSearch 在性能上对比 RediSearch 有比较大的优势。

目前 RediSearch 已经更新到 2.0+ 版本,根据官方对于 RediSearch 2.0 版本介绍,与 RediSearch 1.6 相比,吞吐量和延迟相关的指标都提高了 2.4 倍。

RediSearch 安装

对于目前最新的 RediSearch 2.0 版本来说,官方推荐直接使用 redis-stack-server 镜像进行进行部署,也比较简单,

dockerrun-d--nameredis-stack-server-p6379:6379redis/redis-stack-server:latest

设置登录密码

//设置登录密码dockerrun-eREDIS_ARGS="--requirepassredis-stack"redis/redis-stack:latest

通过 redis-cli 连接查看 RediSearch 是否安装了 search 模块,

redis-cli-hlocalhost>MODULElist...3)1)"name"2)"search"3)"ver"4)"20809"5)"path"6)"/opt/redis-stack/lib/redisearch.so"7)"args"8)1)"MAXSEARCHRESULTS"2)"10000"3)"MAXAGGREGATERESULTS"4)"10000"...

索引操作

FT.CREATE 创建索引命令

>FT.CREATEidx:goodsonhashprefix1"goods:"languagechineseschemagoodsNametextsortable"OK"

FT.CREATE:创建索引命令

idx:goods:索引名称

on hash:索引关联的数据类型,这里指定索引基于 hash 类型的源数据构建

prefix 1 "goods:":表示索引关联的 hash 类型源数据前缀是 goods:

language chinese:表示支持中文语言分词

schema goodsName text sortable:表示字段定义,goodsName 表示元数据属性名,text 表示字段类型 sortable 表示该字段可以用于排序

添加索引时,直接使用 hset 命令添加一个 key 前缀是 "goods:" 的源数据。如下,

hsetgoods:1001goodsName小米手机hsetgoods:1002goodsName华为手机

FT.SEARCH 查询索引

>FT.SEARCHidx:goods1"手机"1)"2"2)"goods:1001"3)1)"goodsName"2)"xe5xb0x8fxe7xb1xb3xe6x89x8bxe6x9cxba"4)"goods:1002"5)1)"goodsName"2)"xe5x8dx8exe4xb8xbaxe6x89x8bxe6x9cxba"

FT.INFO 查询指定名称索引信息

>FT.INFOidx:goods1)"index_name"2)"idx:goods1"3)"index_options"4)(emptylistorset)5)"index_definition"6)1)"key_type"2)"HASH"3)"prefixes"4)1)"goods:"5)"default_language"6)"chinese"7)"default_score"8)"1"7)"attributes"8)1)1)"identifier"2)"goodsName"3)"attribute"4)"goodsName"5)"type"6)"TEXT"7)"WEIGHT"8)"1"9)"SORTABLE"...

FT.INFO 查询指定名称的索引信息

FT.DROPINDEX 删除索引名称

>FT.DROPINDEXidx:goods1"OK"

FT.DROPINDEX 删除指定名称索引,不会删除 hash 类型的源数据

如果需要删除索引数据,直接使用 del 命令删除索引关联的源数据即可。

Java使用 RediSearch

对于 Java 项目直接选用 Jedis4.0 以上版本就可以使用 RediSearch 提供的搜索功能,Jedis 在 4.0 以上版本自动支持 RediSearch,编写 Jedis 连接 RedisSearch 测试用例,用 RedisSearch 命令创建如下,

Jedis 创建 RediSearch 客户端

@BeanpublicUnifiedJedisunifiedJedis(GenericObjectPoolConfigjedisPoolConfig){ UnifiedJedisclient;if(StringUtils.isNotEmpty(password)){ client=newJedisPooled(jedisPoolConfig,host,port,timeout,password,database);}else{ client=newJedisPooled(jedisPoolConfig,host,port,timeout,null,database);}returnclient;}

Jedis 创建索引

Schemaschema=newSchema().addSortableTextField("goodsName",1.0).addSortableTagField("tag","|");IndexDefinitionrule=newIndexDefinition(IndexDefinition.Type.HASH).setPrefixes("idx:goods").setLanguage("chinese");#设置支持中文分词client.ftCreate(idxName,IndexOptions.defaultOptions().setDefinition(rule),schema);

Jedis 添加索引源数据

publicbooleanaddGoodsIndex(StringkeyPrefix,Goodsgoods){ Maphash=MyBeanUtil.toMap(goods);hash.put("_language","chinese");client.hset("idx:goods"+goods.getGoodsId(),MyBeanUtil.toMap(goods));returntrue;}

Jedis 中文查询

publicSearchResultsearch(StringgoodsIdxName,SearchObjVOsearchObjVO,Pagepage){ //查询关键字Stringkeyword=searchObjVO.getKeyword();StringqueryKey=String.format("@goodsName:(%s)",keyword);Queryq=newQuery(queryKey);Stringsort=searchObjVO.getSidx();Stringorder=searchObjVO.getOrder();//查询是否排序if(StringUtils.isNotBlank(sort)){ q.setSortBy(sort,Constants.SORT_ASC.equals(order));}//设置中文分词查询q.setLanguage("chinese");//设置分页q.limit((int)page.offset(),(int)page.getSize());//返回查询结果returnclient.ftSearch(goodsIdxName,q);}

最后聊两句

RediSearch 是这几年新出的一个全文搜索引擎,借助于 Redis 的成功,RediSearch 一出场就获得了较高的关注度。

目前来看,我个人使用 RediSearch 作为项目的全文搜索引擎已经够用了,它有易于安装、索引占用内存低、查询速度快等许多优点。不过在对 Redis 集群的支持上,RediSearch 目前只针对 Redis 企业版有解决方案,开源版还没有,这一点需要告诉大家。

如果想要在生产环境大规模使用,我还是不太建议的。





审核编辑:刘清

访客,请您发表评论:

网站分类
热门文章
友情链接

© 2025. sitemap