elasticsearch ilm 再学习与实战

了解

如果你对 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 可以是以下这样的:

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
}

我们的索引及别名:

# upper
demoLog_index = "%3Cdemolog-%7Bnow%2Fd%7D-000001%3E" # <demolog-{now/d}>
demo_alias = "demolog"

ilm policy:

# 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": {}
                }
            }
        }
    }
}

以下就是我们的初始化脚本:

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,实际测试发现是可用的。

其他脚本

灌数据脚本

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涉及的相关命令

# 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 的应用。

posted on 2024-03-21 16:01  进击的davis  阅读(19)  评论(0编辑  收藏  举报

导航