背景
基于ELK搭建的日志平臺,前期匆忙建設過程中一些參數和設計未做過多的考慮,上線后就需要不斷根據實際情況做調整,而一些調整限于ELK的一些特性,一旦操作不當就會出現丟數據、數據寫入異常、數據查不到等情況。
因此如何在這種背景下,做到對使用方無感知的動態調整是我們所要實現的目標。所以本文更加注重實踐而非深層次的理論講解,有興趣深入了解的可以自行研習。
總體架構
CASES
CASE1:按日/月生成索引
創建的nginx access_log索引,開始采集2周后,數據達到25G+(number_of_replicas=1,因此總體數據超過50G),如果不進行索引拆分,該索引將越來越大,最終會嚴重影響查詢效率,并且一旦出現索引損壞造成的風險也更大。
通過配置logstash ouput 插件實現按照日期生成新索引:
output {
elasticsearch {
hosts => ["192.168.0.1:9200"]
index => "php-nginx-log-%{+YYYY.MM.DD}" #按照天生成索引
}
}
通過我們的配置,目前會存在2個index,分別為歷史的php-nginx-log索引和以php-nginx-log.2019-01-15索引。
CASE2:Kibana查詢所有數據
由于目前我們的索引不再是指定的具體索引,還是一類按照事先約定的命名格式索引集合,這時我們想要能夠在Kibana查詢數據時不受影響,能夠正常查詢到數據,此時主要有兩種解決方式:
1、更改Kibana的Create index pattern,使用通配符關聯出所有index
2、使用index aliases,詳情:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/indices-templates.html
Elasticsearch的別名,就類似數據庫的視圖,別名不僅僅可以關聯一個索引,它能聚合多個索引,下文還會提到別名的更重要的特性。
通過別名的方式是更加建議的方式。
POST /_aliases
{
"actions" : [
{ "add" : { "index" : "new_index1", "alias" : "alias1" } }
]
}
說明:這里使用Elasticsearch的REST API進行設置,具體詳情參考官網:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs.html ,下文中的類似代碼塊都是此類調用。
CASE3:通過模板創建Index
創建index后,如果未指定具體mapping,則在插入具體doc數據時,會自動生成,具體數據字段的數據類型Elasticsearch會做一定的動態識別,但是大部分都將以string定義,這種情況下我們在使用數據時 ,就會出現一些不便,如 Kibana一些函數必須是整型類型、ip類型的字段才可以使用,另外全部默認為string類型會導致查詢效率的低下和存儲容量的浪費。
這時就需要我們去指定index的mapping,而很重要的一點:mapping中的filed一點指定后(無論是默認生成還是手動聲明)就無法進行update filed操作,如果要修改通常只能進行create 新的index。因此我們往往會在index寫入數據前就創建好index的mapping,如下:
PUT new_index1
{
"settings" : {
"number_of_shards" : 1
},
"mappings" : {
"_doc" : {
"properties" : {
"field1" : { "type" : "text" }
}
}
}
}
而通過CASE1中,已經說明了我們的index都是由Logstash按照日期自動創建的,因此手動通過API的方式無法滿足我們的需求,這時我們就需要使用Elasticsearch的template特性:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/indices-templates.html
創建template:
PUT _template/template_nginx_log
{
"index_patterns": ["php-nginx-log*"],
"settings": {
"number_of_shards": "5",
"number_of_replicas": "1"
},
"aliases": {
"php-nginx-log": {}
},
"mapping": {
"doc": {
"properties": {
"@timestamp": {
"type": "date"
},
"geoip": {
"type": "object"
},
"geoip_city_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"geoip_continent_code": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"geoip_country_code2": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"user_device_os_name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
}
具體說明:
index_patterns:指定index匹配表達式,這個特性十分重要,如果配置為 ”php-nginx-log*“,則所有以php-nginx-log為前綴的索引都將自動使用該template進行索引創建,而不需要特殊指定
aliases:為索引指定一個別名,同樣的,通過該配置就能實現我們前面提到的問題,讓按照日期創建的新index能夠被正確的查詢到
CASE4:原index數據遷移(mapping有修改)
1)CASE3開頭的時候提到過,需要按照固定的mapping創建index,來達到生成的index能使用規范的數據類型的目的,而歷史index中數據想要修改mapping只能重新創建,這時我們通常使用Elasticsearch的reindex特性:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs-reindex.html
POST _reindex?slices=5&refresh
{
"source": {
"index": "php-nginx-log-2019.01",
"size": 10000
},
"dest": {
"index": "php-nginx-log-2019.01.15"
}
}
說明:
默認情況下,_reindex使用1000進行批量操作,您可以在source中調整batch_size,如上面設置為了1萬
-
Reindex支持Sliced Scroll以并行化重建索引過程。 這種并行化可以提高效率,并提供一種方便的方法將請求分解為更小的部分,如上面設置為了slices=5
1)slices大小的設置可以手動指定,或者設置slices設置為auto,auto的含義是:針對單索引,slices大小=分片數;針對多索引,slices=分片的最小值。
2)當slices的數量等于索引中的分片數量時,查詢性能最高效。slices大小大于分片數,非但不會提升效率,反而會增加開銷。
3)如果這個slices數字很大(例如500),建議選擇一個較低的數字,因為過大的slices 會影響性能。
-
如果要進行大量批量導入,請考慮通過設置index.number_of_replicas來禁用副本:0。
主要原因在于:復制文檔時,將整個文檔發送到副本節點,并逐字重復索引過程。這意味著每個副本都將執行分析,索引和潛在合并過程。
相反,如果使用零副本進行索引,然后在提取完成時啟用副本,則恢復過程本質上是逐字節的網絡傳輸。 這比復制索引過程更有效。
2)我們要保證新舊index的數據平滑遷移對用戶無感知,此時可以使用前文提到的alias,流程為:
1 . 就index使用alias,數據使用方通過alias查詢數據
2 . reindex生成的新index不要創建別名,進行數據reindex操作
3 . 待數據復制完成后,調用remove+add alias接口,該操作為原子操作,可以保證數據無縫遷移,具體代碼如下:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/indices-aliases.html
POST /_aliases
{
"actions" : [
{ "remove" : { "index" : "test1", "alias" : "alias1" } },
{ "add" : { "index" : "test2", "alias" : "alias1" } }
]
}
總結
至此我們就總結完了一些Elasticsearch及ELK架構下常用CASE,通過合理的使用組件的特性,來滿足我們的業務需求。
后面我們還將總結一些Logstash的經典CASE。
歡迎關注 高廣超的簡書博客 與 收藏文章 !
歡迎關注 頭條號:互聯網技術棧 !
個人介紹:
高廣超:多年一線互聯網研發與架構設計經驗,擅長設計與落地高可用、高性能、可擴展的互聯網架構。目前從事大數據相關研發與架構工作。
本文首發在 高廣超的簡書博客 轉載請注明!