自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何提高ElasticSearch 索引速度

大數(shù)據(jù)
這篇文章會(huì)講述一些關(guān)于索引參數(shù)的原理,以及一些其他的思路。

[[171160]]

我Google了下,大致給出的答案如下:

  1. 使用bulk API
  2. 初次索引的時(shí)候,把 replica 設(shè)置為 0
  3. 增大 threadpool.index.queue_size
  4. 增大 indices.memory.index_buffer_size
  5. 增大 index.translog.flush_threshold_ops
  6. 增大 index.translog.sync_interval
  7. 增大 index.engine.robin.refresh_interval

這篇文章會(huì)講述上面幾個(gè)參數(shù)的原理,以及一些其他的思路。這些參數(shù)大體上是朝著兩個(gè)方向優(yōu)化的:

  • 減少磁盤(pán)寫(xiě)入
  • 增大構(gòu)建索引處理資源

一般而言,通過(guò)第二種方式的需要慎用,會(huì)對(duì)集群查詢功能造成比較大的影響。

這里還有兩種形態(tài)的解決方案:

  • 關(guān)閉一些特定場(chǎng)景并不需要的功能,比如Translog或者Version等
  • 將部分計(jì)算挪到其他并行計(jì)算框架上,比如數(shù)據(jù)的分片計(jì)算等,都可以放到Spark上事先算好

上面的參數(shù)都和什么有關(guān)

  • 其中 5,6 屬于 TransLog 相關(guān)。
  • 4 則和Lucene相關(guān)
  • 3 則因?yàn)镋S里大量采用線程池,構(gòu)建索引的時(shí)候,是有單獨(dú)的線程池做處理的
  • 7 的話個(gè)人認(rèn)為影響不大
  • 2 的話,能夠使用上的場(chǎng)景有限。個(gè)人認(rèn)為Replica這塊可以使用Kafka的ISR機(jī)制。所有數(shù)據(jù)還是都從Primary寫(xiě)和讀。Replica盡量只作為備份數(shù)據(jù)。

Translog

為什么要有Translog? 因?yàn)門(mén)ranslog順序?qū)懭罩颈葮?gòu)建索引更高效。我們不可能每加一條記錄就Commit一次,這樣會(huì)有大量的文件和磁盤(pán)IO產(chǎn)生。但是我們又想避免程序掛掉或者硬件故障而出現(xiàn)數(shù)據(jù)丟失,所以有了Translog,通常這種日志我們叫做Write Ahead Log。

為了保證數(shù)據(jù)的完整性,ES默認(rèn)是每次request結(jié)束后都會(huì)進(jìn)行一次sync操作。具體可以查看如下方法:

 

方法

 

該方法會(huì)調(diào)用IndexShard.sync 方法進(jìn)行文件落地。

你也可以通過(guò)設(shè)置index.translog.durability=async 來(lái)完成異步落地。這里的異步其實(shí)可能會(huì)有一點(diǎn)點(diǎn)誤導(dǎo)。前面是每次request結(jié)束后都會(huì)進(jìn)行sync,這里的sync僅僅是將Translog落地。而無(wú)論你是否設(shè)置了async,都會(huì)執(zhí)行如下操作:根據(jù)條件,主要是每隔sync_interval(5s) ,如果flush_threshold_ops(Integer.MAX_VALUE),flush_threshold_size(512m),flush_threshold_period(30m) 滿足對(duì)應(yīng)的條件,則進(jìn)行flush操作,這里除了對(duì)Translog進(jìn)行Commit以外,也對(duì)索引進(jìn)行了Commit。

所以如果你是海量的日志,可以容忍發(fā)生故障時(shí)丟失一定的數(shù)據(jù),那么完全可以設(shè)置,index.translog.durability=async,并且將前面提到的flush*相關(guān)的參數(shù)調(diào)大。

而極端情況,你還可以有兩個(gè)選擇:

  • 設(shè)置index.translog.durability=async,接著設(shè)置index.translog.disable_flush=true進(jìn)行禁用定時(shí)flush。然后你可以通過(guò)應(yīng)用程序自己手動(dòng)來(lái)控制flush。
  • 通過(guò)改寫(xiě)ES 去掉Translog日志相關(guān)的功能。

當(dāng)然,如果去掉Translog日志有兩個(gè)風(fēng)險(xiǎn)點(diǎn):

  • Get***數(shù)據(jù)會(huì)有點(diǎn)問(wèn)題。因?yàn)楦鶕?jù)ID Get***數(shù)據(jù)是從Translog里拿的。
  • 我們知道ES通過(guò)Shard Replication 保證Node節(jié)點(diǎn)出現(xiàn)故障時(shí)出現(xiàn)數(shù)據(jù)的完整性。在Relocating的時(shí)候,Replica 從Primary 進(jìn)行Recover時(shí),Primary會(huì)先Snapshot Lucene,然后拷貝數(shù)據(jù)到Replica,***通過(guò)回放Translog 保證數(shù)據(jù)的一致性。

Version

Version可以讓ES實(shí)現(xiàn)并發(fā)修改,但是帶來(lái)的性能影響也是極大的,這里主要有兩塊:

  • 需要訪問(wèn)索引里的版本號(hào),觸發(fā)磁盤(pán)讀寫(xiě)
  • 鎖機(jī)制

目前而言,似乎沒(méi)有辦法直接關(guān)閉Version機(jī)制。你可以使用自增長(zhǎng)ID并且在構(gòu)建索引時(shí),index 類型設(shè)置為create。這樣可以跳過(guò)版本檢查。

這個(gè)場(chǎng)景主要應(yīng)用于不可變?nèi)罩緦?dǎo)入,隨著ES被越來(lái)越多的用來(lái)做日志分析,日志沒(méi)有主鍵ID,所以使用自增ID是合適的,并且不會(huì)進(jìn)行更新,使用一個(gè)固定的版本號(hào)也是合適的。而不可變?nèi)罩就亲非笸掏铝俊?/p>

當(dāng)然,如果有必要,我們也可以通過(guò)改寫(xiě)ES相關(guān)代碼,禁用版本管理。

分發(fā)代理

ES是對(duì)索引進(jìn)行了分片(Shard),然后數(shù)據(jù)被分發(fā)到不同的Shard。這樣 查詢和構(gòu)建索引其實(shí)都存在一個(gè)問(wèn)題:

如果是構(gòu)建索引,則需要對(duì)數(shù)據(jù)分揀,然后根據(jù)Shard分布分發(fā)到不同的Node節(jié)點(diǎn)上。

如果是查詢,則對(duì)外提供的Node需要收集各個(gè)Shard的數(shù)據(jù)做Merge

這都會(huì)對(duì)對(duì)外提供的節(jié)點(diǎn)造成較大的壓力,從而影響整個(gè)bulk/query 的速度。

一個(gè)可行的方案是,直接面向客戶提供構(gòu)建索引和查詢API的Node節(jié)點(diǎn)都采用client模式,不存儲(chǔ)數(shù)據(jù),可以達(dá)到一定的優(yōu)化效果。

另外一個(gè)較為麻煩但似乎會(huì)更優(yōu)的解決方案是,如果你使用類似Spark Streaming這種流式處理程序,在***往ES輸出的時(shí)候,可以做如下幾件事情:

  • 獲取所有primary shard的信息,并且給所有shard帶上一個(gè)順序的數(shù)字序號(hào),得到partition(順序序號(hào)) -> shardId的映射關(guān)系
  • 對(duì)數(shù)據(jù)進(jìn)行repartition,分區(qū)后每個(gè)partition對(duì)應(yīng)一個(gè)shard的數(shù)據(jù)
  • 遍歷這些partions,寫(xiě)入ES。方法為直接通過(guò)RPC 方式,類似transportService.sendRequest 將數(shù)據(jù)批量發(fā)送到對(duì)應(yīng)包含有對(duì)應(yīng)ShardId的Node節(jié)點(diǎn)上。

這樣有三點(diǎn)好處:

  1. 所有的數(shù)據(jù)都被直接分到各個(gè)Node上直接處理。避免所有的數(shù)據(jù)先集中到一臺(tái)服務(wù)器
  2. 避免二次分發(fā),減少一次網(wǎng)絡(luò)IO
  3. 防止***處理數(shù)據(jù)的Node壓力太大而導(dǎo)致木桶短板效應(yīng)

場(chǎng)景

因?yàn)槲艺靡鋈罩痉治鲱惖膽?yīng)用,追求高吞吐量,這樣上面的三個(gè)優(yōu)化其實(shí)都可以做了。一個(gè)典型只增不更新的日志入庫(kù)操作,可以采用如下方案:

  1. 對(duì)接Spark Streaming,在Spark里對(duì)數(shù)據(jù)做好分片,直接推送到ES的各個(gè)節(jié)點(diǎn)
  2. 禁止自動(dòng)flush操作,每個(gè)batch 結(jié)束后手動(dòng)flush。
  3. 避免使用Version

我們可以預(yù)期ES會(huì)產(chǎn)生多少個(gè)新的Segment文件,通過(guò)控制batch的周期和大小,預(yù)判出ES Segment索引文件的生成大小和Merge情況。***可能減少ES的一些額外消耗

總結(jié)

大體是下面這三個(gè)點(diǎn)讓es比原生的lucene吞吐量下降了不少:

為了數(shù)據(jù)完整性 ES額外添加了WAL(tanslog)

為了能夠并發(fā)修改 添加了版本機(jī)制

對(duì)外提供服務(wù)的node節(jié)點(diǎn)存在瓶頸

ES的線性擴(kuò)展問(wèn)題主要受限于第三點(diǎn),

具體描述就是:

如果是構(gòu)建索引,接受到請(qǐng)求的Node節(jié)點(diǎn)需要對(duì)數(shù)據(jù)分揀,然后根據(jù)Shard分布分發(fā)到不同的Node節(jié)點(diǎn)上。

如果是查詢,則對(duì)外提供的Node需要收集各個(gè)Shard的數(shù)據(jù)做Merge

另外,索引的讀寫(xiě)并不需要向Master匯報(bào)。

責(zé)任編輯:趙寧寧 來(lái)源: 36大數(shù)據(jù)
相關(guān)推薦

2011-08-15 18:20:05

建立索引SQL Sever數(shù)據(jù)

2011-08-16 13:27:34

索引

2009-05-12 13:10:22

OracleMySQLSELECT

2024-06-27 11:00:07

2011-05-30 13:28:00

PHP

2011-08-10 15:11:23

SQL Server整理索引碎片重建索引

2024-03-01 09:57:19

數(shù)據(jù)庫(kù)檢索項(xiàng)目

2025-04-10 01:11:00

2020-09-28 15:34:38

ElasticSear索引MySQL

2020-10-20 06:41:59

Elasticsear日志

2022-04-27 09:24:22

前端代碼速度

2011-07-04 17:45:45

Qt Sqlite 數(shù)據(jù)庫(kù)

2009-10-16 08:48:08

2011-05-19 11:33:38

數(shù)據(jù)庫(kù)訪問(wèn)速度

2019-09-24 09:25:05

Vue項(xiàng)目加載

2024-08-07 15:40:59

2010-01-06 16:55:33

Web交換機(jī)

2024-03-11 15:47:11

RustPython代碼

2024-09-27 11:46:51

2011-05-30 13:15:05

PHP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)