TairSearch是Tair自主研发的高性能、低延时、基于内存的实时搜索引擎。在Tair中以key作为最小粒度的路由数据单位,TairSearch一个key对应的是搜索中的一个schema。如果一个schema中的文档数过多,则会导致在Tair中存在一个超大key,当文档数占用的总内存超过单节点的内存限制时,业务会出现oom等错误告警。众所周知,当缓存服务的单节点内存容量受限时,可通过变配成集群实例做扩容,前提是需要将大key打散成多个小key分散到集群实例的各个分片中。TairSearch同样也运用了该原理去实现大key的内存搜索,本文将介绍如何使用TairSearch中的msearch API 实现索引分片搜索。
msearch原理
TairSearch使用tft.search API 提供对单个key的查询功能,顾名思义,tft.msearch API则是提供对多个key的查询功能。msearch API需要与核心组件TairProxy联合使用。业务客户端将请求发送给TairProxy后,TairProxy按key将请求拆分到对应的节点分片上,收到分片回复包后,将结果进行汇聚整合,最终回复给业务客户端。
msearch要求多个key的schema配置必须一致,且拆分多key的逻辑由业务决策。业务层需要感知且控制拆分key的索引分片规则。
msearch分页
涉及到深度搜索返回大量结果文档集,需要使用分页的功能将结果集分批次拉取。msearch也提供了一套分页功能。不同于tft.search使用from
+ size
的API做分页,msearch通过返回每个key的分页游标实现多个key的分页查询。
msearch分页的原理是取多个key的满足size需求的文档集,对子文档集合重新按照score
或者指定的sort
排序后,返回top size的最终文档集合,而不是返回每个子key的文档集合。
msearch查询时query语句配置参数reply_with_keys_cursor
为true,表示需要返回的结果中带有分页游标信息,返回结果中携带有keys_cursor
的信息,表示下一次请求每个key的开始游标,业务层下次请求时带上这个游标数据,结合size
参数,则可以实现分页功能。第一次请求时可配置keys_cursor
的初始游标为0或者不配置。
msearch实践
本小节通过模拟内容类的信息流搜索来演示msearch的实践。
每一条产生内容的信息流有时间属性,以毫米时间戳作为唯一文档ID标志,按照文档ID的range作为索引分片的规则。假设每天产生1百万条信息流,以一周作为一个key,每个key承担7百万个文档数目,按照热点信息保留的周数去配置key,过期的信息流可以直接删除,新周期的信息流可以新建key。
假设模拟的场景是保留2周的信息流,一次创建2个key,每个key按照年
月
开始日
结束日
作为命名规则, 且具有相同的字段:
- datetime:信息流创建的时间
- author:作者名称
- uid:作者唯一标志
- content:信息流内容
创建2个key:
redis-cli tft.createindex FLOW_2023010916 '{
"mappings":{
"properties":{
"datetime":{
"type":"long"
},
"author":{
"type":"text"
},
"uid":{
"type":"long"
},
"content":{
"type":"text",
"analyzer": "jieba"
}
}
}
}'
redis-cli tft.createindex FLOW_202301623 '{
"mappings":{
"properties":{
"datetime":{
"type":"long"
},
"author":{
"type":"text"
},
"uid":{
"type":"long"
},
"content":{
"type":"text",
"analyzer": "jieba"
}
}
}
}'
以datetime作为文档ID写入:
redis-cli tft.adddoc FLOW_2023010916 '{
"datetime":20230109001209340,
"author":"热点影视",
"uid":7884455,
"content":"电影《无名》在大年初一就要与观众见面了"
}' with_id 20230109001209340
redis-cli tft.adddoc FLOW_202301623 '{
"datetime":20230118011304250,
"author":"全球时尚咨询",
"uid":100093,
"content":"自由兔,推出品牌2023兔年生肖系列新品"
}' with_id 20230118011304250
搜索2周以来跟生肖兔有关的信息流,结果集按时间排序:
redis-cli tft.msearch 2 FLOW_2023010916 FLOW_202301623 '{
"query":{
"match":{
"content":"生肖兔"
}
},
"sort" : [
{ "datetime": { "order" : "desc" } }
],
"size":10,
"reply_with_keys_cursor":true,
"keys_cursor":{
"FLOW_2023010916":0,
"FLOW_202301623":0
}
}'