1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Solr vs ElasticSearch,搜索技術(shù)哪家強(qiáng)

        共 8984字,需瀏覽 18分鐘

         ·

        2021-09-22 22:33

        點(diǎn)擊“開發(fā)者技術(shù)前線”,選擇“星標(biāo)”

        讓一部分開發(fā)者看到未來


        前言

        Solr和ElasticSearch到底有一些什么不同?我在網(wǎng)上搜索了一些文章,這些文章要么是列出一個(gè)表,詳細(xì)地介紹兩者什么功能有,什么功能沒有(比較好的一篇博客https://solr-vs-elasticsearch.com),要么是從大類出發(fā)(其中比較好的一篇文章https://logz.io/blog/solr-vs-elasticsearch),比較兩者的關(guān)注度,社區(qū)等等。但看完這些文章,還是沒法解決我心中的疑惑。最近由于項(xiàng)目的原因,Solr和ElasticSearch都有所使用。最近又把solr和ElasticSearch的官方文檔都過了一遍。對兩者有了一些淺顯的見解。所以在這里想跟大家分享下我的一些看法。在這篇文章中,我不會列出一個(gè)列表來說明兩者的異同,而是抽出我覺得比較重要的幾點(diǎn)來講一講。本文的對比基于Solr7.3和ElasticSearch7.4。兩者都在快速迭代,可能有一些最新的進(jìn)展我沒有考慮到,同時(shí)我接觸搜索引擎的時(shí)間不長,難免有一些錯(cuò)誤或者我沒關(guān)注到的點(diǎn),歡迎大家指正。


        相同點(diǎn)

        • 兩者都基于Lucene實(shí)現(xiàn)

        這看起來像一句廢話,因?yàn)橹肋@兩個(gè)產(chǎn)品的人,一定知道Solr和ElasticSearch都是基于Luence實(shí)現(xiàn)的。但其實(shí)這句話蘊(yùn)含了兩層意思。

        第一層是Luence支持的功能他們都支持,只是概念和用法上稍有不同。Luence這個(gè)引擎已經(jīng)非常強(qiáng)大,我們在使用搜索引擎時(shí)看到的絕大部分功能,Luence都可以實(shí)現(xiàn)。比如索引時(shí)的分詞,查詢時(shí)的切面(Facet),高亮,拼寫檢查,搜索建議,相似頁面等等,其實(shí)這些都是Luence中實(shí)現(xiàn)的功能,Solr和ElasticSearch都只不過做了包裝而已。Luence中不僅有倒排索引,還有TermVector這種每個(gè)文檔的正排索引,還有DocValue這種列存結(jié)構(gòu),不同的數(shù)據(jù)類型支持了不同的搜索要求。舉例來說,對于按某一個(gè)列排序的需求,如果只有倒排索引,拿到每個(gè)doc的ID之后再去分別做seek取出列值來做排序,DocValue這種按列存的結(jié)構(gòu)可以很快地取出對應(yīng)document的列值,而減少磁盤seek操作。同樣,在TermVector中記錄了一個(gè)doc中每個(gè)term的位置,這是實(shí)現(xiàn)關(guān)鍵詞高亮的基礎(chǔ)。

        這句話第二層意思是Luence做不到的事情,Solr和ElasticSearch必須自己想辦法實(shí)現(xiàn)。比如Luence是不支持Document的部分更新的。做為一個(gè)數(shù)據(jù)庫+搜索引擎的混合體,Solr和ElasticSearch如果也不支持Document的部分更新肯定說不過去,所以他們兩者都實(shí)現(xiàn)了先把原來的文檔讀出來再寫的邏輯。當(dāng)然,要讀出原來的文檔就要求文檔的原始數(shù)據(jù)都在,因此Solr中的部分更新要求schema中所有字段要么是stored,要么有docvalue。而ElasticSearch中則比較激進(jìn),每個(gè)Document默認(rèn)都會帶_source字段,原始文檔都會存在里面,不用任何配置就可以支持部分更新。另外一個(gè)Luence做不了的事情就是文檔的立即可見性。Luence的Document一定要commit刷成Segment后,才能被搜索到。對于一個(gè)搜索引擎來講,這無可厚非,寫入的數(shù)據(jù)過段時(shí)間才能被查到非常正常。但是很多人是把Solr和ElasticSearch當(dāng)數(shù)據(jù)庫用的,如果寫入的數(shù)據(jù)不能立刻可見,這對一個(gè)數(shù)據(jù)庫來說是不可以接受的。所以Solr和ElasticSearch都實(shí)現(xiàn)了一個(gè)“Realtime Get”功能,即寫入的數(shù)據(jù),如果是用id去查,是立馬可以查出來的。實(shí)現(xiàn)原理也很簡單,Solr/ES里在index前都會先寫log,面對Get請求時(shí),Luence中不可見的數(shù)據(jù),可以查log。另外一個(gè)有意思的例子是翻頁。在Luence3.5之前是沒有SearchAfter這個(gè)接口的,要實(shí)現(xiàn)翻頁,Solr的早期版本只能全查出來,然后跳過offset條數(shù)據(jù)??上攵绻脩羯罘?,性能有多差。而當(dāng)Luence開始支持SearchAfter,支持從某一個(gè)文檔開始搜索,Solr也開始支持Cursor功能,給上次翻頁的最后一個(gè)文檔做個(gè)標(biāo)記,下一頁從這個(gè)文檔開始查,大大優(yōu)化了翻頁功能。


        • 不止于搜索

        除了單純基于Luence提供的搜索功能,Solr和ElasticSearch還提供了豐富的能力。比如說ElasticSearch的Aggregation能力。ElasticSearch一定是對他的Aggregation功能非常的自信,因?yàn)樵诠俜轿臋n中,Aggregation是介紹完基本概念,安裝部署后的第一章。用戶完全可以把ElasticSearch當(dāng)成一個(gè)分析引擎來用,各種avg,sum,count以及各種聚合方式,都可以實(shí)現(xiàn)。Solr也同樣提供了Analytics Component。兩者的分析功能我都沒有使用過,因此我沒有發(fā)言權(quán)說誰的功能更加強(qiáng)大。ElasticSearch還提供了一個(gè)強(qiáng)大的scripting,可以用ES支持的幾種腳本語言來寫一些復(fù)雜的求值函數(shù)。Solr中也有streamExpression,自定義了豐富的語法和函數(shù)讓用戶直接寫表達(dá)式來查詢。當(dāng)然,人見人愛的SQL功能也必不可少,Solr和ElasticSearch均支持SQL和JDBC訪問。兩者支持的SQL功能可能存在一些差異,在這里我沒有細(xì)究。


        • 分布式架構(gòu)和高可用

        Solr(Cloud)和ElasticSearch都是分布式架構(gòu),支持對索引進(jìn)行分片,將索引分布到不同服務(wù)器上來實(shí)現(xiàn)scale out。同時(shí),他們都支持給每個(gè)Shard來設(shè)置多個(gè)replica來實(shí)現(xiàn)高可用。Shard的多個(gè)replica都是主從架構(gòu),相當(dāng)于一寫多讀。主從之間都是同步復(fù)制。因此在寫入時(shí),一定需要找到主replica,而讀的時(shí)候,隨機(jī)選擇replica都能讀到最新數(shù)據(jù)。同時(shí),Solr和ElasticSearch還支持集群間復(fù)制,但兩者的實(shí)現(xiàn)稍微有些不同,Solr的集群間復(fù)制采用推的方式,而ElasticSearch采用的是拉。Solr支持雙向復(fù)制,從而能夠?qū)崿F(xiàn)雙活,而ElasticSearch只能實(shí)現(xiàn)主向從的復(fù)制來做主備。此外,一些數(shù)據(jù)庫常用的運(yùn)維功能,如snapshot,backup&restore,兩者都支持。


        不同點(diǎn)

        • 分布式的設(shè)計(jì)理念不同

        Solr在最開始的時(shí)候是單機(jī)版的,并不是分布式架構(gòu)。當(dāng)SolrCloud出現(xiàn)時(shí),才有了分布式架構(gòu)。Solr選用了Zookeeper來做分布式架構(gòu)下的協(xié)調(diào)者。Solr中每一個(gè)節(jié)點(diǎn)都是對等的,Zookeeper的使用主要是用來存分片的路由信息,以及各個(gè)replica之間,overseer節(jié)點(diǎn)的搶主。Solr中唯一一個(gè)不同的角色就是overseer,相當(dāng)于Solr集群中的master角色,所有的Collection creation等admin操作,都需要進(jìn)過overseer節(jié)點(diǎn)。同時(shí),overseer節(jié)點(diǎn)可以根據(jù)AutoScalling框架的配置,在節(jié)點(diǎn)丟失和新節(jié)點(diǎn)加入時(shí),做一些預(yù)設(shè)的操作。比如節(jié)點(diǎn)丟失時(shí),為該節(jié)點(diǎn)上的replica自動(dòng)再add一個(gè)新的replica,保持可用replica數(shù)為固定值。AutoScalling框架是Solr 7.0才加入的,從這里開始,Solr才有真正意義上的自動(dòng)運(yùn)維,在這之前,Solr的自動(dòng)運(yùn)維能力比較弱,就連balance集群,都需要手工去操作。

        ElasticSearch從一出生就是分布式架構(gòu)設(shè)計(jì)。與Solr不同的是,ElasticSearch并沒有依賴其他產(chǎn)品來做分布式,而是自研了一套Zen Discovery協(xié)議來做分布式協(xié)調(diào)。因此,ElasticSearch不像Solr(Cloud)那樣依賴一套Zookeeper集群。Zen Discovery把節(jié)點(diǎn)發(fā)現(xiàn),選主,廣播等事情全都干完了。相對于Solr,ElasticSearch的角色更加豐富,除了有與Solr overseer節(jié)點(diǎn)類似的master節(jié)點(diǎn),還可以配置只負(fù)責(zé)index寫入過程中處理復(fù)雜ingest pipeline(比如分詞,變換等等)的ingest node,以及不存數(shù)據(jù),只負(fù)責(zé)Coordination(接受用戶請求,發(fā)送到對應(yīng)replica,然后聚合返回客戶端)的node。當(dāng)然,Solr也可以通過AutoScalling配置某個(gè)節(jié)點(diǎn)不放任何replica來達(dá)到Coordination node的效果,不過這個(gè)配置就復(fù)雜的多了。ElasticSearch自動(dòng)運(yùn)維能力比較強(qiáng),通過簡單配置,就可以實(shí)現(xiàn)集群的自動(dòng)balance等運(yùn)維操作。當(dāng)節(jié)點(diǎn)宕機(jī)時(shí),master node也會提升從replica為主,并增加一個(gè)replica來保持replica可用數(shù)。這些都是ElasticSearch的默認(rèn)行為,而在Solr中,則需要自己去定義AutoScalling的框架,來配置這些行為。


        • Solr能夠深度定制而ElasticSearch更重于開箱即用

        最近我solr和ElasticSearch的兩個(gè)客戶端都使用過,給我的感覺是ElasticSearch更加簡單易用。有很多的功能ElasticSearch都已經(jīng)內(nèi)置,不要通過配置去定義。舉個(gè)例子來說,在Solr中我要想定義一個(gè)名字為name,類型為string的field,我需要在managed_schema(xml)中配置兩個(gè)東西:


        <fieldType name="string" class="solr.StrField" sortMissingLast="true" docValues="true" /><field name="name" type="string" indexed="true" stored="true" required="true" multiValued="false" />


        也就是說,Solr預(yù)設(shè)的字段類型仍然需要自己去定義使用Solr中的那個(gè)類,比如上面的第一行定義了string這個(gè)類型使用了solr.StrField這個(gè)類。然后我才能指定id field的type為string。如果我想惡作劇把string定義為solr.IntPointField(int類型)來迷惑大家可以嗎?當(dāng)然可以。而在ElasticSearch中,各種類型都已經(jīng)預(yù)定義好,我們只需要一個(gè)json的mapping來指定field的類型就好(keyword即不分詞的string)。


        PUT my_index{  "mappings": {    "properties": {      "name": {        "type":  "keyword"      }    }  }}


        Solr的配置感覺上更加Geek,因?yàn)樗话愣际侵苯优渲胘ava類。而ElasticSearch包裝更好,各種類型都已經(jīng)預(yù)制好。Solr的讀寫鏈路都可以深度定制,你可以在讀寫鏈路上增加各種Processor和Component來添加各種不同的功能。你甚至可以定義處理你請求的handler類。


        <searchComponent name="terms" class="solr.TermsComponent"/>
        <requestHandler name="/terms" class="solr.SearchHandler" startup="lazy"> <lst name="defaults"> <bool name="terms">true</bool> <bool name="distrib">false</bool> </lst> <arr name="components"> <str>terms</str> </arr> </requestHandler>


        比如上面定義"/terms"路徑將由solr.SearchHandler這個(gè)類來處理,同時(shí)在Search的component中加入了一個(gè)叫做solr.TermsComponent的組件。如果你愿意的話,你可以為每個(gè)Collection在訪問“/terms”這個(gè)路徑時(shí),提供完全不同的行為。

        再比如下面的配置可以定義一個(gè)文檔在寫入時(shí)需要經(jīng)過的Processor(如果熟悉HBase的話,你可以認(rèn)為就是HBase的Coprocessor)


        <updateRequestProcessorChain name="add-unknown-fields-to-the-schema" default="${update.autoCreateFields:true}"           processor="uuid,remove-blank,field-name-mutating,parse-boolean,parse-long,parse-double,parse-date,add-schema-fields">    <processor class="solr.LogUpdateProcessorFactory"/>    <processor class="solr.DistributedUpdateProcessorFactory"/>    <processor class="solr.RunUpdateProcessorFactory"/>  </updateRequestProcessorChain>


        Solr的整條讀寫鏈路都是通過這種配置文件定義的,定制化非常自由,以至于如果配置不好,會把正常的讀寫鏈路給配置沒掉。所以Solr在文檔中警告,如果你在使用的updateRequestProcessorChain中沒有配置RunUpdateProcessorFactory的話,寫入請求是不會真正被執(zhí)行的……

        而ElasticSearch很多功能都是開箱即用,并不需要用戶去配置。Solr的配置太過于靈活,給了用戶很多犯錯(cuò)誤的可能,而ElasticSearch的設(shè)計(jì)哲學(xué)是盡量減少用戶犯錯(cuò)的可能,ES對運(yùn)行環(huán)境還做了諸多限制,以避免運(yùn)行過程中出現(xiàn)一些莫名其妙的錯(cuò)誤,因?yàn)楹芏嘤脩舨⒉皇沁@些領(lǐng)域的專家,他們沒法從這些錯(cuò)誤中找到原因。比如說ElasticSearch在啟動(dòng)時(shí)會做memory check,系統(tǒng)是否限制了file descriptor數(shù)等等,甚至如果運(yùn)行的是某個(gè)有已知bug的JVM版本,ElasticSearch也會拒絕啟動(dòng)。ElasticSearch在啟動(dòng)時(shí)還會用JarHell去檢查加載的類里是否有同名類,我曾經(jīng)在自己的測試工程中集成了ElasticSearch想來啟動(dòng)一個(gè)本地的ES集群,著實(shí)被JarHell惡心了一把,在一個(gè)大的Java工程里,各種不同的依賴,不出現(xiàn)同名類確實(shí)太難?;税胩彀凑認(rèn)arHell的報(bào)錯(cuò)提示去exclude依賴之后終于放棄,JarHell檢查還不能被關(guān)閉,我只能fake了一個(gè)空的JarHell類繞過檢查??偠灾?,ES降低了使用門檻,同時(shí)還極力避免用戶犯錯(cuò),對新手友好。


        • Solr支持HDFS存儲而ElasticSearch不能

        Solr能夠支持HDFS做為存儲是Solr的一大特點(diǎn),on HDFS帶來了存儲計(jì)算分離的優(yōu)勢。比如說,在普通存儲上,move一個(gè)replica從一個(gè)節(jié)點(diǎn)到另外一個(gè)節(jié)點(diǎn)意味著大量的數(shù)據(jù)拷貝。而如果on HDFS的話,move一個(gè)replica并不需要移動(dòng)任何數(shù)據(jù),每個(gè)節(jié)點(diǎn)都可以讀到HDFS上的內(nèi)容,另外一個(gè)節(jié)點(diǎn)只需要打開HDFS上的數(shù)據(jù)即可。當(dāng)Solr on HDFS后,配上AutoScalling框架,其實(shí)只需要一個(gè)主replica即可(如果不是想分散讀壓力的話)。因?yàn)橐慌_node掛掉之后,Shard在另外一個(gè)節(jié)點(diǎn)快速上線,不需要拷貝數(shù)據(jù)。當(dāng)我要balance整個(gè)集群時(shí),整個(gè)過程也非???,因?yàn)橹挥羞壿嬌系膕hard在節(jié)點(diǎn)中流動(dòng),而數(shù)據(jù)在HDFS是不需要移動(dòng)的。在這個(gè)點(diǎn)上,ElasticSearch沒有on HDFS的能力,因此這些他都做不到。


        • Solr支持Shard split而ElasticSearch不能

        雖然說Solr/ES的shard是hash分片(根據(jù)doc id或者用戶自定義的field),天生就可以分散熱點(diǎn)。但是仍然可能存在某一些doc比較熱,需要分散熱點(diǎn)?;蛘哒f如果集群中加入一批新的機(jī)器,需要分更多的shard才能保證Collection能夠利用到集群中的每一臺。而Solr是支持Shard做split操作,能夠?qū)⒁粋€(gè)Shard分成多個(gè)。而ElasticSearch卻不可以做shard的split,如果一個(gè)Index想要更多的shard,只能新建一個(gè)擁有更多shard的index,然后將數(shù)據(jù)遷移過去。為什么ElasticSearch不能做這樣的操作?這是他們的路由策略決定的。Solr的分片定義了hash的范圍,split時(shí)可以將范圍分半,切分出兩個(gè)子shard來分別負(fù)責(zé)這兩段范圍。而ElasticSearch的路由是hash后再對shard取mod,來決定落在哪個(gè)shard上,這導(dǎo)致如果新加了shard,取mod就會亂掉。ElasticSearch的shard不能分裂以為這在做規(guī)劃時(shí)需要非常小心地預(yù)估自己的Index將來有多少數(shù)據(jù),需要多少個(gè)shard。一旦估算錯(cuò)誤,后期遷移需要大量拷貝數(shù)據(jù)。


        • ES支持功能和生態(tài)更為豐富

        ElasticSearch的功能豐富程度確實(shí)令人咋舌,畢竟后面有一家非常強(qiáng)大的商業(yè)公司。為了吸引客戶,什么事情都干得出來(褒義)。ELK套間在Log處理這塊已經(jīng)是業(yè)界通用的解決方案。同時(shí),Elastic公司還通過X-Pack給不同層級的用戶提供了尤為豐富的功能。而Solr背后雖然有一些商業(yè)化公司,比如LucidWorks,但總的來說還是沒有Elastic知名,提供的解決方案也比較有限。我在這里列舉一些ElasticSearch中比較優(yōu)秀的功能:

        1. 對JSON友好:支持nested field,天生和JSON契合,而Solr中只支持nested docment。

        2. 支持Index Sorting:我覺得這個(gè)是在排序場景下的殺手級功能。如果用戶的請求都會帶有某個(gè)field的排序條件,ElasticSearch可以在Segment中不是按doc ID排序,而是按照這個(gè)field排序。從而在查詢過程中,能夠掃描前n條就可以獲得快速獲得結(jié)果集,從而提前完成查詢。

        3. 支持Index的life cycle管理:例如超過多少天,自動(dòng)刪除Index,如果Index很hot,則增加replica?;蛘叨〞r(shí)對index做一個(gè)snapshot等等。

        4. 支持時(shí)序數(shù)據(jù)降精度:ElasticSearch針對時(shí)序數(shù)據(jù)領(lǐng)域的重磅功能。能夠支持配置rollup background job,對一些field數(shù)據(jù)做聚合,比如把小時(shí)數(shù)據(jù)聚合成天的存儲在另外field或者Index中。

        5. 支持觸發(fā)器:當(dāng)特定的條件滿足時(shí),可以做出一系列事件,比如curl一個(gè)網(wǎng)頁,從而實(shí)現(xiàn)類似數(shù)據(jù)庫觸發(fā)器的功能。


        總結(jié)

        總的來說,我感覺,ElasticSerach更像一個(gè)商業(yè)產(chǎn)品,而Solr更像一個(gè)軟件。Solr的定制能力更強(qiáng),幾乎什么都可以配置。對于開發(fā)者來說,要實(shí)現(xiàn)一個(gè)新的功能,可以不用動(dòng)Solr核心代碼,而給Solr增加一些Processer和Component,然后通過xml配置服務(wù)器的行為。同時(shí),Solr還提供了BlobStore,可以上傳Jar代碼來在Solr集群中部署這些新的插件(像不像HBase的Coprocessor?)。并且Solr獨(dú)家的On HDFS能力為Solr提供了存儲計(jì)算分離的便捷性,可以做到shard的自由移動(dòng)而不用搬遷數(shù)據(jù)。Solr還支持分裂shard,這些能力都對運(yùn)維友好,能夠在擴(kuò)容、宕機(jī)恢復(fù)方面會有更大的靈活性。而ElasticSearch竭盡全力地降低用戶的使用門檻,用戶可以非常快的上手。同時(shí)堅(jiān)持不引入像Zookeeper這樣的額外組件,也是為了降低部署難度。畢竟,ElasticSearch后面有一家強(qiáng)大的商業(yè)公司,從客戶需求出發(fā),在ElasticSearch上做了非常多豐富的功能,建立起了非常完整的生態(tài),并擁有眾多客戶案例。對于一般的客戶來說,一般會選擇一個(gè)大而全的產(chǎn)品去滿足他們的需求,因?yàn)樵诩夹g(shù)棧中引入一個(gè)新產(chǎn)品,本身學(xué)習(xí)成本和運(yùn)維成本都會比較大。而ElasticSearch更加地契合了這些用戶的需求,ElasticSearch入門簡單,不僅可以搜索,還可以分析,同時(shí)可以處理時(shí)序數(shù)據(jù),還在X-Pack中支持機(jī)器學(xué)習(xí)等等功能。我想,這也是目前ElasticSearch更火的原因吧。




        END


        后臺回復(fù)“面試” “資料” 領(lǐng)取一份干貨,數(shù)百技術(shù)面試手冊等你
        開發(fā)者技術(shù)前線 ,匯集技術(shù)前線快訊和關(guān)注行業(yè)趨勢,大廠干貨,是開發(fā)者經(jīng)歷和成長的優(yōu)秀指南。
        好文點(diǎn)個(gè)在看吧!


        瀏覽 107
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产九色91 回来了 | 日本人妻丰满熟妇久久久久久 | 亚洲欧美国产高清vA在线播放 | 俺去啦俺去也 | 成人豆花视频首页 | 五月天婷婷激情 | 国产精品草 | 91精品国产刺激国语对白 | 欧美巨乳波霸 | 丁香五月婷婷综合网 |