一. 知識(shí)儲(chǔ)備
1.0 什么是ES
Elasticsearch 是一個(gè)高度可擴(kuò)展的開(kāi)源全文搜索和分析引擎懂扼。它可以近乎實(shí)時(shí)地快速存儲(chǔ)辆毡、搜索和 分析大量數(shù)據(jù)。它通常用作支持具有復(fù)雜搜索功能和要求的應(yīng)用程序的底層引擎/技術(shù)。
Elasticsearch是一個(gè)可實(shí)時(shí)的分布式存儲(chǔ)、搜索唐含、分析大量數(shù)據(jù)的引擎
Index:Elasticsearch的Index相當(dāng)于數(shù)據(jù)庫(kù)的Table
Type:這個(gè)在新的Elasticsearch版本已經(jīng)廢除(在以前的Elasticsearch版本,一個(gè)Index下支持多個(gè)Type--有點(diǎn)類(lèi)似于消息隊(duì)列一個(gè)topic下多個(gè)group的概念)
Document:Document相當(dāng)于數(shù)據(jù)庫(kù)的一行記錄
Field:相當(dāng)于數(shù)據(jù)庫(kù)的Column的概念
Mapping:相當(dāng)于數(shù)據(jù)庫(kù)的Schema的概念
DSL:相當(dāng)于數(shù)據(jù)庫(kù)的SQL(給我們讀取Elasticsearch數(shù)據(jù)的API)
1.1字段類(lèi)型
1.字符串:text和keyword滤钱,text會(huì)被分詞器解析, 生成倒排索引, 支持模糊觉壶、精確查詢(xún), 不用于排序, 很少用于聚合脑题。keyword不進(jìn)行分詞件缸,直接索引, 支持模糊、精確查詢(xún), 支持聚合叔遂。
2. 數(shù)值類(lèi)型:byte, short, integer, long他炊,浮點(diǎn)數(shù):float, half_float, scaled_float, double
3. Object類(lèi)型:Json嵌套json格式,ES索引的時(shí)候會(huì)扁平化
4. date類(lèi)型
5. array類(lèi)型
6. ip類(lèi)型已艰,range類(lèi)型
7. nested類(lèi)型痊末,是一個(gè)數(shù)組,數(shù)組里面是對(duì)象
1.2 各類(lèi)查詢(xún)
1.2.1 match:模糊搜索哩掺,入?yún)?huì)被分詞
1.2.2 term:精確查找凿叠,入?yún)⒉粫?huì)被分詞
1.2.3 match_parse: .........
詳情參考:http://www.reibang.com/p/2156335257b6,講得非常好
1.3 數(shù)據(jù)結(jié)構(gòu)
倒排索引,存入ES的字段會(huì)被分詞盒件,然后構(gòu)建倒排索引蹬碧。
分詞存在termDictionary,文檔id存在posting中炒刁。由于Term Dictionary
的詞實(shí)在太多了恩沽,不可能把Term Dictionary
所有的詞都放在內(nèi)存中,于是Elasticsearch還抽了一層叫做Term Index
翔始,這層只存儲(chǔ) 部分 詞的前綴罗心,Term Index
會(huì)存在內(nèi)存中(檢索會(huì)特別快),在內(nèi)存中是以FST(Finite State Transducers)的形式保存的城瞎,其特點(diǎn)是非常節(jié)省內(nèi)存渤闷。
具體參考:https://cdn.modb.pro/db/115165
1.4 數(shù)據(jù)寫(xiě)入
1.5.查詢(xún)過(guò)程
客戶(hù)端請(qǐng)求發(fā)送到集群的某個(gè)節(jié)點(diǎn)上。集群上的每個(gè)節(jié)點(diǎn)都是
coordinate node
(協(xié)調(diào)節(jié)點(diǎn))然后協(xié)調(diào)節(jié)點(diǎn)將搜索的請(qǐng)求轉(zhuǎn)發(fā)到所有分片上(主分片和副本分片都行)
每個(gè)分片將自己搜索出的結(jié)果
(doc id)
返回給協(xié)調(diào)節(jié)點(diǎn)脖镀,由協(xié)調(diào)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)的合并肤晓、排序、分頁(yè)等操作认然,產(chǎn)出最終結(jié)果补憾。接著由協(xié)調(diào)節(jié)點(diǎn)根據(jù)
doc id
去各個(gè)節(jié)點(diǎn)上拉取實(shí)際的document
數(shù)據(jù),最終返回給客戶(hù)端卷员。
一個(gè)查詢(xún)語(yǔ)句究竟具有什么樣的行為和得到什么結(jié)果盈匾,主要取決于它到底是處Query
還是Filter
。兩者有很大區(qū)別毕骡,我們來(lái)看下:
Query context 查詢(xún)上下文
這種語(yǔ)句在執(zhí)行時(shí)既要計(jì)算文檔是否匹配削饵,還要計(jì)算文檔相對(duì)于其他文檔的匹配度有多高,匹配度越高未巫,_score
分?jǐn)?shù)就越高
Filter context 過(guò)濾上下文
過(guò)濾上下文中的語(yǔ)句在執(zhí)行時(shí)只關(guān)心文檔是否和查詢(xún)匹配窿撬,不會(huì)計(jì)算匹配度,也就是得分叙凡。
1.6.倒排索引查詢(xún)
通過(guò) Term Index 數(shù)據(jù)(.tip文件)中的 StartFP 獲取指定字段的 FST
通過(guò) FST 找到指定 Term 在 Term Dictionary(.tim 文件)可能存在的 Block
將對(duì)應(yīng) Block 加載內(nèi)存劈伴,遍歷 Block 中的 Entry,通過(guò)后綴(Suffix)判斷是否存在指定 Term
存在則通過(guò) Entry 的 TermStat 數(shù)據(jù)中各個(gè)文件的 FP 獲取 Posting 數(shù)據(jù)
如果需要獲取 Term 對(duì)應(yīng)的所有 DocId 則直接遍歷 TermFreqs握爷,如果獲取指定 DocId 數(shù)據(jù)則通過(guò) SkipData 快速跳轉(zhuǎn)
具體參考:https://zhuanlan.zhihu.com/p/395787179
1.7.監(jiān)控指標(biāo)
參考:https://blog.csdn.net/pangyemeng/article/details/77524332
二. 查詢(xún)分析
查詢(xún)條件:所有自選股票通過(guò)stock字段match跛璧,通過(guò)tags字段嵌套match,查詢(xún)出來(lái)的結(jié)果取并集新啼。這個(gè)并集用sortkey降序排列追城,且必需sortkey大于某個(gè)值,取前面20條數(shù)據(jù)燥撞。
- 查詢(xún)是否有緩存座柱,比如{"match": {"stock": "601901"}} 結(jié)果會(huì)被緩存迷帜,然后重復(fù)使用嗎
不會(huì)緩存( Lucene頁(yè)緩存除外),filter過(guò)濾會(huì)有緩存(用bitset緩存文檔是否匹配)
- 嵌套查詢(xún)的原理是什么色洞,有倒排索引嗎
嵌套是ES的增強(qiáng)功能瞬矩,lucene本身沒(méi)有,原理是會(huì)拆分多個(gè)文檔存儲(chǔ)锋玲。性能較差景用,高性能場(chǎng)景不建議使用。
- 查詢(xún)傳進(jìn)來(lái)的自選股票數(shù)量最大多少惭蹂,是否可以控制在一個(gè)范圍
should條件過(guò)多伞插,查詢(xún)也會(huì)比較慢,需要控制要查詢(xún)的自選股票數(shù)
- range查詢(xún)是否需要回表才能過(guò)濾
現(xiàn)在需要盾碗,可以把sortkey創(chuàng)建在索引里
- 分頁(yè)查詢(xún)的話(huà)媚污,每一個(gè)分片應(yīng)該查詢(xún)多少數(shù)據(jù)
每一頁(yè)都會(huì)返回20條數(shù)據(jù),匯總之后排序再取前20條
- 排序是在哪執(zhí)行的廷雅,每個(gè)分片還是調(diào)度者耗美。
排序在每個(gè)分片上會(huì)執(zhí)行,總體的時(shí)候還會(huì)執(zhí)行一遍
數(shù)據(jù)是:stock航缀,content都是text類(lèi)型商架。tags是nested類(lèi)型
三. 對(duì)外溝通
- ES能夠直接TO C嗎,可以承接多大的流量(目前我們只能抗400QPS)芥玉,ES集群需要什么樣的配置(目前我們是3臺(tái)物理機(jī)(16C 32G 1TB)蛇摸,每臺(tái)物理機(jī)部署2個(gè)節(jié)點(diǎn),總共6個(gè)節(jié)點(diǎn)灿巧,一個(gè)備份)(master赶袄,數(shù)據(jù)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn)抠藕,預(yù)處理節(jié)點(diǎn))
ES可以直接對(duì)外提高服務(wù)饿肺,對(duì)于索引的創(chuàng)建和數(shù)據(jù)查詢(xún)需要謹(jǐn)慎設(shè)計(jì),美團(tuán)地圖搜索大約能夠承載3WQPS的查詢(xún)盾似。
目前的數(shù)據(jù)體量敬辣,千萬(wàn)級(jí)數(shù)據(jù)(新聞,投研颜说,公告)购岗,單條數(shù)據(jù)最大10M,一般可能100KB门粪。
ES查詢(xún)運(yùn)行的原理是什么德撬,有類(lèi)似mysql的 cache buffer嗎拢蛋,如果內(nèi)存沒(méi)有,磁盤(pán)搜索快嗎灵疮。
lucene會(huì)有頁(yè)緩存,如果使用filter會(huì)有bitset緩存拟蜻。
- ES query查詢(xún)和filter查詢(xún)的區(qū)別绎签,為什么網(wǎng)上說(shuō)filter查詢(xún)可以用到緩存,這個(gè)緩存是如何更新的呢
query:是會(huì)計(jì)算doc對(duì)搜索條件的relevance score酝锅,還會(huì)根據(jù)這個(gè)score去排序
filter:只是簡(jiǎn)單過(guò)濾出想要的數(shù)據(jù)诡必,不計(jì)算relevance score,也不排序搔扁。更新或者刪除文檔會(huì)更新緩存爸舒。
- ES集群搭建有哪些常用優(yōu)化手段(JVM,連接池稿蹲,分片扭勉,備份,linux參數(shù))
建議jvm內(nèi)存設(shè)置成物理內(nèi)存的一半苛聘,一臺(tái)物理機(jī)只部署一個(gè)節(jié)點(diǎn)涂炎。連接池和linux參數(shù)采取默認(rèn)值即可。
四. 總體優(yōu)化建議
match操作修改為filter操作设哗,因?yàn)闆](méi)有相關(guān)性評(píng)分需求
嵌套查詢(xún)盡可能改成非嵌套模式
ES機(jī)器一臺(tái)物理機(jī)只部署一個(gè)節(jié)點(diǎn)唱捣,jvm內(nèi)存設(shè)置成物理內(nèi)存的一半
sortkey包含在索引里
控制需要查詢(xún)的自選股數(shù)量
content字段比較大,而且不需要被索引网梢,建議分開(kāi)創(chuàng)建文檔結(jié)構(gòu)存儲(chǔ)
冷熱數(shù)據(jù)分離爷光,舉例:一年前的數(shù)據(jù)從當(dāng)前索引剝離
建議使用id進(jìn)行排序和分頁(yè),目前的must條件過(guò)濾不掉什么數(shù)據(jù)
一階段todo:
@廖佳豪
1. 排序邏輯修改
2. termQuery是filter邏輯嗎澎粟,到ES的語(yǔ)句是什么樣的
@李文水
3.執(zhí)行計(jì)劃調(diào)查
添加"profile": "true", 可查看執(zhí)行計(jì)劃
4.嵌套查詢(xún)是影響性能嗎
嵌套查詢(xún)與match查詢(xún)蛀序,性能相差一倍。60個(gè)自選股用match匹配(80)和nested匹配(150ms)活烙。建議stock字段和tags字段揉合加工到一個(gè)字段徐裸。
5.自選股分布情況,30個(gè)和300個(gè)差別多大
性能隨著自選股數(shù)量增多而惡化啸盏,30個(gè)自選股耗時(shí)300ms重贺,60個(gè)自選股耗時(shí)600ms。建議自選股數(shù)量限制在50個(gè)
五. 總體思考&實(shí)施建議
目標(biāo)QPS:1.6W回懦,目前ES可抗400QPS气笙。
<colgroup><col width="128"><col width="133"><col width="244"><col width="287"><col width="154"></colgroup>
|
方向
|
子方向
|
現(xiàn)狀
|
建議
|
備注
|
|
查詢(xún)語(yǔ)句
|
根據(jù)標(biāo)簽查詢(xún)資訊
|
query match匹配
|
Filter term匹配
|
標(biāo)簽匹配思考:
一個(gè)標(biāo)簽一定需要匹配一次,只能盡可能減少匹配次數(shù)和每一次匹配速度怯晕。
|
|
一個(gè)標(biāo)簽有2個(gè)stock match匹配潜圃,一個(gè)tags nested匹配
|
減少匹配數(shù)量,做到一個(gè)標(biāo)簽一次匹配
|
|
標(biāo)簽數(shù)量最多300個(gè)
|
300個(gè)標(biāo)簽過(guò)多舟茶,建議控制在50個(gè)
|
|
排序分頁(yè)
|
sortkey小于XX谭期,from size模式
|
search_after模式
| |
|
ES數(shù)據(jù)結(jié)構(gòu)
|
搜索字段定義
|
1.Content(contentSegStr) text類(lèi)型堵第,默認(rèn)分詞器
2.Stock text類(lèi)型,空格分詞器
3.Tags nested類(lèi)型隧出,tagCode keyword類(lèi)型踏志,highlight integer類(lèi)型。
4.sortkey keyword類(lèi)型
|
1.Content(contentSegStr)不要分詞
| |
|
嵌套結(jié)構(gòu)
|
tags為嵌套結(jié)構(gòu)
|
性能比非嵌套結(jié)構(gòu)差一倍胀瞪,建議換成扁平結(jié)構(gòu)
|
C端盡量扁平针余,離線(xiàn)盡量多干活。
|
|
數(shù)據(jù)隔離
|
一個(gè)標(biāo)簽可能查詢(xún)出來(lái)上萬(wàn)個(gè)文檔凄诞,但是我們一般可能只需要前面1000個(gè)
|
冷熱數(shù)據(jù)隔離圆雁,建立一個(gè)最近1年數(shù)據(jù)的別名
| |