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

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

相关推荐
沈韶珺34 分钟前
Visual Basic语言的云计算
开发语言·后端·golang
沈韶珺41 分钟前
Perl语言的函数实现
开发语言·后端·golang
美味小鱼1 小时前
Rust 所有权特性详解
开发语言·后端·rust
我的K84091 小时前
Spring Boot基本项目结构
java·spring boot·后端
慕璃嫣2 小时前
Haskell语言的多线程编程
开发语言·后端·golang
晴空๓2 小时前
Spring Boot项目如何使用MyBatis实现分页查询
spring boot·后端·mybatis
Hello.Reader6 小时前
深入浅出 Rust 的强大 match 表达式
开发语言·后端·rust
customer0810 小时前
【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
计算机-秋大田12 小时前
基于微信小程序的电子竞技信息交流平台设计与实现(LW+源码+讲解)
spring boot·后端·微信小程序·小程序·课程设计