管理 Index 的 Best Practices 系列文章索引
Rollup 是 Elasticsearch 6.3 推出的新功能,目前還在 Experimental 階段,官方不建議直接使用在 Production 環境中,不過版本的演進已從 6.3 發展到了到 7.9,相信已經發展到了接近成熟的階段 ,因此這次還是選擇介紹這功能,不過實際在正式環境中,建議還是等官方正式移除 Experimental 的階段後再開始使用。
Rollup 是一個把用來依時間分析的歷史資料的時間 顆粒度( Granularity ) 變大,以節省空間的 定期執行 的機制。
例如我們收集的即時資料 1秒鐘 有 1000筆,每天就會有 86,400,000 筆資料,而一年後就會有 365 * 86,400,000 筆,這個佔用的儲存空間是很大的,而好處是我們可以隨時查到精確的某一筆原始資料。
但平常在分析上,若我們將時間顆拉度拉最小只能看到 分鐘 為單位,這時只需要保存以1分鐘產生一筆彙總的資料,這樣的筆數就只剩下 86,400 筆,只剩下原來的 1/1000。 (當然實際大小可能有所不同,因為彙總的資料的資料大小可能和原始資料有點落差。)
首先,進入 Kibana > Stack Management 後,點選左側 Data 區塊中的 Rollup Jobs。
點 Create rollup job 之後,會進入設定頁面:
這邊的設定基本上都蠻直覺的,依照旁邊的說明設定即可。
這邊有個要注意的
Index pattern
不應該包含到Rollup index name
,上圖就是一個錯誤的例子,這樣會造成處理邏輯上的錯誤,如果你設定了這樣的配置,最終會看到以下這樣的錯誤畫面。
接下來要分別設定 Date histogram 的時間顆粒度:
設定有哪些欄位會使用到 Term bucketing:
哪些欄位可能會進行 Histogram 的 aggregation:
哪些欄位會使用到 Metrics,這邊請依照資料的特性來判斷,有些沒必要的就不用勾選了。
最後 Review 完沒問題時,就可以直接建立。
當建立完成後,在 Rollup Jobs 的選單中可以看到我們建立的這個 Job。
點開後也可以看到他的 Stats,包含目前已經處理了多少 Documents、Pages、以及執行過多少次。
這時到 Index Management 來查看 Elasticsearch 中的 Index,就可以看到由這個 Rollup Job 所產生的 Index 了。
記得要把上面
Include rollup indices
打勾,才會看得到。
這時 Rollup Job 產生的資料已經可以使用了。
而且我們可以看到, rollup-logstash-daily
佔用的是 446mb 的空間,比起整體 logstash-1
~ logstash-10
的總量,大約只佔了 1/10 。
首先,這是我們測試用的一筆資料,這是一個 HTTP Request 的 Log:
{
"_index" : "logstash-10",
"_type" : "_doc",
"_id" : "VGlRz3QBFWvcdj-NvfL6",
"_score" : 1.0,
"_source" : {
"index" : "logstash-10",
"@timestamp" : "2020-10-27T04:57:02.344Z",
"ip" : "148.214.137.20",
"extension" : "jpg",
"response" : "200",
"geo" : {
"coordinates" : {
"lat" : 34.48339944,
"lon" : -104.2171967
},
"src" : "AU",
"dest" : "ID",
"srcdest" : "AU:ID"
},
"@tags" : [
"warning",
"info"
],
"utc_time" : "2020-10-27T04:57:02.344Z",
"referer" : "http://www.slate.com/success/lisa-nowak",
"agent" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)",
"clientip" : "148.214.137.20",
"bytes" : 3586,
"host" : "media-for-the-masses.theacademyofperformingartsandscience.org",
"request" : "/uploads/konstantin-feoktistov.jpg",
"url" : "https://media-for-the-masses.theacademyofperformingartsandscience.org/uploads/konstantin-feoktistov.jpg",
"@message" : "148.214.137.20 - - [2020-10-27T04:57:02.344Z] \"GET /uploads/konstantin-feoktistov.jpg HTTP/1.1\" 200 3586 \"-\" \"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)\"",
"spaces" : "this is a thing with lots of spaces wwwwoooooo",
"xss" : """<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==" onload="alert('XSS found via img-onload!')"><script>alert("XSS found via script-tag!")</script>""",
"headings" : [
"<h3>chris-hadfield</h5>",
"http://facebook.com/success/christopher-ferguson"
],
"links" : [
"alexander-poleshchuk@www.slate.com",
"http://www.slate.com/login/pavel-belyayev",
"www.twitter.com"
],
"relatedContent" : [ ],
"machine" : {
"os" : "osx",
"ram" : 6442450944
},
"longValues" : "efearpjmayxX"
}
}
而經過 Rollup Job 產生出來的資料,若我們直接用 _search
API 來查詢:
GET rollup-logstash-daily/_search
會看到他回傳的結果長這樣子:
{
"_index" : "rollup-logstash-daily",
"_type" : "_doc",
"_id" : "rollup-logstash-daily$8LKzd9hsjA2IhasDI3Z8kA",
"_score" : 1.0,
"_source" : {
"@timestamp.date_histogram.time_zone" : "Asia/Taipei",
"memory.histogram.interval" : 1000,
"memory.histogram.value" : null,
"bytes.value_count.value" : 1.0,
"@timestamp.date_histogram._count" : 1,
"memory.histogram._count" : 1,
"geo.src.terms.value" : "SD",
"geo.srcdest.terms.value" : "SD:AO",
"machine.ram.max.value" : 2.147483648E9,
"bytes.histogram.interval" : 1000,
"bytes.histogram.value" : 0.0,
"geo.dest.terms.value" : "AO",
"phpmemory.histogram.value" : null,
"bytes.sum.value" : 271.0,
"bytes.min.value" : 271.0,
"geo.src.terms._count" : 1,
"geo.dest.terms._count" : 1,
"_rollup.id" : "rollup-logstash-daily",
"response.keyword.terms.value" : "200",
"@timestamp.date_histogram.timestamp" : 1598544000000,
"referer.terms._count" : 1,
"referer.terms.value" : "http://www.slate.com/error/sigmund-j-hn",
"bytes.max.value" : 271.0,
"machine.os.keyword.terms.value" : "ios",
"url.keyword.terms._count" : 1,
"@timestamp.date_histogram.interval" : "24h",
"bytes.avg.value" : 271.0,
"host.keyword.terms._count" : 1,
"machine.ram.min.value" : 2.147483648E9,
"machine.ram.histogram.value" : 2.147483E9,
"bytes.avg._count" : 1.0,
"request.keyword.terms._count" : 1,
"request.keyword.terms.value" : "/canhaz/yuri-artyukhin.gif",
"phpmemory.histogram.interval" : 1000,
"phpmemory.histogram._count" : 1,
"bytes.histogram._count" : 1,
"geo.srcdest.terms._count" : 1,
"url.keyword.terms.value" : "https://motion-media.theacademyofperformingartsandscience.org/canhaz/yuri-artyukhin.gif",
"_rollup.version" : 2,
"machine.os.keyword.terms._count" : 1,
"machine.ram.histogram._count" : 1,
"host.keyword.terms.value" : "motion-media.theacademyofperformingartsandscience.org",
"response.keyword.terms._count" : 1,
"machine.ram.avg._count" : 1.0,
"machine.ram.histogram.interval" : 1000,
"machine.ram.avg.value" : 2.147483648E9
}
},
Rollup 後的資料,已經是使用另外的彙總的格式來儲存,所以他已經沒有原本的資料內容了。
從上面的例子可以看到,使用 _search
的結果會是長得不一樣的文件,也因此 Rollup 後的資料,若是要進行 search 時,要使用 _rollup_search
的 API。
這邊先從原始的資料來查詢:
再來使用 _rollup_search
來執行一樣的 query:
可以看到結果是一樣的,通常如果是有一些 metrics 的數值運算的話,有可能會有小誤差。
另外在使用上會有一些限制,以下會做相關的介紹。
這邊特別要說一下,使用
_rollup_search
若是跨到 Rollup Index 與 原始的資料 時,不會計算重覆的資料,這讓 Rollup 與 Live data 混搭使用非常的方便。
Rollup 的資料在使用上有一些限制
_rollup_search
可同時包含多個非 rollup index,但一次只能包含一個 rollup index。3d
,就只能用 3d
, 6d
, 9d
...以此類推。Term
, Terms
, Range
, MatchAll
, 以及 Boolean
, ContantScore
等 compound 查詢。Date Histogram
, Histogram
, Terms。
Min
, Max
, Sum
, Average
, Value Count
。在 Kibana 中,若要使用 Rollup 的資料,要特別建立一個 Rollup Index Pattern
,如下圖:
建立好這個 Index Pattern 後,就可以在 Discover, Virtual, Dashboard 來使用了。
(2020.09.29 更新) Rollup 目前產生出來的 Index 還無法套用 Rollover 的機制,這部份的支援已在官方的討論中,有可能在未來會直接整併成 Index Lifecycle Management 中的其中一個 Action,可參考這篇 Githib Issue。
ES 在 Rollup 的支援上,除了讓你整理成較大的時間顆粒度來儲存資料,例如以 1天
為單位。
如果你在進行 Query 與 Aggregate 時,當然最小的顆粒度就是 1天,但如果你要的單位是比1天還大的顆粒度,如:1週
、1個月
、一季
、一年
…等,你不需要為這每個顆粒度建立獨立的 Rollup job,這些都能在 _rollup_search
的計算時,直接以 1天
的資料來彙總計算出來。
這部份的說明比較複雜,建議直接參考 官方文件的說明 ,主要的概念是,建議少用 Calendar 的"一天",而是用"24小時"、少用 Calendar 的"一個月",而是用"30天",這樣的 Interval 單位,因為 Calendar 時間在查詢的時,會是比較難複雜且使用時的限制較多。
另外若使用上是有指定時區的話,記得設定好時區,這樣在時間的切分上才會如使用的預期。
騰訊針對 Metrics 類型的資料:
這樣的顆粒度,是在設計 Rollup Job 時需先考量清楚的,確保使用的情境與需求來製訂規則。
Rollup Job 一但決定下去,就無法改變,除非重建 Rollup Job。
查看最新 Elasticsearch 或是 Elastic Stack 教育訓練資訊: https://training.onedoggo.com
歡迎追蹤我的 FB 粉絲頁: 喬叔 - Elastic Stack 技術交流
不論是技術分享的文章、公開線上分享、或是實體課程資訊,都會在粉絲頁通知大家哦!
此系列文章已整理成書
喬叔帶你上手 Elastic Stack:Elasticsearch 的最佳實踐與最佳化技巧
書中包含許多的修正、補充,也依照 Elastic 新版本的異動做出不少修改。
有興趣的讀書歡迎支持! 天瓏書局連結