全部產品
Search
文件中心

ApsaraDB for Redis:在TairSearch中使用Msearch實現索引分區搜尋

更新時間:Jul 27, 2024

TairSearch是Tair全自研的全文檢索搜尋資料結構,採用和Elasticsearch相似的查詢文法。本文介紹如何在TairSearch中使用TFT.MSEARCH命令,實現索引分區查詢。

背景資訊

在TairSearch資料結構中,Key為路由的最小單位。一個Key通常對應一個Schema(中繼資料,由mappingssettings組成),若單個Key添加了過多文檔,則會使該Key成為大Key(BigKey),嚴重時會因該Key佔用的記憶體超過單節點的記憶體限制而導致記憶體溢出(Out Of Memory)。

當單節點架構的快取服務的記憶體容量受限時,通常採用如下方法進行擴容:

  1. 將單節點架構執行個體變更配置為叢集架構執行個體。

  2. 將大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的索引分區規則。

圖 1. TairSearch資料在TairProxy架構的寫入流程TairProxy資料寫入流程

當用戶端發送讀請求(TFT.MSEARCH)給TairProxy後,TairProxy會將請求分發給各個對應的資料分區節點,資料分區節點會完成各個Key的查詢與首次匯總,並將結果集返回給TairProxy,此時,TairProxy會對所有結果集進行二次打分、排序、彙總並返回最終的結果集給用戶端。

圖 2. TairSearch資料在TairProxy架構的讀取(TFT.MSEARCH)流程Msearch讀取

Msearch分頁

由於涉及到深度搜尋,可能會返回大量結果集,因此,您可以使用分頁功能分批擷取結果集。

分頁原理

TFT.MSEARCH的分頁功能不同於TFT.SEARCH提供的fromsize組合,是通過指定查詢返回的文檔總數量(size)和返回各Key下一輪查詢的遊標資訊(keys_cursor)實現多個Key的分頁查詢。

TFT.MSEARCH的分頁實現過程如下:

  1. 在您指定了size後,TFT.MSEARCH命令會對每個Key擷取size個結果集。

  2. Tair會對匯總結果進行二次打分、排序、彙總,最終返回size個結果集,並返回各個Key下一輪查詢的keys_cursor(您需指定reply_with_keys_cursor參數為true)。

    說明

    keys_cursor預設為0,表示第一位。

  3. 在下次查詢時,可指定上述返回的keys_cursor資訊,Tair將會從各Key指定的位置之後擷取size個結果集,並重複上述步驟。

分頁樣本

例如設定size為10,查詢3個Key(key0key1key2)。

Tair會對key0key1key2分別擷取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個文檔,key1key2也類似。

操作範例

本樣本以類比熱點資訊搜尋進行Msearch實踐介紹。

  • 假設每天會產生100萬條熱點資訊,可以設計1個Key儲存一周的熱點資訊,則每個Key預計儲存700萬個文檔數。

  • 假設類比情境為保留2周的熱點資訊,新周期的資訊可以建立Key,達到到期時間則刪除Key。

  • 每條熱點資訊具有時間屬性(datetime)、作者(author)、作者ID(uid)以及資訊內容(content)。

  1. 建立索引。

    # 建立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"
                }
            }
        }
    }'
  2. 添加文檔資料。

    # 此處分別向每周的Key寫入一條資料為例。
    
    TFT.ADDDOC FLOW_20230109_15 '{
        "datetime":20230109001209340,
        "author":"熱點影視",
        "uid":7884455,
        "content":"電影在大年初一就要與觀眾見面了"
    }'
    
    TFT.ADDDOC FLOW_20230116_23 '{
        "datetime":20230118011304250,
        "author":"熱點時尚",
        "uid":100093,
        "content":"推出品牌2023兔年生肖系列新品"
    }'
  3. 查詢樣本。

    搜尋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
            }
        }
    }