了解
如果你对 es 有一定的使用经验,相信应该听过 ilm 机制,没错,就是 es 的索引生命周期管理机制。
在实际项目应用中,合理应用 ilm 机制可以解放我们的双手,不用手动去管理索引的新建、切分,只需要内部机制处理索引,如:
- 1.最新的数据可读可写
- 2.次新的数据仅可读
- 3.很久的数据一定时间后就被删除
很好,这里正是对应 ilm 机制的若干个不同的状态,如 HOT WARM DELETE 这几个状态。
关于 es ilm 不同状态的官方见:Index lifecycle
通常项目中,以内部项目为例,我们主要涉及3个状态 HOT/WARM/DELETE,分别采取的策略如下:
- HOT,可读可写,限定 max_age max_size,或者 max_docs,只要满足其中之一,相应状态就会转到下个状态
- WARM,可读,限定一个生存时间,如max_age,满足后进入下个状态
- DELETE,不可读不可泄,保留一定时间,如限定 min_age
网络上大部分的资料都是介绍 ilm 这块的应用,对于其原理的讲解也很少,详情自己搜,这里我们主要也通过一个实际的示例看看 ilm 机制的应用。
es官方的 ilm说明:Rollover
总体来说,可以分为以下几步:
- 1.新建template,在template中限定分片与副本数量,哪些index适用,以及绑定那个 ilm policy,以及对应 index 的别名。
- 2.新建索引与别名,注意新建索引的时候,为便于内部管理及可视化,最好通过 es 的 date math 来创建索引
- 3.新建 ilm policy,这里就涉及不同相的变化,如 HOT WARM DELETE等
es Date math涉及带日期的索引名,详见:
应用
比如我们的 template 可以是以下这样的:
python
demo_template = {
"index_patterns": ["demolog-*"], # 通过模板关联的索引
"settings": {
"number_of_shards": 1, # 如果是集群,建议与集群data节点数保持一致
"number_of_replicas": 0, # 副本分片数
"priority": 10, # 优先级
"index.lifecycle.name": "demo_ilm", # ilm name
"index.lifecycle.rollover_alias": demo_alias # rollover别名,一定要设置
}
# 可以设置mappings
}
我们的索引及别名:
ini
# upper
demoLog_index = "%3Cdemolog-%7Bnow%2Fd%7D-000001%3E" # <demolog-{now/d}>
demo_alias = "demolog"
ilm policy:
python
# only 3 status,
# hot -> write and read,
# warm -> only read,
# delete -> about to delete
demo_ilm_policy = {
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": { # 下面触发条件为或关系,满足一条即可
"max_age": "1d", # 为方便看得到效果,设置最大时间1天,也可以 30m 或者 7d,d-天, h-小时,m-分钟
"max_docs": 100, # 文档数100
"max_size": "10GB", # 文档总大小
# "max_primary_shard_size": "10GB" # 主分片大小容量
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "1d",
"actions": {
"readonly": {},
"set_priority": {
"priority": 50
}
}
},
"delete": {
"min_age": "3d",
"actions": {
"delete": {}
}
}
}
}
}
以下就是我们的初始化脚本:
python
ilm_policy_url = "_ilm/policy/demo_ilm"
class ESClient:
@staticmethod
def get_instance():
return Elasticsearch(hosts=hosts, timeout=timeout)
class ILM_Usage:
"""
1.set template
2.set index and alias
3.set ilm policy
"""
def __init__(self):
self.es = ESClient.get_instance()
self.init()
def init(self):
self.set_template()
self.set_index_and_alias()
self.set_ilm_policy()
def set_template(self):
if not self.es.indices.exists_template(name="demo_template"):
# 创建 <index-date-000001>
requests.put("{}{}".format(hosts, demoLog_index))
self.es.indices.put_template(name="demo_template", body=demo_template)
print("es template: demo_business has init success!")
"""
kibana operate work
req:
PUT %3Cdemolog-%7Bnow%2Fd%7D-000001%3E
{
"aliases": {
"demoLog": {
"is_write_index": true
}
}
}
resp:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "demolog-2024.03.21-000001"
}
"""
def set_index_and_alias(self):
if not self.es.indices.exists_alias(index=demo_alias):
try:
# self.es.indices.create(index=demoLog_index)
self.es.indices.put_alias(index="demolog-*", name=demo_alias, body={"is_write_index": True})
except Exception as e:
print(e)
print("es alias settings has init success!")
def set_ilm_policy(self):
policy_url = hosts + ilm_policy_url
resp = requests.get(policy_url, timeout=timeout, auth=auth)
if resp.status_code == 200:
print("ilm policy has init!")
return
resp = requests.put(policy_url, json=demo_ilm_policy, auth=auth)
if resp.status_code == 200:
print("es ilm policy init success!")
为什么创建索引的时候不是用 es的 create api呢,如果你用过就知道,一定会报错,创建会失败,查看 es 客户端的源码,其实每次请求都是构造一个 restful 风格,然后根据 method 调用 requests 库来执行,然后将返回的数据再通过反序列化得到响应数据,既然直接走 create 不通,那就通过 requests,实际测试发现是可用的。
其他脚本
灌数据脚本
python
class Insert_Docs:
def __init__(self):
self.es = ESClient.get_instance()
def run(self):
while True:
self.post_doc()
time.sleep(random.randint(1, 100))
def gen_doc(self):
log = {
"name": str(uuid.uuid4())[:10],
"@timestamp": str(datetime.datetime.now()),
"timestamp": round(time.time(), 3)
}
return log
def post_doc(self):
for i in range(999):
log = self.gen_doc()
self.es.index(index="my-write-alias", doc_type="_doc", body=log)
print("i: {}, insert doc into es, doc:{}".format(i, log))
time.sleep(random.random())
Kibana涉及的相关命令
bash
# ilm api
GET _ilm/policy/demo_ilm/
# 对应别名下的具体索引
GET _alias/demolog
# ilm状态
GET _ilm/status
# 查询doc
GET demolog/_search
{
"sort": [
{
"timestamp": {
"order": "asc"
}
}
]
}
# 索引的增删查
GET _cat/indices/demo*
# 删除索引
DELETE demolog-2024.03.21-000001
# 新建索引 -> demolog-2024.03.21-000001,注意索引名不能带大写字母,es内部规定
PUT %3Cdemolog-%7Bnow%2Fd%7D-000001%3E
# 新建索引的同时关联别名
PUT %3Cdemolog-%7Bnow%2Fd%7D-000001%3E
{
"aliases": {
"demoLog": {
"is_write_index": true
}
}
}
# 删除索引别名,add是新建
POST /_aliases
{
"actions": [
{
"remove": {
"index": "demolog-*",
"alias": "demoLog"
}
}
]
}
# 删除别名
DELETE demoLog
# 查看别名
GET _template/demo_template
# 删除别名
DELETE _template/demo_template
关于别名更多的操作:
希望以上内容能帮到你实现 ilm 的应用。