TairSearch是Tair全自研的全文檢索搜尋資料結構,採用和Elasticsearch相似的查詢文法。本文介紹如何在TairSearch中使用TFT.MSEARCH命令,實現索引分區查詢。
背景資訊
在TairSearch資料結構中,Key為路由的最小單位。一個Key通常對應一個Schema(中繼資料,由mappings和settings組成),若單個Key添加了過多文檔,則會使該Key成為大Key(BigKey),嚴重時會因該Key佔用的記憶體超過單節點的記憶體限制而導致記憶體溢出(Out Of Memory)。
當單節點架構的快取服務的記憶體容量受限時,通常採用如下方法進行擴容:
將單節點架構執行個體變更配置為叢集架構執行個體。
將大Key拆分成多個小Key,並分散到叢集架構執行個體的各個分區中。
TairSearch根據該原理實現了大Key的記憶體搜尋方案:預先將大Key拆分成小Key,設計負載規則將資料寫入不同的Key中,並通過TFT.MSEARCH對該類Key進行查詢。建立該類Key時,必須使該類Key具備相同的Schema配置。更多關於TairSearch的資訊,請參見Search。
推薦在叢集架構(代理模式)或讀寫分離架構下使用Msearch功能,結合TairProxy組件可提升巨量資料情境下的查詢效能。標準架構與叢集架構直連模式也能使用Msearch功能,但由於其架構沒有TairProxy組件,無法發揮該功能的特點,不推薦使用。
Msearch原理
TairSearch提供的TFT.SEARCH命令支援查詢單個Key,提供的TFT.MSEARCH命令支援對Schema配置相同的多個Key進行查詢。
當用戶端發送寫請求給TairProxy後,TairProxy會根據Slot將Key寫入對應的資料分區節點中。
Msearch功能要求多個Key的Schema配置必須相同,且拆分多Key的邏輯由您進行決策,您需要瞭解並控制拆分Key的索引分區規則。
當用戶端發送讀請求(TFT.MSEARCH)給TairProxy後,TairProxy會將請求分發給各個對應的資料分區節點,資料分區節點會完成各個Key的查詢與首次匯總,並將結果集返回給TairProxy,此時,TairProxy會對所有結果集進行二次打分、排序、彙總並返回最終的結果集給用戶端。
Msearch分頁
由於涉及到深度搜尋,可能會返回大量結果集,因此,您可以使用分頁功能分批擷取結果集。
分頁原理
TFT.MSEARCH的分頁功能不同於TFT.SEARCH提供的from和size組合,是通過指定查詢返回的文檔總數量(size)和返回各Key下一輪查詢的遊標資訊(keys_cursor)實現多個Key的分頁查詢。
TFT.MSEARCH的分頁實現過程如下:
在您指定了size後,TFT.MSEARCH命令會對每個Key擷取size個結果集。
Tair會對匯總結果進行二次打分、排序、彙總,最終返回size個結果集,並返回各個Key下一輪查詢的keys_cursor(您需指定
reply_with_keys_cursor
參數為true
)。說明keys_cursor預設為0,表示第一位。
在下次查詢時,可指定上述返回的keys_cursor資訊,Tair將會從各Key指定的位置之後擷取size個結果集,並重複上述步驟。
分頁樣本
例如設定size為10,查詢3個Key(key0
、key1
、key2
)。
Tair會對key0
、key1
、key2
分別擷取10個結果集(此時共有30個候選文檔),對匯總結果進行二次打分、排序、彙總,輸出整體排名靠前的10個結果集,返回的keys_cursor樣本為{"keys_cursor":{"key0":2,"key1":5,"key2":3}}
,表示當前10個結果集的組成為:key0
的前2個、key1
的前5個和key2
的前3個。在下次查詢時指定{"keys_cursor":{"key0":2,"key1":5,"key2":3}}
,Tair將從key0
的第3位開始向後擷取10個文檔,key1
與key2
也類似。
操作範例
本樣本以類比熱點資訊搜尋進行Msearch實踐介紹。
假設每天會產生100萬條熱點資訊,可以設計1個Key儲存一周的熱點資訊,則每個Key預計儲存700萬個文檔數。
假設類比情境為保留2周的熱點資訊,新周期的資訊可以建立Key,達到到期時間則刪除Key。
每條熱點資訊具有時間屬性(datetime)、作者(author)、作者ID(uid)以及資訊內容(content)。
建立索引。
# 建立2個Key,每個Key以“FLOW_年月開始日_結束日”為命名規則,需確保不同Key具有相同的Schema配置。 TFT.CREATEINDEX FLOW_20230109_15 '{ "mappings":{ "properties":{ "datetime":{ "type":"long" }, "author":{ "type":"text" }, "uid":{ "type":"long" }, "content":{ "type":"text", "analyzer": "jieba" } } } }' TFT.CREATEINDEX FLOW_20230116_23 '{ "mappings":{ "properties":{ "datetime":{ "type":"long" }, "author":{ "type":"text" }, "uid":{ "type":"long" }, "content":{ "type":"text", "analyzer": "jieba" } } } }'
添加文檔資料。
# 此處分別向每周的Key寫入一條資料為例。 TFT.ADDDOC FLOW_20230109_15 '{ "datetime":20230109001209340, "author":"熱點影視", "uid":7884455, "content":"電影在大年初一就要與觀眾見面了" }' TFT.ADDDOC FLOW_20230116_23 '{ "datetime":20230118011304250, "author":"熱點時尚", "uid":100093, "content":"推出品牌2023兔年生肖系列新品" }'
查詢樣本。
搜尋2周以來“生肖兔”相關的熱點資訊,結果集按時間排序。
TFT.MSEARCH 2 FLOW_20230109_15 FLOW_20230116_23 '{ "query":{ "match":{ "content":"生肖兔" } }, "sort" : [ { "datetime": { "order" : "desc" } } ], "size":10, "reply_with_keys_cursor":true, "keys_cursor":{ "FLOW_2023010916":0, "FLOW_202301623":0 } }'
預計輸出:
{ "hits":{ "hits":[ { "_id":"20230118011304250", "_index":"FLOW_20230116_23", "_score":1, "_source":{ "datetime":20230118011304250, "author":"熱點時尚", "uid":100093, "content":"推出品牌2023兔年生肖系列新品" } } ], "max_score":1, "total":{ "relation":"eq", "value":1 } }, "aux_info":{ "index_crc64":14159192555612760957, "keys_cursor":{ "FLOW_20230109_15":0, "FLOW_20230116_23":1 } } }