找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

6027

积分

0

好友

771

主题
发表于 前天 21:33 | 查看: 1| 回复: 0

在 2021 年我就接触到了 RediSearch 这个项目,并且已经把它用在了我的开源项目 newbee-mall-pro 中。就实际使用体验来说,简单场景下拿它平替 Elasticsearch 已经足够。比如 Elasticsearch 里常用的中文分词插件,RediSearch 完全可以替代;不过拼音转中文插件目前在 RediSearch 中还没有对应的功能,只能自己想办法处理。

在 newbee-mall-pro 项目中,拼音搜索我是这样实现的:先把中文转成拼音,然后作为拼音字段存入 Redis,再通过 RediSearch 查询拼音字段来完成。

RediSearch 对我来说,相比 Elasticsearch 最大的优势就是 内存占用非常低,查询性能也足够高😂。

在我一台 2 核 4G 的低配服务器上,通过官方提供的 Redis Stack 镜像部署 Redis 及自带模块 RediSearch 后,内存占用还不到 100M。相比之下,部署一个 Elasticsearch 起码要吃掉 1G 内存,所以我更愿意选择 RediSearch。本文的大纲如下:

RediSearch 全文搜索教程大纲思维导图,涵盖简介、Elasticsearch 对比、安装、索引操作、Java 集成

RediSearch 简介

RediSearch 是一个 Redis 模块,为 Redis 提供查询、二级索引和全文搜索能力。要用 RediSearch 的功能,需要先声明一个 index(类似 Elasticsearch 中的索引),之后就可以用 RediSearch 的查询语言来查询该索引下的数据。

RediSearch 内部使用压缩的倒排索引,因此能够以较低的内存占用实现索引的快速构建。目前 RediSearch 最新版支持的查询功能已经相当丰富了:除了基本的文本分词,还支持聚合统计、停用词、同义词、拼写检查、结果排序、标签查询、向量相似度查询以及中文分词等。

对比 Elasticsearch

基本硬件

RediSearch 对比 Elasticsearch 基准测试云实例配置表

数据源

Wikipedia 数据集 wikidump 文档数与大小

RediSearch 配置

RediSearch 索引构建测试分片与文档表大小配置

Elasticsearch 配置

Elasticsearch 索引构建测试分片与 JVM 参数配置

版本

RediSearch 与 Elasticsearch 测试版本信息对比

索引构建测试

在官方提供的索引构建测试中,RediSearch 用了 221 秒就完成了索引构建,而 Elasticsearch 花了 349 秒,领先幅度达到 58%。

RediSearch 与 Elasticsearch 索引构建耗时对比条形图

查询性能测试

数据导入完成后,官方使用运行在专用负载生成器服务器上的 32 个客户端发起两个词的搜索查询。如下图所示,RediSearch 的吞吐量达到了 12.5K ops/sec,而 Elasticsearch 只有 3.1K ops/sec,快了 4 倍。此外,RediSearch 的延迟也稍好一些,平均 8 毫秒,而 Elasticsearch 为 10 毫秒(ops/sec 即每秒操作数)。

RediSearch 与 Elasticsearch 吞吐量和延迟对比柱状图

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

目前 RediSearch 已更新到 2.0+ 版本。根据官方介绍,与 1.6 版本相比,RediSearch 2.0 在吞吐量和延迟相关指标上均提升了 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) "\xe5\xb0\x8f\xe7\xb1\xb3\xe6\x89\x8b\xe6\x9c\xba"
4) "goods:1002"
5) 1) "goodsName"
   2) "\xe5\x8d\x8e\xe4\xb8\xba\xe6\x89\x8b\xe6\x9c\xba"

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 项目,直接选用 Jedis 4.0 以上版本就能使用 RediSearch 提供的搜索功能。Jedis 从 4.0 版本开始自动支持 RediSearch。下面编写 Jedis 连接 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) {
    Map<String, String> hash = 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, Page<SearchPageGoodsVO> page) {
    // 查询关键字
    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 作为 newbee-mall-pro 项目的全文搜索引擎已经完全够用了。它有不少优点:易于安装、索引占用内存低、查询速度快。但有一点需要说明:在对 Redis 集群的支持上,RediSearch 目前只针对 Redis 企业版有解决方案,开源版还没有。所以如果想要在生产环境中大规模使用,我个人还是持保留态度的。

本文中使用的 Jedis 操作 RediSearch 的相关代码,都在 newbee-mall-pro 项目的 JedisSearchTest 类中有体现。

newbee-mall-pro : https://github.com/wayn111/newbee-mall-pro

如果你对 Redis、Elasticsearch 这类中间件的实战经验感兴趣,也可以到 云栈社区 逛逛,上面有不少开发者分享的相关踩坑记录与性能调优思路。




上一篇:AI Agent科研加速怎么测?OpenAI公开用量任务结果三层法
下一篇:RediSearch 全文搜索实战:创建索引并关联 Redis 源数据详解
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-9-13 17:38 , Processed in 0.732071 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表