ElasticSearch
主要功能及应用场景
主要功能:
海量数据的分布式存储以及集群管理,达到了服务与数据的高可用以及水平扩展;
近实时搜索,性能卓越。对结构化、全文、地理位置等类型数据的处理;
海量数据的近实时分析(聚合功能)
应用场景:
- 网站搜索、垂直搜索、代码搜索;
- 日志管理与分析、安全指标监控、应用性能监控、Web抓取舆情分析;
基础概念
Cluster 集群,一个集群由一个唯一的名字标识,默认为“elasticsearch”。
集群名称非常重要,具有相同集群名的节点才会组成一个集群。集群名称可以在配置文件中指定。
Node 节点:存储集群的数据,参与集群的索引和搜索功能。
像集群有名字,节点也有自己的名称,默认在启动时会以一个随机的UUID的前七个字符作为节点的名字,你可以为其指定任意的名字。
通过集群名在网络中发现同伴组成集群。一个节点也可是集群。Index 索引: 一个索引是一个文档的集合(等同于solr中的集合)。
每个索引有唯一的名字,通过这个名字来操作它。一个集群中可以有任意多个索引。
Type 类型:指在一个索引中,可以索引不同类型的文档,如用户数据、博客数据。
从6.0.0 版本起已废弃,一个索引中只存放一类数据。
Document 文档:被索引的一条数据,索引的基本信息单元,以JSON格式来表示。
Shard 分片:在创建一个索引时可以指定分成多少个分片来存储。
每个分片本身也是一个功能完善且独立的“索引”,可以被放置在集群的任意节点上。
Replication 备份: 一个分片可以有多个备份(副本)
Near Realtime(NRT) 近实时。数据提交索引后,立马就可以搜索到。
字段类型的选择建议
text
字段类型是Elasticsearch中用于全文搜索的核心字段类型。它通过分析器将文本拆分为单个词,并存储为倒排索引,适用于非结构化文本的搜索和分析。然而由于其经过分析器处理,不适用于排序和聚合操作。
keyword
字段类型不会对字段值进行分词处理,而是将其作为整体存储。这意味着字段值会被原样存储到倒排索引中,不会被拆分成单独的单词或短语,适用于需要精确匹配的场景。适于对数据进行排序或聚合。
明确业务使用场景,如果不需要进行模糊搜索的话,设置为keyword类型,来避免分词带来的存储开销,增加系统压力。
- 针对Text和数值类型场景的字段,尽量改成keyword字段类型,来提升查询速度。
- 在不确定业务查询有哪些需求的情况下,设置多字段类型keyword。
- 枚举字段没有特殊业务场景下,统一使用keyword字段类型。
- 业务不需要范围查询的话,使用keyword字段类型(支持聚合和排序的)。
- 对keyword字段类型进行模糊查询会性能较差,使用多字段类型wildcard来模糊查询性能更高。
- 尽量不要使用聚合查询,text的fielddata会加大对内存的占用,如有需求使用,建议使用keyword。
- 需要中文分词的话,不要使用默认分词器,推荐使用ik_smart,ik_max_word会生成更多的分词,其中含有重复的内容,需谨慎使用。
- 时间字段不要使用keyword,除非点查,推荐使用date/long类型,支持范围查询,建议精确到分钟,会提高查询效率。
- keyword字段类型不适用于模糊wildcard查询,建议使用wildcard字段类型。
- 日期的查询条件为now时,并不能有效利用缓存,尽量换成绝对时间值。
- ES默认字段个数最大1000,但建议不要超过100,对于不需要建立索引的字段,不写入ES。
- 将不需要建立索引的字段index数据设置为false,对字段不分词,不索引可以减少很多运算操作。
- 不建议或者禁止每次写入后立马进行显示的refresh,refresh会带来较高的磁盘IO,和CPU消耗,甚至有可能导致ES宕机。
分片数规划
在实际的业务场景中做好分片(主副)数量的规划,可以避免慢查、数据倾斜、磁盘容量浪费等问题。
要提前规划预算索引数据量,做好分片数量规划,索引一旦创建 无法修改分片数
当索引分片数量过多时,可能会对ES性能产生不利影响。因为每个分片都需要一定量的内存来存储索引数据和缓存,从而导致内存消耗增加。
另外,当查询或写入数据涉及多个分片时,ES需要在节点之间进行传输和协调数据,从而增加网络开销,这也会导致查询和写入性能的降低。
可见分片数量的选择需要慎重考虑。
具体见:得物技术-分片数规划章节,这里整理部分场景
通用建议
分片数量(推荐公式):主分片数 ≈ 总数据量 / 单分片容量上限
官方建议单分片10-50GB,日志场景可放宽至50-100GB,单个分片文档数在1亿条以内。
副本数量:增加副本数可提升读性能,但会降低写入速度(需同步更多副本),因此在读场景可以酌情考虑。
持续调整索分片:对于集群分片的调整,通常不是一蹴而就的。随着业务的发展,不断新增的子业务 或 原有子业务规模发生突变,都需要持续调整分片数量。
读场景
索引单分片20g~40g,尽量减少分片数,可以降低热点,因为当分片数过多时,就容易出现长尾子请求,即有可能部分子请求因ES集群节点异常、Old GC、网络抖动等延迟响应,导致整个请求响应缓慢。
拆分过多的子请求无法提升数据节点请求吞吐,不能充分利用 CPU。
在尽量减少主分片数的情况下,同时也可以适当增加副本数,从而提升查询吞吐。
写场景
索引单分片10g~20g,小分片更有利于数据写入。
小分片维护的segment数量远低于大分片,在数据刷新落盘与段合并上更有优势。
由于单分片数据量更少,在写入时数据可以更快地缓存至内存中并通过refresh参数更快的持久化至磁盘中。
日志存储场景
- 需要考虑每日写入集群的数据总量大小。通过过数据量与数据节点数评估索引分片数量。
- 在日志存储后是否需要兼顾查询与聚合性能。合理大小的分片数据量能够提高查询效率。
- 根据日志持久化策略,采用按月/周/天的策略生成索引。并使用ILM(索引生命周期管理策略)动态对日志索引进行完整生命周期的管理。
- 建议副本数设置为0来减少磁盘容量成本。