电子说
RediSearch 简介
RediSearch 是一个 Redis 模块,为 Redis 提供查询、二级索引和全文搜索功能。
要使用 RediSearch 的功能,我们需要要先声明一个 index(类似于 Elasticsearch 的索引)。然后就可以使用 RediSearch 的查询语言来查询该索引下的数据。
RediSearch 内部使用压缩的倒排索引,所以可以用较低的内存占用来实现索引的快速构建。
目前 RediSearch 最新版支持的查询功能也比较丰富了,除了基本的文本分词还支持聚合统计、停用词、同义词、拼写检查、结果排序、标签查询、向量相似度查询以及中文分词等。
对比 Elasticsearch
基本硬件
数据源
RediSearch 配置
Elasticsearch 配置
版本
索引构建测试
在官方提供的索引构建测试中,RediSearch 用 221 秒的速度超过了 Elasticsearch 的 349 秒,领先 58%,
查询性能测试
通过数据集导入索引数据后,官方使用运行在专用负载生成器服务器上的 32 个客户端启动了两个词的搜索查询。
如下图所示,RediSearch 的吞吐量达到了 12.5K ops/sec,而 Elasticsearch 的吞吐量只有了 3.1K ops/sec,快了 4 倍。此外 RediSearch 的延迟稍好一些,平均为 8 毫秒,而 Elasticsearch 为 10 毫秒。(ops/sec 每秒操作数)
由此可见,RediSearch 在性能上对比 RediSearch 有比较大的优势。
目前 RediSearch 已经更新到 2.0+ 版本,根据官方对于 RediSearch 2.0 版本介绍,与 RediSearch 1.6 相比,吞吐量和延迟相关的指标都提高了 2.4 倍。
RediSearch 安装
对于目前最新的 RediSearch 2.0 版本来说,官方推荐直接使用 redis-stack-server 镜像进行进行部署,也比较简单,
docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest
设置登录密码
// 设置登录密码 docker run -e REDIS_ARGS="--requirepass redis-stack" redis/redis-stack:latest
通过 redis-cli 连接查看 RediSearch 是否安装了 search 模块,
redis-cli -h localhost > MODULE list ... 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.CREATE idx:goods on hash prefix 1 "goods:" language chinese schema goodsName text sortable "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:" 的源数据。如下,
hset goods:1001 goodsName 小米手机 hset goods:1002 goodsName 华为手机
FT.SEARCH 查询索引
> FT.SEARCH idx:goods1 "手机" 1) "2" 2) "goods:1001" 3) 1) "goodsName" 2) "xe5xb0x8fxe7xb1xb3xe6x89x8bxe6x9cxba" 4) "goods:1002" 5) 1) "goodsName" 2) "xe5x8dx8exe4xb8xbaxe6x89x8bxe6x9cxba"
FT.INFO 查询指定名称索引信息
> FT.INFO idx:goods 1) "index_name" 2) "idx:goods1" 3) "index_options" 4) (empty list or set) 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.DROPINDEX idx:goods1 "OK"
FT.DROPINDEX 删除指定名称索引,不会删除 hash 类型的源数据
如果需要删除索引数据,直接使用 del 命令删除索引关联的源数据即可。
Java 使用 RediSearch
对于 Java 项目直接选用 Jedis4.0 以上版本就可以使用 RediSearch 提供的搜索功能,Jedis 在 4.0 以上版本自动支持 RediSearch,编写 Jedis 连接 RedisSearch 测试用例,用 RedisSearch 命令创建如下,
Jedis 创建 RediSearch 客户端
@Bean public UnifiedJedis unifiedJedis(GenericObjectPoolConfig jedisPoolConfig) { UnifiedJedis client; if (StringUtils.isNotEmpty(password)) { client = new JedisPooled(jedisPoolConfig, host, port, timeout, password, database); } else { client = new JedisPooled(jedisPoolConfig, host, port, timeout, null, database); } return client; }
Jedis 创建索引
Schema schema = new Schema() .addSortableTextField("goodsName", 1.0) .addSortableTagField("tag", "|"); IndexDefinition rule = new IndexDefinition(IndexDefinition.Type.HASH) .setPrefixes("idx:goods") .setLanguage("chinese"); # 设置支持中文分词 client.ftCreate(idxName, IndexOptions.defaultOptions().setDefinition(rule), schema);
Jedis 添加索引源数据
public boolean addGoodsIndex(String keyPrefix, Goods goods) { Maphash = MyBeanUtil.toMap(goods); hash.put("_language", "chinese"); client.hset("idx:goods" + goods.getGoodsId(), MyBeanUtil.toMap(goods)); return true; }
Jedis 中文查询
public SearchResult search(String goodsIdxName, SearchObjVO searchObjVO, Pagepage) { // 查询关键字 String keyword = searchObjVO.getKeyword(); String queryKey = String.format("@goodsName:(%s)", keyword); Query q = new Query(queryKey); String sort = searchObjVO.getSidx(); String order = 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()); // 返回查询结果 return client.ftSearch(goodsIdxName, q); }
最后聊两句
RediSearch 是这几年新出的一个全文搜索引擎,借助于 Redis 的成功,RediSearch 一出场就获得了较高的关注度。
目前来看,我个人使用 RediSearch 作为项目的全文搜索引擎已经够用了,它有易于安装、索引占用内存低、查询速度快等许多优点。不过在对 Redis 集群的支持上,RediSearch 目前只针对 Redis 企业版有解决方案,开源版还没有,这一点需要告诉大家。
如果想要在生产环境大规模使用,我还是不太建议的。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !