ELK 設置定時清理腳本清理索引
873
2025-03-31
寫在前面
從初次了解elastic產品到正式投入使用,拖拖拉拉的也有小半年了,剛接觸的時候看到一些帖子都是安裝教程,后來看到一些都是深入教程,此篇文章較居中一點,總結了我在踩的一些坑和記錄一些周邊插件的使用方式、方法,便于自己后續回顧,也希望能給新用戶一些引導,少走一些彎路;核心其實是想表達一下對rockybean和KennyW的愛,這期間非常感謝兩位的協助,在非工作日深夜排查問題多次,正文多處采用二位給予的講解,萬分感謝。
基于Lucene構建的分布式,RESTful搜索和分析引擎;
實時搜索、分析,穩定,可靠,快速;
JAVA編寫,開源,使用JSON開源通過HTTP來索引數據;
項目介紹
歷史:
由前同事工作交接,原有一套ES1.7集群,但是經常jvm跑滿導致集群不可用,沒有ES調優經驗,甚至沒有使用經驗,從零了解ES,過度版本ES5.3~5.6;
背景:
數據源主要是Nginx訪問日志,由于Nginx是集群,相應的日志分布落在每臺機器上,當對整體日志做一些數據分析、故障排查等,因數據分散且量很大,通過腳本已經不能做分析處理了,為了對Nginx日志做全文搜索、分析,實時監控等,所以踏上ELK之路;
數據量:
每天6-7T,Docs在100億左右
架構圖
第一部分:日志收集(Nginx + Rsyslog)
采用Nginx內置的syslog模塊,每臺機器啟用本地的rsyslog,通過UDP方式傳輸本地的514端口(Rsyslog),然后Rsyslog在將數據轉發至Kafka;
選型比較:日志收集有很多種方式,如flume、filebeat、lua腳本等,但是這些組件都需要額外安裝客戶端,而rsyslog在linux都集成了。簡單對比過Rsyslog和其他區別,首先在Nginx中的syslog對于一個更改相對靈活,JSON日志與落地日志毫無干系(目前是兩份格式:人肉讀取的本地日志格式,機器讀取JSON網絡傳輸格式),日志輸出直接通過網絡傳輸走(網絡消耗很低)不受本地磁盤影響,對不同的server_name或location等可以靈活的修改,總之控制權在Nginx手里,Nginx的維護同學就可以自定義源數據格式,管理成本相對較低;
Rsyslog配置(雙打Kafka)
現有的版本是0.8,而剛開始測試的用logstash5.x需要kafka0.10(最終hangout替換logstash),所以新搭建了一組新的集群,Rsyslog向兩個Kafka集群分別寫數據,配置如下
Module?(load="imudp")?Module?(load="omkafka")?Input?(type="imudp"?port="514")?Module?(load="mmsequence")?$MaxMessageSize?4k?local5.none?/var/log/messages?local5.none?@log.domain.com:514?set?$!newmsg?=?replace($msg,'\x','\u00')?template(name="kafka_topic"?type="string"?string="%programname%")?template(name="kafka_msg"?type="string"?string="%!newmsg%")?if?($syslogfacility-text?==?'local5'?and?$syslogseverity-text?==?'info')?then{?action(type="omkafka"?topic="kafka_topic"?partitions.auto="on"?dynatopic="on"?dynatopic.cachesize="1000"?confParam=["compression.codec=snappy"]?#kafka?broker?addr?broker=["10.10.10.1:9092","10.10.10.2:9092",]?template="kafka_msg"?errorfile="/var/log/omkafka/log_kafka_failures.log")?action(type="omkafka"?topic="kafka_topic"?partitions.auto="on"?dynatopic="on"?dynatopic.cachesize="1000"?confParam=["compression.codec=snappy"]?#kafka?broker?addr?broker=["20.20.20.1:9092","20.20.20.2:9092",]?template="kafka_msg"?errorfile="/var/log/omkafka/log_kafka_failures.log")?stop?}?復制代碼
配置Nginx JSON格式日志
log_format?json_format??'{"@timestamp":"$time_iso8601",'?????????'"cookie_id":"$cookie_id",'?#內部cookie_id?????????'"client_ip":"$remote_addr",'?????????'"remote_user":"$remote_user",'?????????'"request_method":"$request_method",'?????????'"domain":"$host",'?????????'"user_agent":"$http_user_agent",'?????????'"xff":"$http_x_forwarded_for",'?????????'"upstream_addr":"$upstream_addr",'?????????'"upstream_response_time":"$upstream_response_time",'?????????'"request_time":"$request_time",'?????????'"size":"$body_bytes_sent",'?????????'"idc_tag":"tjtx",'?????????'"cluster":"$host_pass",'?????????'"status":"$status",'?????????'"upstream_status":"$upstream_status",'?????????'"host":"$hostname",'?????????'"via":"$http_via",'?????????'"protocol":"$scheme",'?????????'"request_uri":"$request_uri",'?????????'"http_referer":"$http_referer"}';復制代碼
Nginx內置syslog模塊配置,并且引用剛剛定義的json日志格式
access_log?syslog:local5:info:127.0.0.1:514:nginx_aggregation_log?json_format;?#nginx_aggregation_log???這是自定義的Topic復制代碼
NginxSyslog模塊介紹
1) UDP傳輸雖快,但是以太網(Ethernet)數據幀的長度必須在46-1500字節之間,UDP不能像TCP重組數據包,去除IP和UDP的數據包,最終可使用只剩1472字節。如果傳輸大于這個長度的消息,并不會想UDP本身一樣直接丟棄,只是會損壞源數據格式,截斷超過限制字節以外的數據;
2) 對于Nginx日志來說,只要不保留POST數據,基本一條消息不會超過限制字節,我在NginxSyslog介紹中沒看到支持TCP,用lua腳本實現的TCP方式傳輸,但是看了很多帖子都不建議在Nginx中用TCP日志傳輸。就是因為TCP傳輸可靠,但像網絡抖動、傳輸異常,可能會不停的重試多次或等待,直接影響這條請求,也直接影響到了用戶;
3) 消息超過了UDP傳輸限制怎么辦,我這目前是保留一條消息的重要字段,如上述的json_format的格式,將 request_uri、http_referer等可能會較大的字段放到最后,如果真的發現消息不完整,直接丟棄http_referer,取request_uri問號前的內容;(在logstash或hangout中filters實現,具體配置詳見下文Hangout-filters)
第二部分-存儲中間件(Kafka)
Kafka性能很強,順序寫入磁盤,高吞吐量的分布式發布訂閱消息系統
Kafka一直不是瓶頸,也沒太多深入優化,Topic數據保留了12小時,副本為1
針對不同的Topic,對Partition的數量有稍微改變,目前是5臺服務器,之前簡單測過增加Partition的性能,從8、16、32、64增加來看,明顯情況就是Partition增加,CPU使用也會隨之增加,因為kafka本身不是瓶頸,其他明顯問題也未遇到;
目前這邊最大的Topic是一天近5T數據,64Partition沒有任何問題,部分小的Topic都是16Partitio,Kafka整個集群的CPU空閑都在80%以上,內存、IO均無壓力,后續也考慮縮減機器。這邊的kafka團隊有個建議值,供大家參考:【每天數據規模小于50G選擇4分區、50G且小于100G選擇8分區、大于100G且小于500G選擇16分區、大于500G,選擇24分區】
Kafka監控插件:kafka-monitor?和?kafka-manager
注:
目前我們這kakfa集群是kafka_2.10-0.8.1.1版本,但是logstash5.x對kafka有版本要求>0.10版本。后來采用hangout,更換了幾個jar包解決了此問題
第三部分-數據搬運工(Hangout)
模仿logstash做的一個應用,功能沒有logstash多,但是基本使用都有了,java編寫,性能可以翻好幾倍,用到的功能就是從kafka訂閱消息,做一些簡單的過濾,然后寫入ES;目前hangout部署到2臺服務器上,每個進程開8G內存,CPU在60-70左右;
inputs:????-?Kafka:?????topic:??????????nginx_aggregation_log:?32?????codec:??????????json?????consumer_settings:?????????group.id:?es-nginx_aggregation_log?????????zookeeper.connect:?"10.10.10.1:2181,10.10.10.2:2181"?????????auto.commit.interval.ms:?"20000"?????????socket.receive.buffer.bytes:?"1048576"?????????fetch.message.max.bytes:?"1048576"?????????num.consumer.fetchers:?"1"?filters:????-?Filters:????if:?????????-?'<#if?message??>true#if>'??????????#如果不是完整的JSON,會出現message,則走此邏輯????filters:????????-?Grok:????????????match:??????????????-?'(?
Hangout進程管理工具(supervisord)
主要是守護hangout進程,在web界面對hangout進行啟、停、重啟等操作
topic: nginx_aggregation_log: 32,無論是logstash還是hangout都有這個概念,這個32代表需要建立多少子線程去kafka讀取數據,數量最好與Partition相等,如果少于Partition,會一個線程同時去2個Partition讀取消息,若大于Partition則會有不工作的進程
第四部分-Elasticsearch(后面簡稱ES)
CPU:32C,內存:128G?,硬盤:STAT?6T?*?12,網卡:萬兆?復制代碼
【系統】:?Centos7?內核3.10?【JDK】:?1.8.0_66/31G?(據說此版本JDK有BUG,請安裝最新JDK)?【系統參數修改1】:?vm.swappiness=1?[降低對硬盤的緩存]?【系統參數修改2】:?vm.max_map_count=262144?[Elasticsearch針對各種文件使用NioFS和MMapFS的混合。以便有足夠的虛擬內存可用于mmapped文件]?復制代碼
cluster.name:?es-nginx?node.name:?10.10.10.1??#為后期冷熱數據使用?node.attr.rack_id:?hdd??path.data:?/data??path.logs:?/opt/logs/elasticsearch/?network.host:?0.0.0.0??http.port:?9200?#設置新節點被啟動時能夠發現的主節點列表?discovery.zen.ping.unicast.hosts:?["10.10.10.1","10.10.10.2","10.10.10.3"]?#防止腦裂(n/2+1)?discovery.zen.minimum_master_nodes:?2?node.master:?true?node.data:?false復制代碼
剛剛開始測試ES的第一個版本是ES5.3,先搞了3臺機器,每個機器一個節點,配置是master和data共同提供服務,高可用架構集群搭建完成,但是寫入性能特別差,cpu使用在20-30%,少量io.wait,下圖是當時3w左右的性能圖當時覺得既然ES硬件很空閑一定是logstash出問題了,查看logstash確實有很嚴重的Full GC,開始從2臺服務器擴至4臺服務器,后來發現無果,期間各種調整ES的shard的數量都沒效果,又懷疑kafka性能,從2、4、6、8...64分區依舊無果。當時這個坑可爬了一段時間,后來在Google的游蕩中無意中看到帖子說,不要將master和data都啟用,然后我照著做了改變,master單點,data兩臺,問題搞定,效果圖找不到了,起碼翻倍是有的;
[Master除了網卡,其他沒什么消耗]?復制代碼
因shard數量、字段類型、其他設置等都是都是在創建時生成,所以要提前創建好相應的模板,便于規范管理和引用,下面針對shard和aliases做的一些設置,如下:
{???????"template":?"agg-nginx-*",???????"aliases":?{???????????"agg-nginx":?{}?????????},???????"settings":?{?????????"number_of_shards":?4,?????????"number_of_replicas":?1,?????????"index.routing.allocation.include.rack_id":?"ssd"???????}復制代碼
通過上述配置PUT到 _template/ur_name下在分片上的定義已經成功,但是像agg-nginx-
和test-agg-test-這樣的2個索引名字,即使你創建了另一個"template": "agg-nginx-test-*"的模板依舊都匹配第一個,當然換名字最簡單有效,在template的order的是專門解決這個問題的。默認創建"order": "0",值越高優先級越高,所以在想要先匹配的將order值調高即可
ES的mapping非常類似于靜態語言中的數據類型:聲明一個變量為int類型的變量, 以后這個變量都只能存儲int類型的數據。同樣的, 一個number類型的mapping字段只能存儲number類型的數據。同語言的數據類型相比,mapping還有一些其他的含義,mapping不僅告訴ES一個field中是什么類型的值, 它還告訴ES如何索引數據以及數據是否能被搜索到
下列是一個刪減版的mapping復制代碼
"mappings":?{?????"ngx_log":?{????????"_all":?{?????????"enabled":?false???????},???????"properties":?{?????????"@timestamp":?{???????????"type":?"date"?????????},?????????"client_ip":?{???????????"type":?"ip"?????????},?????????"domain":?{???????????"type":?"keyword"?????????},?????????"geoip":?{???????????"properties":?{?????????????"city_name":?{???????????????"type":?"keyword"?????????????},?????????????"country_name":?{???????????????"type":?"keyword"?????????????},?????????????"latitude":?{???????????????"type":?"float"?????????????},?????????????"location":?{???????????????"type":?"geo_point"?????????????},?????????????"longitude":?{???????????????"type":?"float"?????????????},???????????}?????????},?????????"request_time":?{???????????"type":?"float"?????????},?????????"request_url":?{???????????"type":?"keyword"?????????},?????????"status":?{???????????"type":?"keyword"???ype":?"keyword"?????????},????????????????}?????}???}復制代碼
_all字段
該_all字段是一個特殊的catch-all字段,它將所有其他字段的值連接成一個大字符串,使用空格作為分隔符,然后對其進行分析和索引,但不存儲。也就是說它能被查詢,但不能被取回顯示。因為Nginx每個Key對應的value都是提前定義好的,所以不用全文查詢,不需要開啟_all字段,另外也節省了一半的存儲空間
默認的text類型
上邊這英文有點多,其實簡單理解就是不分詞,你就最好別用text了,而且Text類型也會相應的多占用空間,依照上述,數據主要是日志分析,每條數據的格式已經很明確,主要用于日志分析,所以不需要分詞。像一些所有引擎的業務更適合需要分詞;
比如說像這個字段,get_ip中location這個字段類型默認text,但是如果不指定geo_point類型,根本無法使用地圖功能,類型的指定是很重要的
向request_time這樣的數據類型需要做計算,比如說平均值、和、大于、小于等等的,默認的text也能使用,但是效率遠遠小于float類型
字段類型有很多種,什么IP啊、DATE啊等等,根據相應的需要去官網查看詳解吧,mapping-types介紹
[摘取部分蘇若年博客內容]
1)分片算法:
shard = hash(routing) % number_of_primary_shards
routing值是一個任意字符串,它默認是_id但也可以自定義,這個routing字符串通過哈希函數生成一個數字,然后除以主切片的數量得到一個余數(remainder),余數的范圍永遠是0到number_of_primary_shards - 1,這個數字就是特定文檔所在的分片。
這也解釋了為什么主切片的數量只能在創建索引時定義且不能修改:如果主切片的數量在未來改變了,所有先前的路由值就失效了,文檔也就永遠找不到了。
所有的文檔API(get、index、delete、bulk、update、mget)都接收一個routing參數,它用來自定義文檔到分片的映射。自定義路由值可以確保所有相關文檔.比如用戶的文章,按照用戶賬號路由,就可以實現屬于同一用戶的文檔被保存在同一分片上。
2)分片與副本交互:
新建、索引和刪除請求都是寫(write)操作,它們必須在主分片上成功完成才能復制到相關的復制分片上,下面我們羅列在主分片和復制分片上成功新建、索引或刪除一個文檔必要的順序步驟:
1、客戶端給Node 1發送新建、索引或刪除請求。
2、節點使用文檔的_id確定文檔屬于分片0。它轉發請求到Node 3,分片0位于這個節點上。
3、Node 3在主分片上執行請求,如果成功,它轉發請求到相應的位于Node 1和Node 2的復制節點上。當所有的復制節點報告成功,Node 3報告成功到請求的節點,請求的節點再報告給客戶端。
客戶端接收到成功響應的時候,文檔的修改已經被應用于主分片和所有的復制分片。你的修改生效了。
一個索引要分多少片?什么時候該擴容?
取決于硬件和你對響應速度的要求,一般來說一個shard的數據量控制在1、2千萬的級別,速度都還好,過億會比較緩慢。 但是任何事物都有兩面,shard劃分比較小,必然數量就比較多。 在用戶做1、2天數據搜索的時候可能還好,如果搜更長時間的數據,一次搜索需要并行搜索的shard就比較多。如果節點數量有限,就會比較吃力,需要擴充更多的節點
據說是優化之王道,經常拿城市舉的例子,比如說我想看下網站的北京pv是多少,如果按照默認hash邏輯,一定要全shard掃描,然后聚合結果,但是如果提前設置好routing,比如說指定城市字段做hash計算,routing值一樣的放到特定幾個分片,這樣查起來也不需要全shard掃了;這樣弊端就是會造成shard大小不均,所以routing優化需要花一些功夫來觀察、測試;目前kibana還不支持routing查詢,所以目前在kibana上還沒有使用routing,這是優化的重點所以先記錄下來。后續我的想法是,像nginx日志的域名的字段都是英文字母,針對首字母做下routing,當想看某一個域名時不在全盤掃,查詢優化會有明顯效果,后續有結果在與大家分享;
另外hangout開始對routing的支持,后來在GitHub提了一個小issue,很快就加上了,點個贊;
第五部分-Kibana圖形展示
Kibana是一個開源的分析與可視化平臺,設計出來用于和Elasticsearch一起使用的。你可以用kibana搜索、查看、交互存放在Elasticsearch索引里的數據,使用各種不同的圖表、表格、地圖等kibana能夠很輕易地展示高級數據分析與可視化。
先介紹下幾塊功能:
X-pack可以免費使用部分功能,最強就是monitoring功能了,基本重要指標都收集了
Dev_tools的代碼補全神器,類似于IDE;還有強勁的可視化Search Profiler,便于直接定位問題點
其他就是常用的Discover、Visualize、Dashboard、Timelion搜索和繪圖功能了,沒有找到合適的帖子,直接吧迷妹兒的帖子放過來吧,主要介紹了如何優雅的使用kibana的搜索框
還有就是Elastic官方提供了一個Demo,便于大家做圖形展示的時候參考和借鑒
(╯﹏╰)吐槽一下,用SF寫到現在,Chrome都快沒法用了,打完字一會才顯示出來
[QPS展示]
[QPS環比]
[異常狀態碼趨勢]
[慢請求QPS]
[狀態碼比例]
[Domin與URL TOP]
再來一張深夜[熱圖],北京和上海的孩子總是不碎覺
上圖中環比圖是Timelion完成的,其他都是Visualize的功能
Timelion語法:
.es(index=index1,timefield=@timestamp).label('Today').title(QPS).color(#1E90FF),??.es(offset=-24h,index=index2,timefield=@timestamp).label('Yesterday').lines(fill=1,width=0.5).color(gray)復制代碼
kibana認證問題
由于x-pack試用版將認證功能被閹割掉了,直接暴露內容太風險,所以利用Nignx插件auth_basic的功能,做了一個簡單驗證模塊
最后調優
核心問題:查詢慢、查詢15Min數據都超時
數據量:
每天數據在6-7T,Docs在100億左右,其中一個大的索引在4-5T
ES升級
版本升級會帶來一些新特性,以及一些bug修復,當然也會引發新問題,我就踩到了新版本的坑;
ES5.x升級到5.5是滾動升級,相對升級步驟簡單,但是由于數據太大,動輒幾十T,一臺臺完成升級,卻是一個漫長的過程。另外,1.x升級據說很痛苦,有興趣的去看看,連接放在這里reindex-upgrade
簡述下5.x升級的過程
1)關掉分片自動分配:"cluster.routing.allocation.enable": "none"
2)強制刷新,盡可能將緩存中的數據,寫入磁盤: _flush/synced
3)停止一個節點,開始升級及升級插件,然后啟動
4)打開分片自動分配:"cluster.routing.allocation.enable" :"all"
5)等待集群恢復至綠色,繼續下一臺
擴容
擴容很簡單,沒什么可說的,除了配置文件中node.name不一樣,其他都一樣;
最初擴容只是將data節點從3臺擴至20臺,寫入沒問題,1-2k的數據,單機性能寫入在30-40k;
mapping字段優化:
主要像上述的mapping介紹,做類型優化,不分詞的keyword,數學計算的改成整型or浮點等
status這個字段的類型,value一般都是200、301、302、404、502,最多估計也就幾百個,像這樣的字段就不適合做long,long類型的索引是為范圍查找優化的,用的是二叉樹這樣的索引,適合值范圍比較大的字段,比如body_size,可能最大值和最小值相差很多,而用keyword索引是倒排,只用存放一個所有status的詞典,所以keyword更適合
shard數量調整:
開始主分片數量是每臺機器1個,副本1(20shard x 1replicas),每個shard已經達到將近200G,看這個量級已經超過官方建議值30~50G之間(具體要根據實際情況測試為準)。于是開始將數量翻倍40shard * 1replicas,調整后查詢并沒有明顯改善,對寫入沒有什么改變,繼續double,依舊沒效而且分片越多,寫入的時候消耗的CPU就越高
如果過度分配shard,就增大了Lucene在合并分片查詢結果時的復雜度,從而增大了耗時,在新建索引時,更是一筆大的開銷。
一般來說,剛開始的時候盡量少分片為佳, 只有到一個分片上數據太多,單次查詢太慢在考慮加分片。
加分片也有負面作用,提高了并發量,隨之開銷就會越大,更多的shard一般也伴隨更多的segment文件。如果說節點數量沒變,每個節點上會有更多的小文件,搜索的時候并發量是高了,前提是在磁盤io和cpu都還能應付的過來的時候,速度才會快
拆分索引
更改shard已經得不到顯著效果,于是從拆索引下手。數據都是Nginx日志,從源頭拆分沒什么好的方法,于是從hangout這層開始做處理,很簡單就是將域名的第一個字母取出來,寫入相應的索引時候帶過去,例如:nginx-log-{首字母},這樣一拆,一下創建26個索引(shard20 * 1replicas),CPU立馬load 30+,負載直接上來,然后ES數據還跟不上,拒絕了很多內容,如下圖,最終還是無果而告終此方案
上述的索引拆分是比較傻瓜式,首先已知的問題就是可能A開頭的域名很大,其他很小就是很不均勻
Pcle-SSD測試
經過上面的折騰,已經沒有什么突破點,于是借用了8臺SSD的機器,修改ES配置node.attr.rack_id: ssd,將數據寫入SSD,全程io無壓力,寫入一個一天4-5T的索引,CPU在50%左右,但是查詢依舊不給力,經過無數shard調整依舊不給力,IO一直沒空閑,最終結論就是沒有將ssd的性能發揮出來,還是未解決根本問題
kibana BUG
之前沒有ES相關經驗,能想到的辦法、關注點都沒有什么在突破的地方了,在束手無策的時候,又非常有幸認識了KennyW,再次感謝KennyW的支持;問題根本原因是kibana5.4-5.5這兩個版本在查詢問題,為了節省空間,我關掉了_all這個字段,如果搜索框不輸入內容的時候,則會補充*查詢所有字段,生成的bool條件就非常多,引發kibana的缺陷,引用:
當時的版本KennyW給的知道是臨時修復方法如下:
詳細問題請看這里ES 5.4+ 引起的Kibana性能問題,Kibana5.5.2后已經修復此問題,所以最終版本還是升級到了5.6,也是目前的最新版
回歸HDD
經過SSD的折騰,查到了kibanaBug問題,其實SSD并未發現其他的性能亮點,經過與KennyW的交流,他們自己有做過在SSD和多塊HDD的盤對比,寫入量并無明顯提升,所以在磁盤并不是真正的瓶頸,查詢方面SSD明顯提高。但是SSD的高額付出換來那么幾秒鐘的意義不大。相對,對一些公司的搜索業務,數據量級小,還有像一些監控業務,要求實時性非常高,對SSD是很好的選擇,速度快,容量不需要太多,也比較經濟實惠
[KennyW經驗指導]
當做復雜計算,bucket很多的時候主要消耗的是CPU和內存,磁盤并不是瓶頸,hdd和ssd在我們實際用下來,感覺在大數據場景分別不大,ssd優勢在大量的隨機磁盤io,ES本身做了很多優化,讓數據變成順序的磁盤訪問,而且搜索過的數據塊,ES都能利用文件系統緩存加速,所以即使使用hdd,可能第一次搜索磁盤訪問會帶來額外的幾秒耗時,但多次執行同一個搜索時,后面幾次幾乎沒什么磁盤io開銷,速度會有明顯提升
RAID0的重要性
當所有的集群全部更改回hdd的集群時候,發現一個之前沒太關注的指標,每塊盤的利用率。剛開始解決的時候我們的機器都是裸盤直接掛上,path.data:data1,data2,data...這樣掛載,但是在5.x版本發現這樣磁盤問題(CMD:iostat -x 1)這樣看來很奇怪,為什么這塊盤這么忙,多觀察一會發現,一會又發現其他的盤又很忙,然后df查看磁盤使用率,扎心了
掛了這么多盤,真實寫入連一半的盤都不到,既然這樣,沒得說的了,直接上raid0吧
收尾
做到目前這些調整,現在一天小于1T的索引任何查詢都沒有問題,查詢在10s左右返回所有數據(上圖kibana展示),但是那個一天4-5T的索引還是有問題,一查詢IO就跑滿,到30s直接超時了,先說下IO跑滿的問題吧,問題是request_uri臺過于分散,聚合出現問題如圖:15分鐘就出現了2000多萬不同值,如果長時間計算,不可想象的恐怖
【KennyW指導】
request_uri 會產生大量的磁盤IO。 ES做terms聚合的時候,為了節省內存,不會將所有term的內容直接讀出來做bucket,因為有些term的內容可能很長,會比較耗費內存。 所以他會借助一種叫做oridinals的數據結構, 這種數據結構類似這樣
1 abc
2 efg
3 hfa
.............
一個該字段所有不同值的順序列表。 做分桶聚合的時候,只需要拿這個順序數字做key就可以了,等聚合出結果,再通過這個key查ordinals表,得到實際的key值填充結果。 但是這個ordinals是隨著segment 文件生成的,每個segment文件的ordinals順序可能不一樣。 因此在聚合的時候,需要一個全局的global ordinals。 這個數據結構是在聚合的時候,實時生成后緩存在內存里的。 如果某個字段的不同值非常多,計算價值非常的昂貴,那么這個構造過程就非常的緩慢,除了大量的磁盤IO消耗,還會有很大的內存消耗。
下圖是關掉這個有問題的visualize前后對比圖,雖然不快,但是latency降了很多
后來對uri的?后邊的參數全部丟棄,像這樣的問題只能減少然后做聚合使用,原有數據做搜索使用,但是由于數據太大,做復雜計算還是會超時30s,這種情況只能是降低team的cardinality,或者加分片、加機器或者拆索引了,所以對kibana的超時時間做了一點調整,還有一些周邊小的修改如下
1)kibana默認的30s超時改成2min,kibana.yml中修改
elasticsearch.requestTimeout: 120000
2)kibana默認地圖使用高德,kibana.yml中新增
tilemap.url: 'http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
3)結合cerebro插件,高效管理索引
后續
說到這里順便給大家推薦一個交流學習群:650385180,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,相信對于已經工作和遇到技術瓶頸的碼友,在這個群里一定有你需要的內容。
到這里基本的一期項目算是結束,雖然部分查詢并沒有迅速返回,但是基本數據都可以展示,后續會關注幾個點繼續深入優化和調整,有結果在與大家分享
routing優化查詢
curator管理過期索引
比較大index索引做拆分
增加client節點,減少集群影響
冷熱數據分離(node.attr.rack)、定期對冷數據force_merge,優化查詢速度
總結
首先在這里還是先要感謝rockybean和KennyW的大力支持。
對自己的總結就是,對ES經驗太少,踩了很多不必要的坑,另外就是沒有好好統一閱讀下官網文檔,這樣極其影響效率與進度,好多時候也會束手無策,不知從何下手。
第一次寫技術帖,而且時間稍緊,有哪些地方寫的不好或敏感煩請指出,我會及時更正。希望這篇文章,能給予像我這樣的小白用戶少踩一點坑,多一點愛。
Elasticsearch
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。