当前位置: 首页 > news >正文

Easysearch 索引别名(Index Alias)详解

在 Easysearch 中,索引别名(Index Alias) 是一种逻辑名称,它可以指向一个或多个真实索引。
使用别名的好处在于:

  • 让应用层无需感知底层索引名变化;
  • 方便进行索引切换、版本升级和数据迁移;
  • 支持查询、写入、过滤、路由等控制;
  • 实现读写分离或权限隔离。

简而言之,别名是索引的抽象层,就像数据库中的“视图(View)”或操作系统中的“符号链接(symlink)”。

创建索引别名

别名可以在创建索引时定义,也可以在已有索引上添加。

在创建索引时定义别名
PUT /logs_2025-10
{"aliases": {"logs_current": {}}
}

该操作创建索引 logs_2025-10,并同时定义一个别名 logs_current

之后,所有针对 logs_current 的查询都会路由到 logs_2025-10

POST logs_2025-10/_doc
{"age":20}GET /logs_current/_search

给现有索引添加别名
POST /logs_2025-10/_alias/logs_current_v2

或者使用 _aliases 批量操作:

POST /_aliases
{"actions": [{ "add": { "index": "logs_2025-10", "alias": "logs_current_v3" }}]
}

image-20251006083715981

查询与写入的区别

默认情况下,别名仅支持查询
如果一个别名指向多个索引,那么写入(POST /alias/_doc)操作会报错。

{"error": {"root_cause": [{"type": "illegal_argument_exception","reason": "no write index is defined for alias [logs_current_v2]. The write index may be explicitly disabled using is_write_index=false or the alias points to multiple indices without one being designated as a write index"}],"type": "illegal_argument_exception","reason": "no write index is defined for alias [logs_current_v2]. The write index may be explicitly disabled using is_write_index=false or the alias points to multiple indices without one being designated as a write index"},"status": 400
}

image-20251006084352866

为了解决这一问题,可以通过 is_write_index 参数指定某个索引作为写入目标。

POST /_aliases
{"actions": [{ "add": { "index": "logs_2025-10-01", "alias": "logs_all" }},{ "add": { "index": "logs_2025-10-02", "alias": "logs_all", "is_write_index": true }}]
}

此时:

  • 查询 GET /logs_all/_search 会同时检索两个索引;
  • 写入 POST /logs_all/_doc 时,数据会写入 logs_2025-10

动态切换索引(零停机升级)

别名的最大优势之一是实现索引的无缝切换

例如,应用程序始终通过 logs_all 查询数据,而底层实际索引会按天数变化。

切换示例:

POST /_aliases
{"actions": [{ "remove": { "index": "logs_2025-10-01", "alias": "logs_all" }},{ "add": { "index": "logs_2025-10-03", "alias": "logs_all" }}]
}

这里我移除了logs_2025-10-01,然后添加了logs_2025-10-03。

可以使用GET /_cat/aliases?v查看。

image-20251006085901163

过滤别名(Filtered Alias)

别名还可以定义过滤条件,控制用户只能看到部分数据。
这是实现数据分区视图或权限隔离的常见方式。

它展示如何让一个别名只返回 region=china 的文档,而不暴露其他地区的数据。

1. 创建一个示例索引并插入数据
PUT /transactions
{"mappings": {"properties": {"region": { "type": "keyword" },"user":   { "type": "keyword" },"amount": { "type": "float" }}}
}POST /transactions/_bulk
{ "index": { "_id": 1 } }
{ "region": "china", "user": "alice", "amount": 100.0 }
{ "index": { "_id": 2 } }
{ "region": "usa", "user": "bob", "amount": 200.0 }
{ "index": { "_id": 3 } }
{ "region": "china", "user": "cindy", "amount": 150.0 }
{ "index": { "_id": 4 } }
{ "region": "japan", "user": "daisuke", "amount": 300.0 }

刷新索引:

POST /transactions/_refresh
创建过滤别名

定义一个只允许访问中国区数据的别名:

POST /_aliases
{"actions": [{"add": {"index": "transactions","alias": "transactions_cn","filter": {"term": { "region": "china" }}}}]
}
使用过滤别名查询
GET /transactions_cn/_search

返回结果类似:

{"hits": {"hits": [{"_id": "1","_source": { "region": "china", "user": "alice", "amount": 100.0 }},{"_id": "3","_source": { "region": "china", "user": "cindy", "amount": 150.0 }}]}
}

可以看到:

  • 来自 usajapan 的记录不会出现在结果中;
  • 别名层面自动做了过滤;
  • 应用层调用时完全不需要在查询语句中加 term 条件。

image-20251006090520921

路由别名(Routing Alias)

Elasticsearch 的数据分片(sharding)是通过一个公式决定的:

shard = hash(routing) % number_of_primary_shards
  • 默认情况下,routing = _id
  • 但如果你有多租户、分国家、分部门的场景,可以用业务逻辑字段当作 routing。
  • routing 相同的数据会落在同一个分片上,提高写入和查询的性能。

因此:

把别名和 routing 绑定起来,可以实现“逻辑分区 + 性能优化 + 查询隔离”。

下面通过一个完整的数据例子演示。

创建索引
PUT users
{"settings": {"number_of_shards": 4,"number_of_replicas": 0},"mappings": {"properties": {"name": { "type": "keyword" },"country": { "type": "keyword" },"age": { "type": "integer" }}}
}
创建带 routing 的别名
POST /_aliases
{"actions": [{"add": {"index": "users","alias": "users_cn","routing": "china"}},{"add": {"index": "users","alias": "users_us","routing": "usa"}}]
}

✅ 我们现在有两个逻辑视图:

AliasRouting用途
users_cn"china"代表中国用户
users_us"usa"代表美国用户
通过别名写入数据
POST users_cn/_doc
{"name": "张伟","country": "CN","age": 29
}POST users_cn/_doc
{"name": "王芳","country": "CN","age": 34
}POST users_us/_doc
{"name": "John","country": "US","age": 42
}POST users_us/_doc
{"name": "Emily","country": "US","age": 31
}

✅ 实际都写入到同一个物理索引 users
但数据被根据 routing(china / usa)分到了不同分片。

4️⃣ 验证分片路由情况

GET users/_search_shards

返回示例:

{"nodes": {"mIS34pJJRrWWYDERAJLuqw": {"name": "node-1","ephemeral_id": "BgJLaTndTAWGxDGri8125w","transport_address": "172.100.1.2:9300","attributes": {}}},"indices": {"users": {}},"shards": [[{"state": "STARTED","primary": true,"node": "mIS34pJJRrWWYDERAJLuqw","relocating_node": null,"shard": 0,"index": "users","allocation_id": {"id": "XT6Ds-NTSb-hhUeNCeHHjA"}}],[{"state": "STARTED","primary": true,"node": "mIS34pJJRrWWYDERAJLuqw","relocating_node": null,"shard": 1,"index": "users","allocation_id": {"id": "74BEgGYOTOO0tg7kVXtvDA"}}],[{"state": "STARTED","primary": true,"node": "mIS34pJJRrWWYDERAJLuqw","relocating_node": null,"shard": 2,"index": "users","allocation_id": {"id": "9hdcuoz5TbWql3kipudCxA"}}],[{"state": "STARTED","primary": true,"node": "mIS34pJJRrWWYDERAJLuqw","relocating_node": null,"shard": 3,"index": "users","allocation_id": {"id": "h0esaYy8QJmvfiGLjn3Zwg"}}]]
}

image-20251006113500768

查询数据
查询中国区用户:
GET users_cn/_search

输出:

{"hits": {"total": 2,"hits": [{"_source": {"name": "张伟", "age": 29}},{"_source": {"name": "王芳", "age": 34}}]}
}
查询美国区用户:
GET users_us/_search

输出:

{"hits": {"total": 2,"hits": [{"_source": {"name": "John", "age": 42}},{"_source": {"name": "Emily", "age": 31}}]}
}
如果直接查物理索引
GET users/_search

返回所有 4 条记录,因为没带 routing。

再加一个过滤型 alias(可选)
POST /_aliases
{"actions": [{"add": {"index": "users","alias": "users_adults","filter": { "range": { "age": { "gte": 30 } } }}}]
}

然后查询:

GET users_adults/_search

→ 只返回 王芳(34岁)和 John(42岁)和Emily(31岁)。


场景routing 带来的好处
写入相同 routing 的文档总是写入同一分片,减少 shard 跳转
查询查询时只访问一个 shard,速度可提升数倍
多租户每个租户 routing 不同,实现物理隔离
地域分区中国区、美国区等逻辑分区共享同一个索引

查看与删除别名

查看当前集群中所有别名:

GET /_cat/aliases?v

输出结果:

alias          index          filter  routing.index  routing.search  is_write_index
logs_current   logs_2025-10   -       -              -               -
logs_all       logs_2025-10   -       -              -               true

删除别名:

DELETE /logs_2025-10/_alias/logs_current

或:

POST /_aliases
{"actions": [{ "remove": { "index": "logs_2025-10", "alias": "logs_current" }}]
}

总结

Easysearch 的索引别名是一个轻量、强大且几乎“零成本”的机制,它在索引生命周期管理中起着核心作用。

合理使用别名,可以实现:

  • 热切换(零停机索引迁移);
  • 分片控制(按租户或地理位置隔离);
  • 安全访问(按条件过滤可见数据);
  • 持续演进(读写分离 + 版本平滑过渡)。

对于任何生产环境的 Easysearch 集群来说,别名是不可或缺的基础能力

http://www.dtcms.com/a/449512.html

相关文章:

  • 安徽省港航建设投资集团网站wordpress图片清晰度
  • 网站交互性企业营销型网站建设规划
  • 无锡设计网站公司微信小程序登录流程
  • GraphQL 工程化篇 I - REST vs GraphQL 的取舍与基础配置
  • springboot二手儿童绘本交易系统设计与实现(代码+数据库+LW)
  • 如何解决 pip install -r requirements.txt 本地轮子路径 ‘./packages/xxx.whl’ 不存在 问题
  • 西宁好的网站建设智慧工业园区建设方案
  • Kotlin Flow 与“天然背压”(完整示例)
  • Kotlin invoke 函数调用重载
  • 郑州网站建设培训学校昆明怎样优化网站
  • XMLHttpRequest 异步请求servlet 上传文件并且带有参数
  • Python私教FastAPI+React构建Web应用01 概述
  • 深入理解操作系统进程:管理的本质与“先描述,再组织“的核心逻辑
  • 网站手机自适应无锡产品排名优化
  • 深度学习(十五):Dropout
  • 收录提交大全成都百度seo推广
  • wordpress本地更换为网站域名龙华区网站建设
  • 高佣金返利平台的数据一致性挑战:基于Seata的分布式事务解决方案与补偿机制设计
  • 外包网站开发多少钱安监局网站做应急预案备案
  • go build命令
  • Go语言入门(22)-goroutine
  • 网站建设及编辑岗位职责网站做查赚钱
  • 开源革命下的研发突围:Meta Llama系列模型的知识整合实践与启示
  • 做的网站怎样更新排名优化网站seo排名
  • 鸿蒙NEXT网络通信实战:使用HTTP协议进行网络请求
  • FastApi项目启动失败 got an unexpected keyword argument ‘loop_factory‘
  • 杭州有专业做网站的吗用.net做购物网站
  • 什么是 mesh 组网
  • 网站建设什么行业创建个人网站教案
  • 十五、深入理解 SELinux