Elasticsearch索引自動化管理

在這裏插入圖片描述

背景

前端性能監控的日誌之前爲單一索引,隨着日誌內容的不斷增多,索引文件變得越來越多大(官方建議單個索引文件不要超過20G)。

在此種方案下只能定時通過delete query的方式刪除xxx天之前的數據,此種方式刪除數據時異常緩慢,而且磁盤空間不會立即釋放。

亟需採取新的索引方案解決該問題,比如按天生成索引,定時刪除一個月之前的索引文件,直接刪除索引文件的效率會高不少。

索引創建

索引模板

索引模板是爲了方便按天去生成相同配置的索引文件,樣例如下:

# 創建索引模板
PUT _template/jz-fe-performance-log-template
{
  "index_patterns" : ["jz-fe-performance-log-*"],
  "settings" : {
      "index" : {
        "lifecycle" : {
          "name" : "jz-fe-log-15days"
        }
      }
    },
  "mappings": {
    "dynamic": "strict",
    "properties":{
      "groupName":{"type":"keyword"}, 
      "projectName":{"type":"keyword"}, 
      "href":{"type":"keyword"}, 
      "clientDate":{"type":"date","format":"yyyy-MM-dd HH:mm:ss"},
      "serverDate":{"type":"date","format":"yyyy-MM-dd HH:mm:ss"},
      "appId":{"type":"keyword"}, 
      "hmsr":{"type":"keyword"}, 
      "znsr":{"type":"keyword"}, 
      "hmpl":{"type":"keyword"}, 
      "unloadTime":{"type":"integer"}, 
      "redirectTime":{"type":"integer"}, 
      "appCacheTime":{"type":"integer"}, 
      "dnsTime":{"type":"integer"}, 
      "tcpTime":{"type":"integer"}, 
      "requestTime":{"type":"integer"}, 
      "responseTime":{"type":"integer"}, 
      "analysisTime":{"type":"integer"}, 
      "loadEventTime":{"type":"integer"}, 
      "connectTime":{"type":"integer"}, 
      "resourceTime":{"type":"integer"}, 
      "domReadyTime":{"type":"integer"}, 
      "TTFBTime":{"type":"integer"}, 
      "TTSRTime":{"type":"integer"}, 
      "TTDCTime":{"type":"integer"}, 
      "TTFLTime":{"type":"integer"}, 
      "FMPTime":{"type":"integer"},
      "uid":{"type":"keyword"},
      "phone":{"type":"keyword"},
      "platform":{"type":"keyword"},
      "os":{"type":"keyword"},
      "browser":{"type":"keyword"},
      "version":{"type":"keyword"},
      "userAgent":{"type":"text"},
      "ip":{"type":"keyword"},
      "networkType":{"type":"keyword"},
      "ISP":{"type":"keyword"},
      "region":{"type":"keyword"}
    }
  }
}

說明:

  • PUT _template/jz-fe-performance-log-template創建名稱爲jz-fe-performance-log-template的索引模板
  • index_patterns中的jz-fe-performance-log-*代表索引名稱爲jz-fe-performance-log-的索引都按這個模板的配置去生成
  • settings中的lifecycle項註明以哪一個lifecycle配置來管理該索引,在後續的索引刪除部分會使用到
  • mappings就是所有文檔的配置了,strict表面爲嚴格模式,索引數據只能爲下面聲明的字段名稱,否則無法保存

數據保存

在數據調用Node服務接口時,做如下處理,即可按天把日誌保存到當天的日誌文件中


const { Client } = require('@elastic/elasticsearch')

// 性能數據索引
const PERFORMANCE_PROD_INDEX = 'jz-fe-performance-log'
const PERFORMANCE_TEST_INDEX = 'jz-fe-performance-log-test'

/**
 * ES數據插入操作
 * @param index 索引
 * @param data 數據
 * @returns {Promise<ApiResponse<any>>}
 */
async function base ({ index, data }) {
    const res = await client.index({
        index: index,
        body: data
    }).catch(err=>{
        console.error('err', JSON.stringify(err))
    })
    return res
}

/**
  * 日期格式化
  * 返回 2020-6-5類型數據
  * @param {日期} date 
  */
function dateFormat (date) {
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    return year + '-' + month + '-' + day
} 

/**
 * 性能數據入庫
 * @param body
 * @returns {Promise<ApiResponse<any>|TResult>}
 */
async function performanceAdd (data) {
    const index = tools.isTestENV() ? PERFORMANCE_TEST_INDEX : `${PERFORMANCE_PROD_INDEX}-${dateFormat(new Date())}`
    const res = await base({ index: index, data })
    return res
}

說明:

  • 索引名稱以jz-fe-performance-log打頭的索引文件沒有時都爲以上面的模板新創建
  • 性能數據保存時,指定保存到當天的索引文件中

索引刪除

實現了索引文件按天拆分之後,下一步就需要考慮如何把索引文件管理起來。

日誌數據一般只保留一個月,這個時候可以考慮可以寫一個程序定時去刪除一個月之前的索引。

Elasticsearch 6.6開始提供了一個叫Index Lifecycle Management的功能來管理日誌。

ILM配置

可以通過kibana可視化的做配置,也可以通過寫ES語句的方式創建
在這裏插入圖片描述

點擊Create policy即可創建對應配置
在這裏插入圖片描述

可通過如下方式查看剛纔創建的具體配置信息

# 查看Index Lifecycle Manegment配置
GET /_ilm/policy/jz-fe-log-15days

返回結果如下

{
  "jz-fe-log-15days" : {
    "version" : 1,
    "modified_date" : "2020-06-04T10:02:16.233Z",
    "policy" : {
      "phases" : {
        "hot" : {
          "min_age" : "0ms",
          "actions" : {
            "set_priority" : {
              "priority" : 100
            }
          }
        },
        "delete" : {
          "min_age" : "15d",
          "actions" : {
            "delete" : { }
          }
        }
      }
    }
  }
}

說明:

  • 索引要被哪個ILM管理是在索引的settingslifecycle處指定的
  • ES默認10分鐘執行一次檢查,如果對應索引滿足創建時間大於15天,則刪除索引

其他操作

下面是測試驗證該功能會用到的相關ES語句

# =========索引模板相關===========

# 創建索引模板
PUT _template/jz-fe-test-template
{
  "index_patterns" : ["jz-fe-test-*"],
  "settings" : {
      "index" : {
        "lifecycle" : {
          "name" : "jz-fe-log-30s"
        }
      }
    },
  "mappings": {
    "dynamic": "strict",
    "properties":{
      "gitGroup":{"type":"keyword"}, 
      "projectName":{"type":"keyword"}
    }
  }
}


# 查看指定template信息
GET /_template/jz-fe-test-template
# 查看指定前綴template信息
GET /_template/jz-fe-*

# 刪除索引模板
DELETE /_template/jz-fe-test-template

# 增加數據
POST /jz-fe-test-2020-06-03/_doc
{
  "gitGroup":"OS X",
  "projectName":"iPhone2"
}

# 查詢數據
GET jz-fe-test-2020-06-*/_search

# 查看索引詳情
GET /_cat/indices/jz-fe-test*?v&s=index

# 刪除測試索引
DELETE /jz-fe-test-2020-06-*

# =========Index Lifecyce Management===========

# 設置10秒刷新1次(即定時器間隔),生產環境10分種刷新一次
# 可設置索引的保留時間爲30s,每10s判斷一次是否滿足條件
PUT _cluster/settings
{
  "persistent": {
    "indices.lifecycle.poll_interval":"10s"
  }
}

# 查看設置
GET _cluster/settings

# 查看Index Lifecycle Manegment配置
GET /_ilm/policy/jz-fe-log-15days

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章