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

相关推荐
嘉伟桑1 小时前
Python调用电价API返回JSON示例:分时电价、现货电价和字段解析
后端
武子康1 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端
我叫黑大帅2 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
AskHarries2 小时前
文件上传系统
后端
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn3 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530143 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908403 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端