Elasticsearch 架構(gòu)以及源碼概覽

Elasticsearch 架構(gòu)以及源碼概覽

Elasticsearch是最近兩年異軍突起的一個兼有搜索引擎和NoSQL數(shù)據(jù)庫功能的開源系統(tǒng)句惯,基于Java/Lucene構(gòu)建玲销。最近研究了一下输拇,感覺 Elasticsearch 的架構(gòu)以及其開源的生態(tài)構(gòu)建都有許多可借鑒之處,所以整理成文章分享下贤斜。本文的代碼以及架構(gòu)分析主要基于 Elasticsearch 2.X 最新穩(wěn)定版策吠。

Elasticsearch 看名字就能大概了解下它是一個彈性的搜索引擎。首先彈性隱含的意思是分布式瘩绒,單機系統(tǒng)是沒法彈起來的猴抹,然后加上靈活的伸縮機制,就是這里的 Elastic 包含的意思锁荔。它的搜索存儲功能主要是 Lucene 提供的洽糟,Lucene 相當(dāng)于其存儲引擎,它在之上封裝了索引堕战,查詢坤溃,以及分布式相關(guān)的接口。

Elasticsearch 中的幾個概念

集群(Cluster)一組擁有共同的 cluster name 的節(jié)點嘱丢。

節(jié)點(Node) 集群中的一個 Elasticearch 實例薪介。

索引(Index) 相當(dāng)于關(guān)系數(shù)據(jù)庫中的database概念,一個集群中可以包含多個索引越驻。這個是個邏輯概念汁政。

主分片(Primary shard) 索引的子集,索引可以切分成多個分片缀旁,分布到不同的集群節(jié)點上记劈。分片對應(yīng)的是 Lucene 中的索引。

副本分片(Replica shard)每個主分片可以有一個或者多個副本并巍。

類型(Type)相當(dāng)于數(shù)據(jù)庫中的table概念目木,mapping是針對 Type 的。同一個索引里可以包含多個 Type懊渡。

Mapping 相當(dāng)于數(shù)據(jù)庫中的schema刽射,用來約束字段的類型,不過 Elasticsearch 的 mapping 可以自動根據(jù)數(shù)據(jù)創(chuàng)建剃执。

文檔(Document) 相當(dāng)于數(shù)據(jù)庫中的row誓禁。

字段(Field)相當(dāng)于數(shù)據(jù)庫中的column。

分配(Allocation) 將分片分配給某個節(jié)點的過程肾档,包括分配主分片或者副本摹恰。如果是副本辫继,還包含從主分片復(fù)制數(shù)據(jù)的過程。

分布式以及 Elastic

分布式系統(tǒng)要解決的第一個問題就是節(jié)點之間互相發(fā)現(xiàn)以及選主的機制俗慈。如果使用了 Zookeeper/Etcd 這樣的成熟的服務(wù)發(fā)現(xiàn)工具骇两,這兩個問題都一并解決了。但 Elasticsearch 并沒有依賴這樣的工具姜盈,帶來的好處是部署服務(wù)的成本和復(fù)雜度降低了低千,不用預(yù)先依賴一個服務(wù)發(fā)現(xiàn)的集群,缺點當(dāng)然是將復(fù)雜度帶入了 Elasticsearch 內(nèi)部馏颂。

服務(wù)發(fā)現(xiàn)以及選主 ZenDiscovery

節(jié)點啟動后先ping(這里的ping是 Elasticsearch 的一個RPC命令示血。如果 discovery.zen.ping.unicast.hosts 有設(shè)置,則ping設(shè)置中的host,否則嘗試ping localhost 的幾個端口, Elasticsearch 支持同一個主機啟動多個節(jié)點)

Ping的response會包含該節(jié)點的基本信息以及該節(jié)點認(rèn)為的master節(jié)點椒惨。

選舉開始丸升,先從各節(jié)點認(rèn)為的master中選袜刷,規(guī)則很簡單,按照id的字典序排序,取第一個。

如果各節(jié)點都沒有認(rèn)為的master黔姜,則從所有節(jié)點中選擇,規(guī)則同上蒂萎。這里有個限制條件就是 discovery.zen.minimum_master_nodes秆吵,如果節(jié)點數(shù)達(dá)不到最小值的限制,則循環(huán)上述過程五慈,直到節(jié)點數(shù)足夠可以開始選舉纳寂。

最后選舉結(jié)果是肯定能選舉出一個master,如果只有一個local節(jié)點那就選出的是自己泻拦。

如果當(dāng)前節(jié)點是master毙芜,則開始等待節(jié)點數(shù)達(dá)到 minimum_master_nodes,然后提供服務(wù)争拐。

如果當(dāng)前節(jié)點不是master腋粥,則嘗試加入master。

Elasticsearch 將以上服務(wù)發(fā)現(xiàn)以及選主的流程叫做 ZenDiscovery 陆错。由于它支持任意數(shù)目的集群(1-N),所以不能像 Zookeeper/Etcd 那樣限制節(jié)點必須是奇數(shù)灯抛,也就無法用投票的機制來選主,而是通過一個規(guī)則音瓷,只要所有的節(jié)點都遵循同樣的規(guī)則,得到的信息都是對等的夹抗,選出來的主節(jié)點肯定是一致的绳慎。但分布式系統(tǒng)的問題就出在信息不對等的情況,這時候很容易出現(xiàn)腦裂(Split-Brain)的問題,大多數(shù)解決方案就是設(shè)置一個quorum值杏愤,要求可用節(jié)點必須大于quorum(一般是超過半數(shù)節(jié)點)靡砌,才能對外提供服務(wù)。而 Elasticsearch 中珊楼,這個quorum的配置就是 discovery.zen.minimum_master_nodes 通殃。 說到這里要吐槽下 Elasticsearch 的方法和變量命名,它的方法和配置中的master指的是master的候選節(jié)點厕宗,也就是說可能成為master的節(jié)點画舌,并不是表示當(dāng)前的master,我就被它的一個 isMasterNode 方法坑了已慢,開始一直沒能理解它的選舉規(guī)則曲聂。

彈性伸縮 Elastic

Elasticsearch 的彈性體現(xiàn)在兩個方面:

1. 服務(wù)發(fā)現(xiàn)機制讓節(jié)點很容易加入和退出。

2. 豐富的設(shè)置以及allocation API佑惠。

Elasticsearch 節(jié)點啟動的時候只需要配置discovery.zen.ping.unicast.hosts朋腋,這里不需要列舉集群中所有的節(jié)點,只要知道其中一個即可膜楷。當(dāng)然為了避免重啟集群時正好配置的節(jié)點掛掉旭咽,最好多配置幾個節(jié)點。節(jié)點退出時只需要調(diào)用 API 將該節(jié)點從集群中排除 (Shard Allocation Filtering)赌厅,系統(tǒng)會自動遷移該節(jié)點上的數(shù)據(jù)轻专,然后關(guān)閉該節(jié)點即可。當(dāng)然最好也將不可用的已知節(jié)點從其他節(jié)點的配置中去除察蹲,避免下次啟動時出錯请垛。

分片(Shard)以及副本(Replica)分布式存儲系統(tǒng)為了解決單機容量以及容災(zāi)的問題,都需要有分片以及副本機制洽议。Elasticsearch 沒有采用節(jié)點級別的主從復(fù)制宗收,而是基于分片。它當(dāng)前還未提供分片切分(shard-splitting)的機制亚兄,只能創(chuàng)建索引的時候靜態(tài)設(shè)置混稽。

(elasticsearch 官方博客的圖片)

比如上圖所示,開始設(shè)置為5個分片审胚,在單個節(jié)點上匈勋,后來擴容到5個節(jié)點,每個節(jié)點有一個分片膳叨。如果繼續(xù)擴容洽洁,是不能自動切分進(jìn)行數(shù)據(jù)遷移的。官方文檔的說法是分片切分成本和重新索引的成本差不多菲嘴,所以建議干脆通過接口重新索引饿自。

Elasticsearch 的分片默認(rèn)是基于id 哈希的汰翠,id可以用戶指定,也可以自動生成昭雌。但這個可以通過參數(shù)(routing)或者在mapping配置中修改复唤。當(dāng)前版本默認(rèn)的哈希算法是MurmurHash3。

Elasticsearch 禁止同一個分片的主分片和副本分片在同一個節(jié)點上烛卧,所以如果是一個節(jié)點的集群是不能有副本的佛纫。

恢復(fù)以及容災(zāi)

分布式系統(tǒng)的一個要求就是要保證高可用。前面描述的退出流程是節(jié)點主動退出的場景总放,但如果是故障導(dǎo)致節(jié)點掛掉呈宇,Elasticsearch 就會主動allocation。但如果節(jié)點丟失后立刻allocation间聊,稍后節(jié)點恢復(fù)又立刻加入攒盈,會造成浪費。Elasticsearch的恢復(fù)流程大致如下:

集群中的某個節(jié)點丟失網(wǎng)絡(luò)連接

master提升該節(jié)點上的所有主分片的在其他節(jié)點上的副本為主分片

cluster集群狀態(tài)變?yōu)?yellow ,因為副本數(shù)不夠

等待一個超時設(shè)置的時間哎榴,如果丟失節(jié)點回來就可以立即恢復(fù)(默認(rèn)為1分鐘型豁,通過 index.unassigned.node_left.delayed_timeout 設(shè)置)。如果該分片已經(jīng)有寫入尚蝌,則通過translog進(jìn)行增量同步數(shù)據(jù)迎变。

否則將副本分配給其他節(jié)點,開始同步數(shù)據(jù)飘言。

但如果該節(jié)點上的分片沒有副本衣形,則無法恢復(fù),集群狀態(tài)會變?yōu)閞ed姿鸿,表示可能要丟失該分片的數(shù)據(jù)了谆吴。

分布式集群的另外一個問題就是集群整個重啟后可能導(dǎo)致不預(yù)期的分片重新分配(部分節(jié)點沒有啟動完成的時候,集群以為節(jié)點丟失)苛预,浪費帶寬句狼。所以 Elasticsearch 通過以下靜態(tài)配置(不能通過API修改)控制整個流程,以10個節(jié)點的集群為例:

gateway.recover_after_nodes: 8

gateway.expected_nodes: 10

gateway.recover_after_time: 5m

比如10個節(jié)點的集群热某,按照上面的規(guī)則配置腻菇,當(dāng)集群重啟后,首先系統(tǒng)等待 minimum_master_nodes(6)個節(jié)點加入才會選出master昔馋, recovery操作是在 master節(jié)點上進(jìn)行的筹吐,由于我們設(shè)置了 recover_after_nodes(8),系統(tǒng)會繼續(xù)等待到8個節(jié)點加入秘遏, 才開始進(jìn)行recovery丘薛。當(dāng)開始recovery的時候,如果發(fā)現(xiàn)集群中的節(jié)點數(shù)小于expected_nodes垄提,也就是還有部分節(jié)點未加入榔袋,于是開始recover_after_time 倒計時(如果節(jié)點數(shù)達(dá)到expected_nodes則立刻進(jìn)行 recovery)周拐,5分鐘后铡俐,如果剩余的節(jié)點依然沒有加入凰兑,則會進(jìn)行數(shù)據(jù)recovery。

搜索引擎 Search

Elasticsearch 除了支持 Lucene 本身的檢索功能外审丘,在之上做了一些擴展吏够。

1. 腳本支持

Elasticsearch 默認(rèn)支持groovy腳本,擴展了 Lucene 的評分機制滩报,可以很容易的支持復(fù)雜的自定義評分算法锅知。它默認(rèn)只支持通過sandbox方式實現(xiàn)的腳本語言(如lucene expression,mustache)脓钾,groovy必須明確設(shè)置后才能開啟售睹。Groovy的安全機制是通過java.security.AccessControlContext設(shè)置了一個class白名單來控制權(quán)限的,1.x版本的時候是自己做的一個白名單過濾器可训,但限制策略有漏洞昌妹,導(dǎo)致一個遠(yuǎn)程代碼執(zhí)行漏洞。 2. 默認(rèn)會生成一個 _all 字段握截,將所有其他字段的值拼接在一起飞崖。這樣搜索時可以不指定字段,并且方便實現(xiàn)跨字段的檢索谨胞。 3. Suggester Elasticsearch 通過擴展的索引機制固歪,可以實現(xiàn)像google那樣的自動完成suggestion以及搜索詞語錯誤糾正的suggestion。

NoSQL 數(shù)據(jù)庫

Elasticsearch 可以作為數(shù)據(jù)庫使用胯努,主要依賴于它的以下特性:

1. 默認(rèn)在索引中保存原始數(shù)據(jù)牢裳,并可獲取。這個主要依賴 Lucene 的store功能叶沛。

2. 實現(xiàn)了translog蒲讯,提供了實時的數(shù)據(jù)讀取能力以及完備的數(shù)據(jù)持久化能力(在服務(wù)器異常掛掉的情況下依然不會丟數(shù)據(jù))。Lucene 因為有 IndexWriter buffer, 如果進(jìn)程異常掛掉恬汁,buffer中的數(shù)據(jù)是會丟失的伶椿。所以 Elasticsearch 通過translog來確保不丟數(shù)據(jù)。同時通過id直接讀取文檔的時候氓侧,Elasticsearch 會先嘗試從translog中讀取脊另,之后才從索引中讀取。也就是說约巷,即便是buffer中的數(shù)據(jù)尚未刷新到索引偎痛,依然能提供實時的數(shù)據(jù)讀取能力。Elasticsearch 的translog 默認(rèn)是每次寫請求完成后統(tǒng)一fsync一次独郎,同時有個定時任務(wù)檢測(默認(rèn)5秒鐘一次)踩麦。如果業(yè)務(wù)場景需要更大的寫吞吐量枚赡,可以調(diào)整translog相關(guān)的配置進(jìn)行優(yōu)化。

3. dynamic-mapping?以及 schema-free

Elasticsearch 的dynamic-mapping相當(dāng)于根據(jù)用戶提交的數(shù)據(jù)谓谦,動態(tài)檢測字段類型贫橙,自動給數(shù)據(jù)庫表建立表結(jié)構(gòu),也可以動態(tài)增加字段反粥,所以它叫做schema-free卢肃,而不是schema-less。這種方式的好處是用戶能一定程度享受schema-less的好處才顿,不用提前建立表結(jié)構(gòu)莫湘,同時因為實際上是有schema的,可以做查詢上的優(yōu)化郑气,檢索效率要比純schema-less的數(shù)據(jù)庫高許多幅垮。但缺點就是已經(jīng)創(chuàng)建的索引不能變更數(shù)據(jù)類型(Elasticsearch 寫入數(shù)據(jù)的時候如果類型不匹配會自動嘗試做類型轉(zhuǎn)換,如果失敗就會報錯尾组,比如數(shù)字類型的字段寫入字符串”123”是可以的忙芒,但寫入”abc”就不可以。)演怎,要損失一定的自由度匕争。

另外 Elasticsearch 提供的index-template功能方便用戶動態(tài)創(chuàng)建索引的時候預(yù)先設(shè)定索引的相關(guān)參數(shù)以及type mapping,比如按天創(chuàng)建日志庫爷耀,template可以設(shè)置為對 log-* 的索引都生效甘桑。這兩個功能我建議新的數(shù)據(jù)庫都可以借鑒下。

4. 豐富的QueryDSL功能

Elasticsearch 的query語法基本上和sql對等的歹叮,除了join查詢跑杭,以及嵌套臨時表查詢不能支持。不過 Elasticsearch 支持嵌套對象以及parent外部引用查詢咆耿,所以一定程度上可以解決關(guān)聯(lián)查詢的需求德谅。另外group by這種查詢可以通過其aggregation實現(xiàn)。Elasticsearch 提供的aggregation能力非常強大萨螺,其生態(tài)圈里的 Kibana 主要就是依賴aggregation來實現(xiàn)數(shù)據(jù)分析以及可視化的窄做。

系統(tǒng)架構(gòu)

Elasticsearch 的依賴注入用的是guice,網(wǎng)絡(luò)使用netty慰技,提供http rest和RPC兩種協(xié)議椭盏。

Elasticsearch 之所以用guice,而不是用spring做依賴注入吻商,關(guān)鍵的一個原因是guice可以幫它很容易的實現(xiàn)模塊化掏颊,通過代碼進(jìn)行模塊組裝,可以很精確的控制依賴注入的管理范圍。比如 Elasticsearch 給每個shard單獨生成一個injector乌叶,可以將該shard相關(guān)的配置以及組件注入進(jìn)去盆偿,降低編碼和狀態(tài)管理的復(fù)雜度,同時刪除shard的時候也方便回收相關(guān)對象准浴。這方面有興趣使用guice的可以借鑒事扭。

ClusterState

前面我們分析了 Elasticsearch 的服務(wù)發(fā)現(xiàn)以及選舉機制,它是內(nèi)部自己實現(xiàn)的兄裂。服務(wù)發(fā)現(xiàn)工具做的事情其實就是跨服務(wù)器的狀態(tài)同步句旱,多個節(jié)點修改同一個數(shù)據(jù)對象阳藻,需要有一種機制將這個數(shù)據(jù)對象同步到所有的節(jié)點晰奖。Elasticsearch 的ClusterState 就是這樣一個數(shù)據(jù)對象,保存了集群的狀態(tài)腥泥,索引/分片的路由表匾南,節(jié)點列表,元數(shù)據(jù)等蛔外,還包含一個ClusterBlocks蛆楞,相當(dāng)于分布式鎖,用于實現(xiàn)分布式的任務(wù)同步夹厌。

主節(jié)點上有個單獨的進(jìn)程處理 ClusterState 的變更操作豹爹,每次變更會更新版本號。變更后會通過PRC接口同步到其他節(jié)點矛纹。主節(jié)知道其他節(jié)點的ClusterState 的當(dāng)前版本臂聋,發(fā)送變更的時候會做diff,實現(xiàn)增量更新或南。

Rest 和 RPC

Elasticsearch 的rest請求的傳遞流程如上圖(這里對實際流程做了簡化): 1. 用戶發(fā)起http請求孩等,Elasticsearch 的9200端口接受請求后,傳遞給對應(yīng)的RestAction采够。 2. RestAction做的事情很簡單肄方,將rest請求轉(zhuǎn)換為RPC的TransportRequest,然后調(diào)用NodeClient蹬癌,相當(dāng)于用客戶端的方式請求RPC服務(wù)权她,只不過transport層會對本節(jié)點的請求特殊處理。

這樣做的好處是將http和RPC兩層隔離逝薪,增加部署的靈活性隅要。部署的時候既可以同時開啟RPC和http服務(wù),也可以用client模式部署一組服務(wù)專門提供http rest服務(wù)翼闽,另外一組只開啟RPC服務(wù)拾徙,專門做data節(jié)點,便于分擔(dān)壓力感局。

Elasticsearch 的RPC的序列化機制使用了 Lucene 的壓縮數(shù)據(jù)類型尼啡,支持vint這樣的變長數(shù)字類型暂衡,省略了字段名,用流式方式按順序?qū)懭胱侄蔚闹笛虏t。每個需要傳輸?shù)膶ο蠖夹枰獙崿F(xiàn):

void writeTo(StreamOutput out)

T readFrom(StreamInput in)

兩個方法狂巢。雖然這樣實現(xiàn)開發(fā)成本略高,增刪字段也不太靈活书聚,但對 Elasticsearch 這樣的數(shù)據(jù)庫系統(tǒng)來說唧领,不用考慮跨語言,增刪字段肯定要考慮兼容性雌续,這樣做效率最高斩个。所以 Elasticsearch 的RPC接口只有java client可以直接請求,其他語言的客戶端都走的是rest接口驯杜。

網(wǎng)絡(luò)層Elasticsearch 的網(wǎng)絡(luò)層抽象很值得借鑒受啥。它抽象出一個 Transport 層,同時兼有client和server功能鸽心,server端接收其他節(jié)點的連接滚局,client維持和其他節(jié)點的連接,承擔(dān)了節(jié)點之間請求轉(zhuǎn)發(fā)的功能顽频。Elasticsearch 為了避免傳輸流量比較大的操作堵塞連接藤肢,所以會按照優(yōu)先級創(chuàng)建多個連接,稱為channel糯景。

recovery: 2個channel專門用做恢復(fù)數(shù)據(jù)嘁圈。如果為了避免恢復(fù)數(shù)據(jù)時將帶寬占滿,還可以設(shè)置恢復(fù)數(shù)據(jù)時的網(wǎng)絡(luò)傳輸速度莺奸。

bulk: 3個channel用來傳輸批量請求等基本比較低的請求丑孩。

regular: 6個channel用來傳輸通用正常的請求,中等級別灭贷。

state: 1個channel保留給集群狀態(tài)相關(guān)的操作温学,比如集群狀態(tài)變更的傳輸,高級別甚疟。

ping: 1個channel專門用來ping仗岖,進(jìn)行故障檢測。

(3個節(jié)點的集群連接示意览妖,來源 Elasticsearch 官方博客)

每個節(jié)點默認(rèn)都會創(chuàng)建13個到其他節(jié)點的連接轧拄,并且節(jié)點之間是互相連接的,每增加一個節(jié)點讽膏,該節(jié)點會到每個節(jié)點創(chuàng)建13個連接檩电,而其他每個節(jié)點也會創(chuàng)建13個連回來的連接。

線程池由于java不支持綠色線程(fiber/coroutine),我前面的《并發(fā)之痛》那篇文章也分析了線程池的問題俐末,線程池里保留多少線程合適料按?如何避免慢的任務(wù)占用線程池,導(dǎo)致其他比較快的任務(wù)也得不到執(zhí)行卓箫?很多應(yīng)用系統(tǒng)里载矿,為了避免這種情況,會隨手創(chuàng)建線程池烹卒,最后導(dǎo)致系統(tǒng)里充塞了大的量的線程池闷盔,浪費資源。而 Elasticsearch 的解決方案是分優(yōu)先級的線程池旅急。它默認(rèn)創(chuàng)建了10多個線程池逢勾,按照不同的優(yōu)先級以及不同的操作進(jìn)行劃分。然后提供了4種類型的線程池坠非,不同的線程池使用不同的類型:

CACHED 最小為0敏沉,無上限,無隊列(SynchronousQueue炎码,沒有緩沖buffer),有存活時間檢測的線程池秋泳。通用的潦闲,希望能盡可能支撐的任務(wù)。

DIRECT 直接在調(diào)用者的線程里執(zhí)行迫皱,其實這不算一種線程池方案歉闰,主要是為了代碼邏輯上的統(tǒng)一而創(chuàng)造的一種線程類型。

FIXED 固定大小的線程池卓起,帶有緩沖隊列和敬。用于計算和IO的耗時波動較小的操作。

SCALING 有最小值戏阅,最大值的伸縮線程池昼弟,隊列是基于LinkedTransferQueue 改造的實現(xiàn),和java內(nèi)置的Executors生成的伸縮線程池的區(qū)別是優(yōu)先增加線程奕筐,增加到最大值后才會使用隊列舱痘,和java內(nèi)置的線程池規(guī)則相反。用于計算和IO耗時都不太穩(wěn)定离赫,需要限制系統(tǒng)承載最大任務(wù)上限的操作芭逝。

這種解決方案雖然要求每個用到線程池的地方都需要評估下執(zhí)行成本以及應(yīng)該用什么樣的線程池,但好處是限制了線程池的泛濫渊胸,也緩解了不同類型的任務(wù)互相之間的影響旬盯。

腦洞時間

以后每篇分析架構(gòu)的文章,我都最后會提幾個和該系統(tǒng)相關(guān)的改進(jìn)或者擴展的想法,稱為腦洞時間胖翰,作為一種鍛煉频丘。不過只提供想法,不深入分析可行性以及實現(xiàn)泡态。

支持shard-spliting

這個被人吐糟了好長時間搂漠,官方就是不愿意提供。我簡單構(gòu)想了下某弦,感覺實現(xiàn)這個應(yīng)該也不復(fù)雜桐汤。一種實現(xiàn)方式是按照傳統(tǒng)的數(shù)據(jù)庫sharding機制,1分2靶壮,2分4怔毛,4分8等,主要擴展點在數(shù)據(jù)遷移以及routing的機制上腾降。但這種方式?jīng)]辦法實現(xiàn)1分3拣度,3分5,這樣的sharding螃壤。另外一個辦法就是基于當(dāng)前官方推薦的重建索引的機制抗果,只是對外封裝成resharding的接口,先給舊索引創(chuàng)建別名奸晴,客戶端通過別名訪問索引冤馏,然后設(shè)定新索引的sharding數(shù)目,后臺創(chuàng)建新的索引寄啼,倒數(shù)據(jù)逮光,等數(shù)據(jù)追上的時候,切換別名墩划,進(jìn)行完整性檢查涕刚,這樣整個resharding的機制可以自動化了。

支持mapreduce

認(rèn)為Elasticsearch 可以借鑒 Mongo 的輕量mapreduce機制乙帮,這樣可以支持更豐富的聚合查詢杜漠。

支持語音以及圖片檢索

當(dāng)前做語音和圖片識別的庫或者服務(wù)的開發(fā)者可以提供一個 Elasticsearch 插件,把語音以及圖片轉(zhuǎn)換成文本進(jìn)行索引查詢蚣旱,應(yīng)用場景應(yīng)該也不少碑幅。

用ForkJoinPool來替代 Elasticsearch 當(dāng)前的線程池方案

ForkJoinPool加上java8的CompletableFuture,一定程度上可以模擬coroutine效果塞绿,再加上最新版本的netty內(nèi)部已經(jīng)默認(rèn)用了ForkJoinPool沟涨,Elasticsearch 這種任務(wù)有需要拆子任務(wù)的場景,很適合使用ForkJoinPool异吻。

Elasticsearch 的開源產(chǎn)品啟示

還記得10年前在大學(xué)時候搗鼓 Lucene裹赴,弄校園內(nèi)搜索喜庞,還弄了個基于詞典的分詞工具。畢業(yè)后第一份工作也是用 Lucene 做站內(nèi)搜索棋返。當(dāng)時搭建的服務(wù)和 Elasticsearch 類似延都,提供更新和管理索引的api給業(yè)務(wù)程序,當(dāng)然沒有 Elasticsearch 這么強大睛竣。當(dāng)時是有想過做類似的一個開源產(chǎn)品的晰房,后來發(fā)現(xiàn)apache已經(jīng)出了 Solr(2004年的時候就創(chuàng)建了,2008年1.3發(fā)布射沟,已經(jīng)相對成熟)殊者,感覺應(yīng)該沒啥機會了。但 Elasticsearch 硬是在這種情況下成長起來了(10年創(chuàng)建验夯,14年才發(fā)布1.0)猖吴。 二者的功能以及性能幾乎都不相上下(開始性能上有些差距,但 Solr 有改進(jìn)挥转,差不多追上了)海蔽,參看文末比較鏈接。

我覺得一方面是 Elasticsearch 的簡單友好的分布式機制占了先機绑谣,也正好趕上了移動互聯(lián)網(wǎng)爆發(fā)移動應(yīng)用站內(nèi)搜索需求高漲的時代党窜。第一波站內(nèi)搜索是web時代,也是 Lucene 誕生的時代域仇,但web的站內(nèi)搜索可以簡單的利用搜索引擎服務(wù)的自定義站點實現(xiàn)刑然,而應(yīng)用的站內(nèi)搜索就只能靠自己搭了。另外一方面是 Elasticsearch 的周邊生態(tài)以及目標(biāo)市場看把握的非常精準(zhǔn)暇务。Elasticsearch 現(xiàn)在的主要目標(biāo)市場已經(jīng)從站內(nèi)搜索轉(zhuǎn)移到了監(jiān)控與日志數(shù)據(jù)的收集存儲和分析,也就是大家常談?wù)摰腅LK怔软。

Elasticsearch 現(xiàn)在主要的應(yīng)用場景有三塊垦细。站內(nèi)搜索,主要和 Solr 競爭挡逼,屬于后起之秀括改。NoSQL json文檔數(shù)據(jù)庫,主要搶占 Mongo 的市場家坎,它在讀寫性能上優(yōu)于 Mongo(見文末比較鏈接)嘱能,同時也支持地理位置查詢,還方便地理位置和文本混合查詢虱疏,屬于歪打正著惹骂。監(jiān)控,統(tǒng)計以及日志類時間序的數(shù)據(jù)的存儲和分析以及可視化做瞪,這方面是引領(lǐng)者对粪。

據(jù)說 Elasticsearch 的創(chuàng)始人當(dāng)初創(chuàng)建 Elasticsearch 的時候是為了給喜歡做菜的媳婦搭建個菜譜的搜索網(wǎng)站右冻,雖然菜譜搜索網(wǎng)站最后一直沒做出來,但誕生了 Elasticsearch著拭。所以程序員堅持一個業(yè)余項目也是很重要的纱扭,萬一無心插柳就成蔭了呢?

相關(guān)閱讀

solr vs elasticsearch 功能比較

elasticsearch vs solr 性能比較

Shard Allocation Filtering

MurmurHash3

Elasitcsearch 重新索引接口

MongoDB vs. Elasticsearch: The Quest of the Holy Performances

Elasticsearch 早期版本的遠(yuǎn)程代碼執(zhí)行漏洞

(微信不支持外鏈接儡遮,請點擊原文查看)

題圖來源:Qingcloud 公司設(shè)計師 Bink 作品乳蛾,最后打個小廣告,本人開發(fā)的 Qingcloud 的 Elasticsearch 服務(wù)上周已經(jīng)上線鄙币,歡迎試用肃叶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市爱榔,隨后出現(xiàn)的幾起案子被环,更是在濱河造成了極大的恐慌,老刑警劉巖详幽,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筛欢,死亡現(xiàn)場離奇詭異,居然都是意外死亡唇聘,警方通過查閱死者的電腦和手機版姑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迟郎,“玉大人剥险,你說我怎么就攤上這事∠苄ぃ” “怎么了表制?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長控乾。 經(jīng)常有香客問我么介,道長,這世上最難降的妖魔是什么蜕衡? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任壤短,我火速辦了婚禮,結(jié)果婚禮上慨仿,老公的妹妹穿的比我還像新娘久脯。我一直安慰自己,他們只是感情好镰吆,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布帘撰。 她就那樣靜靜地躺著,像睡著了一般鼎姊。 火紅的嫁衣襯著肌膚如雪骡和。 梳的紋絲不亂的頭發(fā)上相赁,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機與錄音慰于,去河邊找鬼钮科。 笑死,一個胖子當(dāng)著我的面吹牛婆赠,可吹牛的內(nèi)容都是我干的绵脯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼休里,長吁一口氣:“原來是場噩夢啊……” “哼蛆挫!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妙黍,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悴侵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拭嫁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體可免,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年做粤,在試婚紗的時候發(fā)現(xiàn)自己被綠了浇借。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡怕品,死狀恐怖妇垢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肉康,我是刑警寧澤闯估,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站吼和,受9級特大地震影響睬愤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纹安,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望砂豌。 院中可真熱鬧厢岂,春花似錦、人聲如沸阳距。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽筐摘。三九已至卒茬,卻和暖如春船老,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背圃酵。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工柳畔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人郭赐。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓薪韩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捌锭。 傳聞我的和親對象是個殘疾皇子俘陷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容