0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

解密Elasticsearch:深入探究這款搜索和分析引擎

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-09-20 14:37 ? 次閱讀

?開篇

最近使用Elasticsearch實現(xiàn)畫像系統(tǒng),實現(xiàn)的dmp的數(shù)據(jù)中臺能力。同時調(diào)研了競品的架構(gòu)選型。以及重溫了redis原理等。特此做一次es的總結(jié)和回顧。網(wǎng)上沒看到有人用Elasticsearch來完成畫像的。我來做第一次嘗試。

背景說完,我們先思考一件事,使用內(nèi)存系統(tǒng)做數(shù)據(jù)庫。他的優(yōu)點是什么?他的痛點是什么?

?一、原理

這里不在闡述全貌。只聊聊通訊、內(nèi)存、持久化三部分。

通訊

es集群最小單元是三個節(jié)點。兩個從節(jié)點搭配保證其高可用也是集群化的基礎。那么節(jié)點之間RPC通訊用的是什么?必然是netty,es基于netty實現(xiàn)了Netty4Transport的通訊包。初始化Transport后建立Bootstrap,通過MessageChannelHandler完成接收和轉(zhuǎn)發(fā)。es里區(qū)分server和client,如圖1。序列化使用的json。es在rpc設計上偏向于易用、通用、易理解。而不是單追求性能。

wKgaombtGDuAYsf6AACTtnR5aTA620.png

??

圖1

有了netty的保駕護航使得es放心是使用json序列化。

內(nèi)存

wKgaombtGD2AYwM4AAAvB7I1388822.png

??

圖2

es內(nèi)存分為兩部分【on heap】和【off heap】。on heap這部分由es的jvm管理。off heap則是由lucene管理。on heap 被分為兩部分,一部分可以回收,一部分不能回收。

能回收的部分index buffer存儲新的索引文檔。當被填滿時,緩沖區(qū)的文檔會被寫入到磁盤segment上。node上共享所有shards。

不能被回收的有node query cache、shard request cache、file data cache、segments cache

node query cache是node級緩存,過濾后保存在每個node上,被所有shards共享,使用bitset數(shù)據(jù)結(jié)構(gòu)(布隆優(yōu)化版)關(guān)掉了評分。使用的LRU淘汰策略。GC無法回收。

shard request cache是shard級緩存,每個shard都有。默認情況下該緩存只存儲request結(jié)果size等于0的查詢。所以該緩存不會被hits,但卻緩存hits.total,aggregations,suggestions??梢酝ㄟ^clear cache api清除。使用的LRU淘汰策略。GC無法回收。

file data cache 是把聚合、排序后的data緩存起來。初期es是沒有doc values的,所以聚合、排序后需要有一個file data來緩存,避免磁盤IO。如果沒有足夠內(nèi)存存儲file data,es會不斷地從磁盤加載數(shù)據(jù)到內(nèi)存,并刪除舊的數(shù)據(jù)。這些會造成磁盤IO和引發(fā)GC。所以2.x之后版本引入doc values特性,把文檔構(gòu)建在indextime上,存儲到磁盤,通過memory mapped file方式訪問。甚至如果只關(guān)心hits.total,只返回doc id,關(guān)掉doc values。doc values支持keyword和數(shù)值類型。text類型還是會創(chuàng)建file data。

segments cache是為了加速查詢,F(xiàn)ST永駐堆內(nèi)內(nèi)存。FST可以理解為前綴樹,加速查詢。but??!es 7.3版本開始把FST交給了堆外內(nèi)存,可以讓節(jié)點支持更多的數(shù)據(jù)。FST在磁盤上也有對應的持久化文件。

off heap 即Segments Memory,堆外內(nèi)存是給Lucene使用的。 所以建議至少留一半的內(nèi)存給lucene。

es 7.3版本開始把tip(terms index)通過mmp方式加載,交由系統(tǒng)的pagecache管理。除了tip,nvd(norms),dvd(doc values), tim(term dictionary),cfs(compound)類型的文件都是由mmp方式加載傳輸,其余都是nio方式。tip off heap后的效果jvm占用量下降了78%左右。可以使用_cat/segments API 查看 segments.memory內(nèi)存占用量。

由于對外內(nèi)存是由操作系統(tǒng)pagecache管理內(nèi)存的。如果發(fā)生回收時,F(xiàn)ST的查詢會牽扯到磁盤IO上,對查詢效率影響比較大。可以參考linux pagecache的回收策略使用雙鏈策略。

持久化

es的持久化分為兩部分,一部分類似快照,把文件緩存中的segments 刷新(fsync)磁盤。另一部分是translog日志,它每秒都會追加操作日志,默認30分鐘刷到磁盤上。es持久化和redis的RDB+AOF模式很像。如下圖

wKgaombtGD6AZlf1AACKOS_NcvA912.png

??

圖3

上圖是一個完整寫入流程。磁盤也是分segment記錄數(shù)據(jù)。這里濡染跟redis很像。但是內(nèi)部機制沒有采用COW(copy-on-write)。這也是查詢和寫入并行時load被打滿的原因所在。

wKgZombtGECALbCZAACMvZrlAxI716.png

??

圖4

如果刪除操作,并不是馬上物理清除被刪除的文檔,而是標記為delete狀態(tài);更新操作,標記原有的文檔為delete狀態(tài),再插入一條新的文檔。( 如圖4)

系統(tǒng)中會產(chǎn)生很多的Segment file文件。所以定期要執(zhí)行合并(merge)操作,將多個Segment file文件合并為一個。在合并的過程中,會將標記刪除的文件進行物理刪除操作。

ES記錄每個Segment file文件的提交點(commit point),用于管理所有的Segment file文件。

小結(jié)

es內(nèi)存和磁盤的設計上非常巧妙。零拷貝上采用mmap方式,磁盤數(shù)據(jù)映射到off heap,也就是lucene。為了加速數(shù)據(jù)的訪問,es每個segment都有會一些索引數(shù)據(jù)駐留在off heap里;因此segment越多,瓜分掉的off heap也越多,這部分是無法被GC回收!

結(jié)合以上兩點可以清楚知道為什么es非常吃內(nèi)存了。

二、應用

用戶畫像系統(tǒng)中有以下難點需要解決。

1.人群預估:根據(jù)標簽選出一類人群,如20-25歲的喜歡電商社交的男性。20-25歲∩電商社交∩男性。通過與或非的運算選出符合特征的clientId的個數(shù)。這是一組。

我們組與組之前也是可以在做交并差的運算。如既是20-25歲的喜歡電商社交的男性,又是北京市喜歡擼鐵的男性。(20-25歲∩電商社交∩男性)∩(20-25歲∩擼鐵∩男性)。對于這樣的遞歸要求在17億多的畫像庫中,秒級返回預估人數(shù)。

2.人群包圈選:上述圈選出的人群包。 要求分鐘級構(gòu)建。

3.人包判定:判斷一個clientId是否存在若干個人群包中。要求10毫秒返回結(jié)果。

我們先嘗試用es來解決以上所有問題。

人群預估,最容易想到方案是在服務端的內(nèi)存中做邏輯運算。但是圈選出千萬級的人群包人數(shù)秒級返回的話在服務端做代價非常大。這時候可以吧計算壓力拋給es存儲端,像查詢數(shù)據(jù)庫一樣。使用一條語句查出我們想要的數(shù)據(jù)來。

例如mysql

select a.age from a where a.tel in (select b.age from b);

對應的es的dsl類似于

{"query":{"bool":{"must":[{"bool":{"must":[{"term":{"a9aa8uk0":{"value":"age18-24","boost":1.0}}},{"term":{"a9ajq480":{"value":"male","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}},{"bool":{"adjust_pure_negative":true,"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}}}

這樣使用es的高檢索性能來滿足業(yè)務需求。無論所少組,組內(nèi)多少的標簽。都打成一條dsl語句。來保證秒級返回結(jié)果。

使用官方推薦的RestHighLevelClient,實現(xiàn)方式有三種,一種是拼json字符串,第二種調(diào)用api去拼字符串。我使用第三種方式BoolQueryBuilder來實現(xiàn),比較優(yōu)雅。它提供了filter、must、should和mustNot方法。如

     /**
     * Adds a query that must not appear in the matching documents.
     * No {@code null} value allowed.
     */
    public BoolQueryBuilder mustNot(QueryBuilder queryBuilder) {
        if (queryBuilder == null) {
            throw new IllegalArgumentException("inner bool query clause cannot be null");
        }
        mustNotClauses.add(queryBuilder);
        return this;
    }

    /**
     * Gets the queries that must not appear in the matching documents.
     */
    public List mustNot() {
        return this.mustNotClauses;
    }

使用api的可以大大的show下編代碼的能力。

構(gòu)建人群包。目前我們?nèi)Τ鲎畲蟮陌?千多萬的clientId。想要分鐘級別構(gòu)建完(7千萬數(shù)據(jù)在條件限制下35分鐘構(gòu)建完)需要注意兩個地方,一個是es深度查詢,另一個是批量寫入。

es分頁有三種方式,深度分頁有兩種,后兩種都是利用游標(scroll和search_after)滾動的方式檢索。

scroll需要維護游標狀態(tài),每一個線程都會創(chuàng)建一個32位唯一scroll id,每次查詢都要帶上唯一的scroll id。如果多個線程就要維護多個游標狀態(tài)。search_after與scroll方式相似。但是它的參數(shù)是無狀態(tài)的,始終會針對對新版本的搜索器進行解析。它的排序順序會在滾動中更改。scroll原理是將doc id結(jié)果集保留在協(xié)調(diào)節(jié)點的上下文里,每次滾動分批獲取。只需要根據(jù)size在每個shard內(nèi)部按照順序取回結(jié)果即可。

寫入時使用線程池來做,注意使用的阻塞隊列的大小,還要選擇適的拒絕策略(這里不需要拋異常的策略)。批量如果還是寫到es中(比如做了讀寫分離)寫入時除了要多線程外,還有優(yōu)化寫入時的refresh policy。

人包判定接口,由于整條業(yè)務鏈路非常長,這塊檢索,上游服務設置的熔斷時間是10ms。所以優(yōu)化要優(yōu)化es的查詢(也可以redis)畢竟沒負責邏輯處理。使用線程池解決IO密集型優(yōu)化后可以達到1ms。tp99高峰在4ms。

?三、優(yōu)化、瓶頸與解決方案

以上是針對業(yè)務需求使用es的解題方式。還需要做響應的優(yōu)化。同時也遇到es的瓶頸。

1.首先是mapping的優(yōu)化。畫像的mapping中fields中的type是keyword,index要關(guān)掉。人包中的fields中的doc value關(guān)掉。畫像是要精確匹配;人包判定只需要結(jié)果而不需要取值。es api上人包計算使用filter去掉評分,filter內(nèi)部使用bitset的布隆數(shù)據(jù)結(jié)構(gòu),但是需要對數(shù)據(jù)預熱。寫入時線程不易過多,和核心數(shù)相同即可;調(diào)整refresh policy等級。手動刷盤,構(gòu)建時index.refresh_interval 調(diào)整-1,需要注意的是停止刷盤會加大堆內(nèi)存,需要結(jié)合業(yè)務調(diào)整刷盤頻率。構(gòu)建大的人群包可以將index拆分成若干個。分散存儲可以提高響應。目前幾十個人群包還是能支撐。如果日后成長到幾百個的時候。就需要使用bitmap來構(gòu)建存儲人群包。es對檢索性能很卓越。但是如遇到寫操作和查操作并行時,就不是他擅長的。比如人群包的數(shù)據(jù)是每天都在變化的。這個時候es的內(nèi)存和磁盤io會非常高。上百個包時我們可以用redis來存。也可以選擇使用MongoDB來存人包數(shù)據(jù)。

四、總結(jié)

以上是我們使用Elasticsearch來解決業(yè)務上的難點。同時發(fā)現(xiàn)他的持久化沒有使用COW(copy-on-write)方式。導致在實時寫的時候檢索性能降低。

使用內(nèi)存系統(tǒng)做數(shù)據(jù)源有點非常明顯,就是檢索塊!尤其再實時場景下堪稱利器。同時痛點也很明顯,實時寫會拉低檢索性能。當然我們可以做讀寫分離,拆分index等方案。

除了Elasticsearch,我們還可以選用ClickHouse,ck也是支持bitmap數(shù)據(jù)結(jié)構(gòu)。甚至可以上Pilosa,pilosa本就是BitMap Database。

?

?

參考

?貝殼DMP平臺建設實踐?

?Mapping parameters | Elasticsearch Reference [7.10] | Elastic?

?Elasticsearch 7.3 的 offheap 原理?

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3904

    瀏覽量

    65832
  • 引擎
    +關(guān)注

    關(guān)注

    1

    文章

    366

    瀏覽量

    22909
  • Elasticsearch
    +關(guān)注

    關(guān)注

    0

    文章

    30

    瀏覽量

    2989
收藏 人收藏

    評論

    相關(guān)推薦
    熱點推薦

    單節(jié)點Elasticsearch+Filebeat+Kibana安裝指南

    單節(jié)點Elasticsearch+Filebeat+Kibana安裝指南
    的頭像 發(fā)表于 05-21 11:06 ?163次閱讀
    單節(jié)點<b class='flag-5'>Elasticsearch</b>+Filebeat+Kibana安裝指南

    如何在Linux環(huán)境下高效安裝部署和配置Elasticsearch

    /CentOS-7-x86_64-DVD-2009.iso elasticsearch-7.10.0-linux-x86_64.tar.gz https://www.elastic.co/cn/downloads/past-releases
    的頭像 發(fā)表于 01-16 11:49 ?908次閱讀

    在華為云上通過 Docker 容器部署 Elasticsearch 并進行性能評測

    ? 2.2 安裝 Docker ? 2.3 啟動 Docker ? 3. 使用Docker部署Elasticsearch ? 3.1 拉取Elasticsearch鏡像 ? 3.2 啟動
    的頭像 發(fā)表于 01-13 13:36 ?397次閱讀
    在華為云上通過 Docker 容器部署 <b class='flag-5'>Elasticsearch</b> 并進行性能評測

    構(gòu)建高效搜索解決方案,Elasticsearch &amp; Kibana 的完美結(jié)合

    前言 構(gòu)建高效搜索解決方案,F(xiàn)lexusX 服務器與 Elasticsearch & Kibana 的完美結(jié)合,為企業(yè)帶來云端搜索新體驗。FlexusX 實例以其卓越性能與靈活擴展性,確保高并發(fā)
    的頭像 發(fā)表于 12-27 13:48 ?356次閱讀
    構(gòu)建高效<b class='flag-5'>搜索</b>解決方案,<b class='flag-5'>Elasticsearch</b> &amp; Kibana 的完美結(jié)合

    SSR的優(yōu)勢和劣勢分析

    SSR(Server-Side Rendering,服務器端渲染)的優(yōu)勢和劣勢分析如下: SSR的優(yōu)勢 SEO友好 : 由于搜索引擎爬蟲的性質(zhì),更容易識別和抓取服務端渲染的頁面內(nèi)容,因此提升了網(wǎng)站
    的頭像 發(fā)表于 11-18 11:27 ?1403次閱讀

    阿里國際推出全球首個B2B AI搜索引擎Accio

    近日,在歐洲科技峰會Web Summit上,阿里國際正式推出了全球首個B2B領(lǐng)域的AI搜索引擎——Accio。這一創(chuàng)新產(chǎn)品面向全球商家開放,標志著阿里國際正式入局當前備受矚目的AI Search賽道。
    的頭像 發(fā)表于 11-15 16:53 ?1137次閱讀

    Elasticsearch 再次開源

    Elasticsearch 和 Kibana 又可以被稱為開源了。很難表達這句話讓我有多高興。我激動得簡直要跳起來了。我們 Elastic 的所有人都是如此。開源是我的 DNA。這也是Elastic的DNA。能夠再次將 Elasticsearch 稱為開源,我感到非常高興
    的頭像 發(fā)表于 11-13 12:14 ?399次閱讀
    <b class='flag-5'>Elasticsearch</b> 再次開源

    Meta開發(fā)新搜索引擎,減少對谷歌和必應的依賴

    將基于Meta AI聊天機器人進行生成。 據(jù)一位曾與Meta搜索引擎團隊交流過的人士透露,Meta希望通過這款搜索引擎降低對谷歌搜索和微軟必應的依賴。目前,這兩家
    的頭像 發(fā)表于 10-29 11:49 ?753次閱讀

    月訪問量超2億,增速113%!360AI搜索成為全球增速最快的AI搜索引擎

    與傳統(tǒng)搜索引擎不同,作為AI原生搜索引擎的360AI搜索基于公開網(wǎng)絡、知識庫、大模型三大支柱。借助首創(chuàng)的 CoE 技術(shù)架構(gòu),360AI搜索整合了國內(nèi)主流的16家廠商51款大模型,支持用
    的頭像 發(fā)表于 09-09 13:44 ?818次閱讀
    月訪問量超2億,增速113%!360AI<b class='flag-5'>搜索</b>成為全球增速最快的AI<b class='flag-5'>搜索引擎</b>

    軟件系統(tǒng)的數(shù)據(jù)檢索設計

    存儲、搜索、分析引擎,它可以近乎實時的存儲、檢索數(shù)據(jù),本身擴展性很好,可以擴展到上百臺服務器,處理PB級別(大數(shù)據(jù)時代)的數(shù)據(jù),ElasticSearch的檢索流程如下: 數(shù)據(jù)檢索流
    的頭像 發(fā)表于 08-22 14:08 ?459次閱讀
    軟件系統(tǒng)的數(shù)據(jù)檢索設計

    深入探究石英可編程 DXO/VCXO 振蕩器 SWPQ201 系列(10MHz 至 1500 MHz)

    深入探究石英可編程 DXO/VCXO 振蕩器 SWPQ201 系列(10MHz 至 1500 MHz)
    的頭像 發(fā)表于 08-10 10:05 ?804次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>探究</b>石英可編程 DXO/VCXO 振蕩器 SWPQ201 系列(10MHz 至 1500 MHz)

    OpenAI推出SearchGPT原型,正式向Google搜索引擎發(fā)起挑戰(zhàn)

    在人工智能領(lǐng)域的持續(xù)探索中,OpenAI 邁出了重大一步,發(fā)布了其最新的 SearchGPT 原型,直接瞄準了 Google 的核心業(yè)務——搜索引擎。這一舉動不僅標志著 OpenAI 在技術(shù)上的又一次飛躍,也預示著搜索引擎市場即將迎來一場前所未有的變革。
    的頭像 發(fā)表于 07-26 15:11 ?761次閱讀

    微軟計劃在搜索引擎Bing中引入AI摘要功能

    近期,科技界傳來新動向,微軟緊隨百度與谷歌的步伐,宣布計劃在其搜索引擎Bing中引入先進的AI摘要功能,旨在為用戶帶來更加智能、豐富的搜索體驗。
    的頭像 發(fā)表于 07-26 14:23 ?714次閱讀

    深入探究 MEMS LVCMOS 振蕩器 SiT1602 系列 52 種標準頻率

    深入探究 MEMS LVCMOS 振蕩器 SiT1602 系列(52 種標準頻率)
    的頭像 發(fā)表于 07-19 16:16 ?589次閱讀

    深入理解渲染引擎:打造逼真圖像的關(guān)鍵

    在數(shù)字世界中,圖像渲染是創(chuàng)造逼真視覺效果的核心技術(shù)。渲染引擎,作為這一過程中的關(guān)鍵組件,負責將二維或三維的模型、紋理、光照等數(shù)據(jù)轉(zhuǎn)化為人們?nèi)庋劭梢姷亩S圖像。本文將深入探討渲染引擎的工作原理及其在打
    的頭像 發(fā)表于 06-29 08:28 ?613次閱讀
    <b class='flag-5'>深入</b>理解渲染<b class='flag-5'>引擎</b>:打造逼真圖像的關(guān)鍵

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學習
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品