换掉ES!Redis官方搜索引擎来了,性能炸裂!
1、介绍
RediSearch是一个Redis模块,为Redis提供查询、二次索引和全文搜索。要使用RediSearch,首先要在Redis数据上声明索引。然后可以使用重新搜索查询语言来查询该数据。RedSearch使用压缩的反向索引进行快速索引,占用内存少。RedSearch索引通过提供精确的短语匹配、模糊搜索和数字过滤等功能增强了
2、实现特性
基于文档的多个字段全文索引
高性能增量索引
文档排序(由用户在索引时手动提供)
在子查询之间使用 AND 或 NOT 操作符的复杂布尔查询
可选的查询子句
基于前缀的搜索
支持字段权重设置
自动完成建议(带有模糊前缀建议)
精确的短语搜索
在许多语言中基于词干分析的查询扩展
支持用于查询扩展和评分的自定义函数
将搜索限制到特定的文档字段
数字过滤器和范围
使用 Redis 自己的地理命令进行地理过滤
Unicode 支持(需要 UTF-8 字符集)
检索完整的文档内容或只是 ID 的检索
支持文档删除和更新与索引垃圾收集
支持部分更新和条件文档更新
对比 Elasticsearch
如下图所示,RediSearch 构建索引的时间为 221 秒,而 Elasticsearch 为 349 秒,快了 58%。
索引构建测试
我们模拟了一个多租户电子商务应用程序,其中每个租户代表一个产品类别并维护自己的索引。对于此基准测试,我们构建了 50K 个索引(或产品),每个索引最多存储 500 个文档(或项目),总共 2500 万个文档。RediSearch 仅用了 201 秒就构建了索引,平均每秒运行 125K 个索引。然而,Elasticsearch 在 921 个索引后崩溃了,显然它不是为应对这种负载而设计的。
查询性能测试
一旦数据集被索引,我们就使用在专用负载生成器服务器上运行的 32 个客户端启动两个单词的搜索查询。如下图所示,RediSearch 吞吐量达到了 12.5K 操作/秒,而 Elasticsearch 为 3.1K 操作/秒,速度提高了 4 倍。此外,RediSearch 延迟稍好一些,平均为 8 毫秒,而 Elasticsearch 为 10 毫秒。
3、安装
3.1 源码安装
git clone https://github.com/RediSearch/RediSearch.git |
3.2 docker安装
note: RediSearch的安装比较复杂原包无法进行编译操作所以我们使用docker安装
docker run -p 6379:6379 redislabs/redisearch:latest |
3.3 判断是否安装成功
127.0.0.1:0>module list |
返回数组存在“ft”或 “search”(不同版本),表明 RediSearch 模块已经成功加载。
命令行操作
1、创建
1.1 创建索引
创建索引不妨想象成创建表结构,表一般基本属性有表名、字段和字段类别等,所以我们可以考虑将索引名代表表名,字段代表字段,属性即表示属性。
123.232.112.84:0>ft.create "student" schema "name" text weight 5.0 "sex" text "desc" text "class" tag |
student 表示索引名,name、sex、desc表示字段,text表示类型(这样表示只是为了便于理解)
“weight”为权重,默认值为 1.0
插播一条,如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 1万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术栈五百套套,精品系列教程,免费提供。
type student |
我们创建的索引redis是不认识的,这证明使用的是插件。
1.2 创建文档
创建文档上下文的过程不妨想想成向表中插入数据,这里请注意字段名可以使用双引号但切记一定要用英文,这里之所以着重提出是因为有些编译器中文双引号和英文双引号用肉眼实在难以辨认否则会出现
“Fields must be specified in FIELD VALUE pairs”(其实是将“ 当作内容处理了以至于缺少了字段)
123.232.112.84:0>ft.add student 001 1.0 language "chinese" fields name "张三" sex "男" desc "这是一个学生" class "一班" |
其中001为文档ID,”1.0”为评分缺少此值会报”Could not parse document score”异常
language 指明使用的语言默认是英文编码 如果没有此标记存储是没有问题的但不可以通过中文字符查询
1.3 查询
1.3.1 基本查询
1.3.1.1 全量查询
123.232.112.84:0>FT.SEARCH student * SORTBY sex desc RETURN 3 name sex desc |
1.3.1.2 匹配查询
123.232.112.84:0>ft.search student "张三" limit 0 10 RETURN 3 name sex desc |
limit 与mysql相识主要用于分页,此处是全量匹配,如果没有设置language “chinese” 此处查询为0,
1.3.2 模糊匹配
1.3.2.1 后置匹配
ft.search student "李*" SORTBY sex desc RETURN 3 name sex desc |
1.3.2.2 模糊搜索
123.232.112.84:0>FT.SEARCH beers "%%张店%%" |
别高兴太早全量模糊匹配是由很大限制的,他基于Levenshtein距离(LD)进行模糊匹配。术语的模糊匹配是通过在术语周围加“%”来实现的,模糊匹配的最大LD为3,
确切的说这只是一种相识度查询,并非一般意义上的模糊搜索,
但是:如果仔细观察会发现通过精确匹配时不仅能够将完整value值查询出来而且还查询出其他处于文档某个位置的key请看官方提供的一个例子:
FT.CREATE idx SCHEMA txt TEXT |
之所以会出现这样的效果是因为redisearch对文本进行了分词,其使用的工具是friso相比es的ik还是弱一些前者主要是对中文分词,体积小可移植性强。
从而我们可以结合后后置匹配算法
插播一条,如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 1万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术栈五百套套,精品系列教程,免费提供。
123.232.112.84:0>FT.SEARCH idx "数*" LANGUAGE chinese HIGHLIGHT |
或者结合Levenshtein算法这样基本上能够满足业务查询需求
123.232.112.84:0>FT.SEARCH idx "%%单的树%%" LANGUAGE chinese HIGHLIGHT |
1.3.2.3 字段查询
通过字段查询也可以实现模糊搜索,直接给例子,后面跟着官网上给的sql 和 redisearch的对照表
ft.search student * |
sql | redisearch |
---|---|
WHERE x=‘foo’ AND y=‘bar’ | @x:foo @y:bar |
WHERE x=‘foo’ AND y!=‘bar’ | @x:foo -@y:bar |
WHERE x=‘foo’ OR y=‘bar’ | (@x:foo) |
WHERE x IN (‘foo’, ‘bar’,‘hello world’) | @x:(foo |
WHERE y=‘foo’ AND x NOT IN (‘foo’,‘bar’) | @y:foo (-@x:foo) (-@x:bar) |
WHERE x NOT IN (‘foo’,‘bar’) | -@x:(foo |
WHERE num BETWEEN 10 AND 20 | @num:[10 20] |
WHERE num >= 10 | @num:[10 +inf] |
WHERE num > 10 | @num:[(10 +inf] |
WHERE num < 10 | @num:[-inf (10] |
WHERE num <= 10 | @num:[-inf 10] |
WHERE num < 10 OR num > 20 | @num:[-inf (10] |
WHERE name LIKE ‘john%’ | @name:john* |
1.4 删除
1.3.1 删除文档
123.232.112.84:0>ft.del student 002 |
1.3.3 删除索引
123.232.112.84:0>ft.drop student |
1.5 查看
1.5.1 查看所有索引
123.232.112.84:0>FT._LIST |
1.5.2 查看索引文档中的数据
1.5.2.1 获取单条数据
123.232.112.84:0>ft.get student 001 |
1.5.2.2 获取多条数据
123.232.112.84:0>ft.mget student 001 002 |
1.6 索引别名操作
1.6.1 添加别名
123.232.112.84:0>FT.ALIASADD xs student |
给索引student起个xs的别名,一个索引可以起多个别名
1.6.2 修改别名
1.6.3 删除别名
123.232.112.84:0>FT.ALIASDEL xs
"OK"