Elasticsearch(ES)是一款基於Lucene的開源分佈式搜索引擎。因爲其穩定、可靠、快速、安裝使用方便等優良特性,目前在業界已普遍使用。ES用途主要分兩個方向:分佈式實時文件存儲 以及 分佈式實時分析搜索引擎。json
1、爲何須要查詢代理緩存
屏蔽複雜的DSL分佈式
某二手交易平臺使用ES,主要用來支持商品、用戶等(如下統稱文檔)的搜索和分析。ide
ES爲查詢功能提供了基於Json的完整Query DSL,功能很是強大,但同時也略顯複雜,學習成本不低。學習
以搜索暱稱爲化仁的用戶爲例,DSL大體以下:搜索引擎
json {"from" : 0, "size" : 20, "query" : {"bool" : { "must" : { "multi_match" : {"query" : "化仁", "fields": [ "nickname", "nickname.pinyin" ], "type" :"best_fields", "operator" : "OR","minimum_should_match" : "1", "tie_breaker" : 1.0} }, "filter" : { "term" : { "del" : 0 } } } } }設計
若是讓每一個業務方根據須要編寫DSL實現相應功能,工做量及維護複雜程度可想而知!代理
避免依賴限制擴散視頻
· ES要求客戶端和服務端JDK版本儘可能保持一致blog
· ES2.x要求JDK7以上
· ES5.x要求JDK8以上
· 大量Jar包依賴
· 其它可能出現的限制
使用查詢代理以後,各業務方無需引入上述依賴和限制
鬆耦合及管控
屏蔽底層引擎變更對線上業務的影響,例如底層引擎偶爾須要升級或重啓,此時,只需查詢代理層實現主從切換等機制,引擎的升級可作到對線上業務徹底透明。
此外,查詢代理還能夠屏蔽業務方錯誤的危險操做,防止集羣直接暴露給各業務方,從而下降不肯定因素對系統的影響。
2、查詢代理層實現
業界作法
業界有將SQL做爲代理層語言,實現一套SQL轉DSL的解析器,這種方式針對將ES做爲DB使用的狀況很是合適。可是,前面提到過,某二手交易平臺的使用場景是文檔的搜索,其中涉及到文檔的複雜排序,SQL沒法完整實現目標需求,並且文檔屬性很是多的狀況下,容易產生語句過於複雜的問題。
方案
種種因果,咱們最終的實現方案以下:
請求語法
· 語句分爲query域和param域,query域爲篩選召回條件,param域爲排序參數;
· 域爲屬性字段的組合;
· 域使用URL參數語法表述;
還以搜索暱稱爲化仁的用戶爲例,請求以下:
query:from=1&size=10&nickname=化仁 param: null 請求會自動轉換成前面提到的DSL例子。能夠看到,相比之下仍是很是簡單的。
實現邏輯
補充說明:
· 根據解析方式,字段大體分爲:內置字段 (起始位置、獲取數量、排序策略等) 和 配置字段 (字符串、數值、日期、經緯度等,會解析成對應ES支持的索引字段類型)
· 配置字段根據使用場景分爲:匹配篩選型、排序參數型、字段排序型、排序打分型、二次打分型等
· 各類類型的配置字段配有配置解析器和請求處理器
· 處理過程當中會作諸如字段默認值、非法字段過濾等處理
· 處理過程生成query的梗概信息做爲外部緩存的key值,減輕ES集羣壓力
· 請求通過校驗、解析、處理後拼裝成ES的DSL,請求發送到系統分配ES集羣
配置樣例:
yml entry.user:index: user type: user query_fields: - { face: id, type: Number, class: Long }- { face: nickname, type: StringMultiMatch, fieldName:"nickname,nickname.pinyin", _tie_breaker: 1 } order_strategys:default: boostMode: multiply scores: - type: NumberTermsFilter fieldName: label_idclass: Long values: "1141730738345" weight: 2
3、總結
本文從ES查詢接口的必要性出發,主要講述了某二手交易平臺ES查詢接口的語法設計和實現邏輯及簡要說明。其中有不合理之處,歡迎指正交流。
更多免費技術資料及視頻