Appearance
Elasticsearch 索引创建与搜索原理
索引与分片结构
- 一个 Elasticsearch 索引由一个或多个分片(Primary Shards)组成。
- 每个分片会进一步由多个 segment(段)构成,每个 segment 是一个独立的倒排索引。
- segment 一旦写入后即不可变,通过段合并(segment merge)来减少段的数量并提高查询效率。
写入流程与原理
写入请求路由
- 客户端向任意节点(如
node1
)发送写入请求,该节点作为协调节点(Coordinating Node)。 - 协调节点通过
_id
使用路由算法shard = hash(routing) % number_of_primary_shards
确定文档应该存储的主分片。注意:分片的数量在索引创建时确定,后期只能通过reIndex重建索引 - 协调节点将文档发送至对应主分片所在的节点(如
node2
)。主分片节点将文档写入本地,并同步到相应的副本分片。 - 所有分片写入成功后,向协调节点返回成功响应,最终返回给客户端。
- 客户端向任意节点(如
写入缓冲与可见性
- 文档写入时会先记录到 translog(事务日志,存储于磁盘),并暂存于 in-memory buffer(内存缓冲区)。
- 在完成写入后,刚写入的文档尚不可检索。只有在执行了 refresh 操作后,文档才会对搜索可见。
Refresh 操作
refresh_interval
(默认 1s)由 Elasticsearch 定期触发或手动调用_refresh
接口,创建一个新的搜索器视图。- 执行过程:
- 将 in-memory buffer 中的文档写入新的 segment(存储于磁盘)。
- 清空 in-memory buffer,但不会清空 translog。
- 创建新的搜索器,使新写入的文档可被查询到。
- 由于 segment 是不可变的,频繁的 refresh 会导致小 segment 过多,需要通过后台的 segment merge 来优化。
Flush 操作
- Flush 主要用于生成安全的提交点(commit),确保数据持久化并清空 translog。
- 执行过程:
- 将还未刷新到 segment 的文档写入新的 segment 并执行 Lucene commit,确保数据安全落盘。
- 清空 translog(因为有了最新的 commit 点,重启时可从 segment 重建索引状态)。
- 注意:Flush 并不是段合并操作,段合并是由 Elasticsearch 的后台进程定期执行,以减少 segment 数量提升检索性能。
查询与检索过程(Query Then Fetch)
默认查询模式:QUERY_THEN_FETCH
查询阶段(Query)
- 客户端发送查询请求至协调节点(如
node1
)。 - 协调节点将查询分发至每个包含数据的分片(主分片或副本分片),在本地执行查询。
- 每个分片根据查询结果对文档打分,并按
from+size
限制返回最高分的文档 ID 和相关排序信息给协调节点。 - 协调节点汇总各分片的初步结果并进行全局排序,以确定最终要返回的文档集合。
- 客户端发送查询请求至协调节点(如
取回阶段(Fetch)
- 协调节点根据全局排序结果,向对应分片节点发送 fetch 请求,获取实际的文档内容(如 _source)。
- 分片节点返回文档给协调节点,协调节点等待所有相关分片的数据返回完成后,将最终排序和聚合好的结果返回给客户端。
集群规划及节点角色规划最佳实践
如何划分 候选主节点
- 创建或删除索引、分片分配
- 重要性:拥有一个稳定的主节点对于集群健康的很重要
- 经投票选举为主节点 协调节点
- 智能负载均衡器
- 分散(scatter),收集(gather) 数据节点
- CRUD,搜索和聚合
- I/o 密集型、内存密集型和cpu密集型 ingest 节点
- 写入前的数据预处理
角色 | 描述 | 存储 | 内存 | 计算 | 网络 |
---|---|---|---|---|---|
数据节点 | 存储和检索数据 | 极高 | 高 | 高 | 中 |
主节点 | 管理集群状态 | 低 | 低 | 低 | 低 |
Ingest 节点 | 转换输入数据 | 低 | 中 | 高 | 中 |
机器信息节点 | 机器学习 | 低 | 极高 | 极高 | 中 |
协调节点 | 请求转发和合并检索结果 | 低 | 中 | 中 | 中 |
实战建议
- 不混合部署
- 一台物理或者虚拟机只部署一个接节点
- 不混合部署其他应用,如 redis、kafka 等
- 大的集群一定要独立节点角色
- 不建议将主节点作为协调节点,尽可能有独立的协调节点
- 不建议将主节点和数据节点混合角色部署,确保角色单一
- 客户端链接的节点配置为协调接节点
- 超大规模集群建议
- 独立:3主 + 3协调 + 其他数据节点
- 主节点建议配置: 8C16G以上
- 写入量大优先建议:32C64GB配置(5W/s写入)
集群 在实际的开发之前,需要对集群的配置进行规划
硬件层面
- CPU
- 内存
- 堆内存:可用RAM的50%,最多最大32GB RAM
- 对外内存:缓存数据(Lucene 使用),通过避免在全文检索、文档聚合和排序环节的磁盘读取,极大地提高了性能
- 磁盘
- 固态硬盘:提供最佳 “热” 工作负载的性能
- 普通磁盘:用于“暖”和“冷”数据存储
- 网络
- 针对大规模集群,ingest、搜索和副本复制相关的数据传输可能会导致网络饱和
节点规划
分片和副本规划
用途
- 分片:
- 提高系统水平扩展能力,单台服务器提供的能力是有限的,需要水平扩展
- 分割巨大索引,让读写并行操作
- 副本分片:
- 增强系统的高可用性
- 主节点故障时的数据转移
- 增加的读取吞吐量
- 副本分片数支持动态修改
主分片数量设置不合理
分片设置过少
一旦检索出故障,极难恢复 无法充分利用节点资源,造成机器资源利用率不高或不均衡 影响写入/查询的效率
分片设置过多
线上反馈:分片量极多,打开文件多,导致集群挂掉 索引和分片管理可能会使主节点超载,并可能会导致集群无响应,甚至导致集群宕机 批量写入/查询请求被分割为过多的子写入/查询 跨大量分片的搜索会耗尽节点的搜索线程池。这会导致低吞吐量和缓慢的搜索速度 导致该index的写入,查询拒绝率上升。每个分片都使用内存和CPU资源。在大多数情况下,一小组大分片比许多小分片使用更少的资源
分片设置
- 单 Segment 支持文档数:2的32次幂 20亿
- Shard 大小官方建议:30GB-50GB
- 1GB 堆内存:建议支持:20-30个分片
- 各个节点相对均衡分配分片:index.routing.allocation.totalshardsper_node
- 单节点支持分片数:
- 不建议超过1000 (cluster.max_shards_per_node 默认值:1000)
数据量方面:
- 数据量较小(100GB以下)索引
- 写入压力查询压力相对较低
- 一般设置3-5个shard(根据节点数),副本设置为1
- 数据量较大(100GB以上)的索引
- 单个shard的数据量控制在(30GB-50GB)让 index 压力分摊至多个节点
- 可通过index.routing.allocation.totalshardsper_node参数,分片均匀发布
- 集群规模大以后
- 如果shard 数量(不包含副本)超过50个,就很可能引发拒绝率上升的问题
- 可考虑把该index拆分为多个独立的index,分摊数据量,考虑:rollver或者ilm
- 配合routing使用,降低每个查询需要访问的shard数量
容量规划
需要考虑的点 基础数据
- 每天将索引多少原始数据
- 保留数据多少天
- 每天增量数据是多少
- 设置多少个副本
- 数据节点内存多大
- 内存:数据比率是多少 增量数据
- 预留15%警戒磁盘水位空间
- 为错误余量和后台活动预留+5%
计算规则 总数据量(GB): 每天原始数据量(GB)* 保留天数 * 净膨胀系数 * (副本+1) 磁盘存储(GB): 总数据量(GB)* (1 + 0.15 + 0.05) 数据节点 向上取值(磁盘存储(GB)/(每个数据节点的磁盘空间*0.85) + 1)
工具: 测量机器指标:esrally
集群性能调优及原理
1. 性能调优整体思路
1.1 硬件资源优化
CPU(线程池和队列)
- 线程池类型:Search Thread Pool(
search
/suggest
/count
等) - 参数设置:建议
search thread pool
大小为 int((# of allocated processors * 3)/2)+1,需要根据集群 CPU 数量、实际查询负载进行动态调优。
- 线程池类型:Search Thread Pool(
内存
- JVM 堆内存:堆设置为系统内存的 50%,但不超过 32GB
- 堆外内存:其余内存可做文件系统缓存( Lucene 段文件等),能有效加快检索速度。
磁盘
- SSD:对性能要求较高的场景优先使用 SSD。
- 本地存储:避免使用 NFS、SMB 等远程文件系统,以免产生网络和 I/O 的双重瓶颈。
1.2 参数与集群配置调优
写入进程独占节点
- 在集群规模允许的情况下,将大批量写入的负载独立到专门的节点上,避免对检索造成严重干扰。
写入与检索一致的路由设置
- 写入时通过路由将同一业务数据写入相同分片;检索时同样指定路由,可显著减少查询所需的分片范围。
Index Sorting
- 对符合排序需求的字段提前进行排序,可以显著减少查询阶段的数据扫描量,提高检索速度。
1.3 调优经验
使用缓存
- 合理利用操作系统的文件系统缓存。
- 使用
filter
查询时不参与打分,可极大提高缓存命中效率。
“不不不不” 策略
- 不使用前缀模糊匹配(
wildcard
)等高成本查询,如非必要可使用ngram
或match_phrase+slop
方案替代。 - 不进行深度分页(
from-size
过大对性能影响严重)。 - 不返回不必要的字段(通过
_source
、stored_fields
控制)。 - 不执行过于复杂的嵌套聚合(
nested
、join
需谨慎,建模时尽量避免过度关联)。
- 不使用前缀模糊匹配(
查询语句优化
- 使用针对性强的查询方式(例如
match_phrase
替代match
)。 - 合理拆分与合并查询,减少多次 IO 开销。
- 使用针对性强的查询方式(例如
数据模型优化
- 尽量避免复杂关联,能使用“宽表”就不再分多张表(
join
和nested
会造成额外开销)。 - 对数据分层:将高频(热)数据与低频(冷)数据分离,冷热数据可置于不同硬件(SSD / SATA)。
- 在系统初始化或更新后对常用数据做“预热”,让操作系统或 ES Cache 提前加载相关数据。
- 尽量避免复杂关联,能使用“宽表”就不再分多张表(
3. 检索性能调优
3.1 常见检索类型及优化点
Wildcard 查询
- 高危操作,能不用尽量不用,极易导致集群过载。
- 如果必须使用,可通过
ngram
分词或match_phrase
(配合slop
)等方式变通。 - 避免以通配符开头,如
*foo
或正则.*foo
。 - 避免让终端用户直接使用正则表达式(封装白名单或限流逻辑)。
match_phrase
替代match
match_phrase
精度更高,可减少无关文档干扰。- 若需更高检索精度,可在分词(字、词混合)上做进一步优化。
query_string
- 对复杂的布尔逻辑(与/或/非等表达式)检索,可直接使用
query_string
,少造轮子。
- 对复杂的布尔逻辑(与/或/非等表达式)检索,可直接使用
合并检索
- 一次性执行多个条件组合检索效率通常高于多次分别检索。
range
查询替换- 如果字段取值种类较少(如情感极性:正面、负面、中性),建议改用
term
精确匹配。
- 如果字段取值种类较少(如情感极性:正面、负面、中性),建议改用
充分利用缓存
- 无需打分的查询可使用
filter
,可大大提高命中率。
- 无需打分的查询可使用
最大化优化 DSL
- 仅检索并返回需要的字段,
_source
或stored_fields
中不要过度包含无关数据。
- 仅检索并返回需要的字段,
聚合优化
- 聚合结果默认是非精确的 Top-N,若要全量计算会带来显著性能开销。
- 若业务可接受近似值,可用分段统计或限制聚合深度来提升速度。
深度翻页问题
from-size
:单次请求上限是 10,000 个文档,过大的from-size
会降低性能。scroll
:适合离线批量查询或分页;但不适用于实时更新场景。search_after
:支持实时翻页,但在大规模数据上也需合理设计索引和排序。- 业务侧应尽量规避全量聚合、全量翻页。
避免返回大数据集
- 批量处理使用
Scroll API
,并适度控制size
。 - 高亮或大字段会带来更多 I/O 和缓存开销,必要时只索引/存储关键字段。
- 计数场景使用
_count
接口。
- 批量处理使用
冷热数据隔离
- 对写入和检索压力大的近期数据,放置在 SSD 等高性能存储中。
- 将历史数据迁移到普通 SATA 盘,结合 ES 的 ILM(Index Lifecycle Management)或
rollover + 别名 + curator
策略管理。
4. 写入性能调优
副本分片设置
- 写入前可将副本数调为
0
,待写入完成后再恢复正常副本数。
- 写入前可将副本数调为
ID 生成
- 优先使用系统自动生成的
_id
,避免自定义 ID 带来的额外索引开销。
- 优先使用系统自动生成的
刷新频率
- 调大
refresh_interval
(如 30s 甚至更长),可减少 segment merge 对写入的影响。
- 调大
索引缓冲区大小
- 合理调大
index_buffer
以减少频繁的写入及合并,但需留意 JVM 堆大小。
- 合理调大
保证堆外内存空间
- Lucene 会利用文件系统缓存提升写入和查询性能,应保留一半以上物理内存给操作系统。
Bulk 批量写入
- 批量写入的吞吐量远高于单条写入,并可减少网络开销和索引合并频率。
多线程并发
- 在客户端或中间层进行多线程并发写入,结合 Bulk 进一步提升效率。
线程池与队列大小
- 调整
write
/bulk
等线程池大小以及队列长度,避免任务排队阻塞。
- 调整
合理设置 Mapping
- 生产环境中不建议使用默认
dynamic mapping
,要对业务字段(text、keyword、number 等)进行手动定义。 - 例如中文分词可指定 IK 分词(
ik_smart
/ik_max_word
),结合业务场景调整。
- 生产环境中不建议使用默认
分词器选择
- 分词器的粒度决定了检索和写入成本:越细的分词,索引体量越大,但召回效果更好。
- 根据查询场景评估召回率、精确率与写入代价,选择合适的分词策略。
- 磁盘选择
- 针对写入非常密集的场景,SSD 依旧是最有效的“终极手段”之一。
- 集群节点角色拆分
- 当集群规模较大时,建议单独的主节点、数据节点、协调节点。
- 拆分角色能减轻节点压力,提高写入与检索效率。
- 官方客户端
- 使用官方 Elasticsearch 客户端(Java、Go 等),其连接池与连接管理更优化,更易与 ES 新版本特性保持兼容。
5. 典型实战问题分析
5.1 用户画像宽表性能问题
问题场景
- 许多团队使用 ES 做用户画像,常常索引里包含上千字段,甚至超过 1000 个字段后出现性能问题。
解决思路
- 字段裁剪:检查业务实际所需字段,尽量避免存储或索引无关字段。
- Mapping 优化:在字段类型、索引方式(
text
、keyword
、nested
等)上仔细设计,不要盲目使用默认配置。 - 索引分拆:将超大宽表按业务场景、字段分组拆分为多个索引或使用索引模式(index pattern)。
- 数据模型:宽表虽然在查询端简单,但写入和存储成本非常高。可以考虑冷热分区、按时间或业务范围进行分区。
5.2 高写入量导致查询性能下降
问题场景
- 监控到
indexing rate
达到 5w/s(5 万条每秒),查询性能直线下降。
解决思路
- 专用写入节点:把写入操作和检索压力物理隔离。
- Bulk 写入:批量写入可显著减少段合并与网络开销。
- 刷新频率:适度调大
refresh_interval
。 - 分片数量:检查是否分片过多导致写入及管理开销高,反之也要保证分片数足够支撑吞吐量。
- 线程池:对
search
与write
线程池进行独立配置。 - 冷热数据:将存量数据或历史数据迁移到冷节点,腾出硬件资源给新数据写入。
5.3 一次召回文档 4000 篇,如何在 30ms 内完成?
问题场景
- 做资讯/内容推荐,需要一次性召回 4000 篇文档,目标耗时不超过 30ms。
可能的解决思路
- 路由或索引拆分:如果可以提前确定召回范围,采用路由以减少分片查询数。
- 预热与缓存:将常用查询或热门数据在应用启动时或定时进行预热。
- Hardware & 角色分离:利用 SSD、充足内存,并尽可能地拆分协调节点和数据节点,以保证查询的并行度。
- DSL 精简:仅返回必要字段,减少网络与反序列化开销。
- Index Sorting:对常用的排序字段进行预排序,减少搜索过程中的排序代价。
5.4 检索 30 天数据,1.9 亿条记录,耗时达 50s,慢在哪?
问题场景
- 三台服务器(各 8 核 32GB),每节点给 ES 分配 6GB 堆内存,其余资源给其他服务。
- 每天创建一个索引,6 个分片,默认副本数,当前大约有 180 个分片,每个索引 20GB,数据量合计约 1.9 亿条。
- Kibana 查询默认过去 30 天,不加任何过滤条件,导致查询耗时达 50s。
可能的瓶颈
- 查询无过滤条件:ES 需要扫描所有索引的全部分片,开销巨大。
- 内存不足:每节点仅 6GB Heap,且系统缓存也有限,无法对海量 segment 做充分缓存。
- 过多分片:分片过多会带来额外的
shard request
开销和集群管理负担。 - 聚合/排序:如果 Kibana 可视化中包含全量聚合或复杂聚合,也会大幅拖慢速度。
优化建议
- 查询范围收缩:让用户先做业务侧过滤或时间范围细分,避免默认一次性扫 1.9 亿条。
- 分片数量调整:对老索引做合并或减少分片,保证单分片大小合理(几十 GB ~ 百 GB 级)。
- 内存优化:在有条件的情况下增大 ES 堆内存(但不超过 32GB),并保留充足的系统内存用于文件系统缓存。
- 冷热数据架构:近期热门索引存放在性能更佳的节点或 SSD 盘,旧索引迁移至冷节点。
- 合理聚合:在可接受的情况下减少聚合粒度或使用近似算法(例如
composite
聚合)。
6. 工具推荐
Cerebro
- 一款第三方可视化管理工具,类似于 Kopf、Head,用于监控和管理 ES 集群。
Kibana 自带 Monitoring
- 官方提供的监控工具,集成度高,能可视化集群健康度、节点负载、索引写入率等多种指标。
数据建模最佳实践
建模的意义
客户实战问题
- 分片数喝副本数大小如何设计,才能提升es 集群的性能?
- es 的mapping 该如何设计,才能保证高效写入或检索?
- 分词该如何设计,才能满足复杂业务场景需求?
- 传统数据库中的多表关联在es 中如何设计?
- 每日几百GB 增量实时数据的TB级甚至PB级别的大索引如何设计?
- 检索类型 term/match/match_phrase/querystring/match_phrase_prefix/fuzzy 那么多,设计阶段如何设计
实战
Settings:
- static:
- index.number_of_shards
- index.number_of_routing_shards
- dynamic:
- index.number_of_replicas
- index.refresh_interval
- index.max_result_window
- index.max_terms_count
- index.default_pipeline
单索引建模
Settings
分片/副本设置
分片
- 避免分片过大,因为这样会对集群从故障中恢复造成不利 影响。人们通常将 50GB 作为分片上限,而且这一限值在各种用例中都已得到验证。
- 分片过小会导致段过小,进而致使开销增加对时序型数据用例而言,分片大小通常介于 20GB 至 40GB 之间。
- 每 GB 堆内存对应20个分片,一个拥有 30GB 堆内存的节点最多应该有 600 个分片。
- Lucene 单segment 最大支持文档数:2的32次幂-1,也就是21亿(2,147,483,648)左右。
副本
- 对于集群数据节点 >=2 的场景:建议副本至少设置为 1
- 单节点的机器设置了副本也不会生效的。
- 副本数的设计结合数据的安全需要。
刷新频率设置
缺省pipeline设置
Mapping
认证前提
- ES 支持新增Mapping字段
- ES 不支持直接删除Mapping字段
- ES 不支持直接修改Mapping字段
- ES 不支持直接修改Mapping字段类型
- 如果非要做灵活设计,借助reindex。
- 但是数据量大会有性能问题,建议设计阶段综合权衡考虑。
字段类型敲定
es 数据类型:
- 核心数据类型
- string: text and keyword
- Numeric: long,integer,short,byte,double,float,half_float,scaled_float
- Date: date
- Date nanoseconds: date_nanos
- Boolean: boolean
- Binary: binary
- Range: integer_range,float_range,long_range,double_range,date_range,ip_range
- 复杂数据类型
- object
- nested
- GEO 数据类型
- Geo-point
- Geo-shape
- 特定数据类型
- IP
- Completion datatype
- Token count
- mapper-murmur3
- mapper-annotated-text
- Percolator
- Join
- Rank feature
- Rank features
- Dense vector
- Sparse vector
- Search-as-you-type
- Alias
- Flattened
- Shape
- Histogram
- Constant keyword
- 尽量避免动态映射
- 了解各种 datatype 的含义,为字段选择原则上正确的 datatype
- 了解text和keyword的区别,term query应该使用keyword
- 知道何时使用array,nested,parent-child(Join)类型
js
{
"mappings": {
"dynamic": "strict"
}
}
- 能够根据业务的需求,选择最合适的的类型和参数
- 不用来聚合和排序的字段,关闭 doc_value(正排索引)
- 合理使用 Multi-fields
- 比如,一个字符串字段可以被映射 为text和keywrod, • 前者用于全文检索, • 后者用于排序、聚合
- 我们可以将一个字段同时映射多个分析器,尝试命中更多的内容
- 选择合适的一对多的关系
- 更新嵌套对象需要对根对象及其所有其他嵌套对象进行完全的重新索引
- join数据类型的主要优点:能够独立于父对象修改子对象
对比 | Nested | Join 父子文档 |
---|---|---|
适用场景 | 子文档偶尔更新,查询频繁 | 子文档更新频繁 |
优点 | 文档存储在一起,读取性能高 | 父子文档独立更新,互不影响 |
缺点 | 更新父或子文档需要更新整个文档 | 为了维护join关系,需占用部分内容,读取性能较差 |
参数设置
参数 | 取值 | 作用 |
---|---|---|
enabled | true(默认),false | 仅存储,不做搜索和聚合分析 |
index | true(默认),false | 是否构建倒排索引 |
index_option | docs,freqs,positions,offests | 存储倒排索引的哪些信息 |
norms | ture(默认),false | 是否存储归一化修改参数,如果字段仅用于过滤和聚合分析,可关闭 |
doc_values | true(默认),false | 是否启动doc_values,用户聚合和排序分析 |
fielddata | true(默认),false | 是否为text类型启动fielddata,实现排序和聚合分析 |
store | false(默认),true | 是否存储该字段值 |
coerce | true(默认),false | 是否开启自动数据了些转换功能,比如:字符串转数字,浮点转整形 |
multifields | - | 灵活的使用多字段解决多样的业务需求 |
dynamic | true(默认),false,strict | 控制mapping的自动更新 |
data_detection | true(默认),false | 是否自动识别日期类型 |
基于字词混合索引的精确匹配技术
put mix_index
{
"mappings": {
properties: {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"fields": {
"standard": {
"type": "text",
"analyzer": "standard"
},
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
类型判断
何种数据类型?
1.字符串类型:需要分词,text,否则keyword 2.枚举类型:基于性能keyword,即便是整形 3.数值类型:尽量选择贴近大小的类型 4.其他类型:布尔、日期,地理位置
是否需要检索
完全不需要检索、排序、聚合分析 enable 设置为false
- 否 -> index:false
- 是:
index: true
index_options: 1) docs; 2)freqs; 3)positions; 4) offsets
是需要排序和聚合分析
否:
- doc_value: false
- fielddata:false(默认) 是: 是否需要另行存储 是 -> store:true, 与source: false 配合使用
数据库默认自带字段,规范
字段 | es 字段名称 | 类型 | 说明 |
---|---|---|---|
业务id | kw_business_id | keyword | |
创建用户 | kw_create_user | keyword | |
创建时间 | date_create_time | date | 系统自动生成 |
分类tag | kw_class_tags | keyword | |
是否有效 | bool_is_active | boolean | true/false |
动态模板设置
字段 | 子字段 | 内容 | 说明 |
---|---|---|---|
index_patterns | base_* | ||
settings | index.number_of_shards | 静态参数,设置后不可修改,除非reindex。指定分片数,建议和节点数一致 | |
index.number_of_replicas | 1 | 动态参数,可以检索基本设置,设置为为1 | |
index.refresh_interval | 30s | 默认1s,实时性如果要求不高,可以改成:30s | |
index.max_result_windows | 不指定,采用默认值 | 默认10000,可以根据需要调整 | |
aliases | 无 | 全局动态模板,不指定别名 | |
order | 全局索引,最低优先级 | ||
keyword | "kw_spec":{"match":"kw_*", "mapping": {"type":"keyword}} | kw_* 前缀匹配 | |
text | "text_spec":{"match":"text_*", "mapping":{"type":"text", "analyzer":"ik_max_word"}} | text_* 前缀匹配 | |
date | "date_spec":{"match":"date_*", "mapping": | date_* 前缀匹配 |
参数设置合理
自定义分词
多索引建模
• 尽量使用 别名访问索引(尤其数据量大的场景) • 可以使用alias来交换索引,达到索引重命名的效果 • 使用字段的alias,可以帮助我们重新命名一个字段, 并让这个字段的名称符合我们的命名规则。
模板 template
掌握模板的技巧
- 指定 索引模糊匹配格式
- 指定 Settings
- 指定 Mappings
- 指定 别名
- 指定 default 管道(数据预处理)
别名 alias
管道 pipeline
引申点
PB 级别的大索引如何设计? 旧:大索引设计建议:使用模板+Rollover+Curator动态创建索引 新:ilm
索引生命周期管理
ilm
rollover
冷热集群架构
原理:
借助 es 的分片分配策略 步骤: 1.设置节点属性 elasticsearch.yml 配置:node.attr.box_type: hot kibana 查看属性:GET _cat/nodeattrs?v=true&h=node,host,attr,value&s=attr
- 设置分配分配策略 put logs_01 { "setting": { "index.routing.allocation.include.box_type": "host", "number_of_replicas": 0 } }
- 适时数据迁移 put log_01/setting { "index.routing.allocation.include.box_type": "cold" } tip: 分配分配策略还有 index.routing.allocation.exclude.xx index.routing.allocation.require.xx
索引生命周期管理ILM实战
步骤:
- 配置ilm policy
- phrase: hot,warm,cold,freeze,delete 等
- actions: 操作动作
- 创建模板1,绑定policy, 指定别名
- 创建起始索引
- 索引基于第一步指定的policy进行滚动
跨集群检索实战
分片分配策略
主节点的主要作用:确定将哪些分片分配给哪些节点,以及何时在节点之间移动分片以重新平衡集群 分片分配发生的时机:分片分配是将分片分配给节点的过程
- 初始恢复
- 副本分配
- 重新平衡
- 添加或删除节点
- 分片分配策略分类
- 集群分配分配策略
- 基于磁盘的分片分配 cluster.routing.allocation.disk.watermark.low: 低警戒水位线--默认为磁盘容量的85%,副本将不能分配 cluster.routing.allocation.disk.watermark.high: 高警戒水位线--默认为磁盘容量的90%;将导致重新分配分片;此设置会影响所有分片的分配,无论先前是否分配 cluster.routing.allocation.disk.watermark.flood_stage: 洪水警戒水位线--默认为磁盘容量的95%;es 对每个索引强制执行只读索引块;这是防止节点耗尽磁盘空间的最后手段
- 跨集群分片分配
先设置节点属性: elasticsearch.yml 配置:node.attr.rack_id: rack01 PUT _cluster/settings { "persistent": { "cluster.routing.allocation.awareness.attributes": "rack_id", "cluster.routing.allocation.awareness.force.rack_id.values": "rack01" } } 主分片将会分配到rack01 上
- 索引分配分配策略 重要参数: index.routing.allocation.total_shards_per_node:控制每个节点上单个索引的最大分配数