ui网站建设,百度seo营销推广,成都seo网络优化公司,导购网站的seo怎么做目录
1、通用优化策略
1.1 通用最小化法则
1.2 职责单一原则
1.3 其他
2、写性能调优
2.1 基本原则
2.2 优化手段
2.2.1 增加 flush 时间间隔#xff0c;
2.2.2 增加refresh_interval的参数值
2.2.3 增加Buffer大小#xff0c;
2.2.4 关闭副本
2.2.5 禁用swap
2…目录
1、通用优化策略
1.1 通用最小化法则
1.2 职责单一原则
1.3 其他
2、写性能调优
2.1 基本原则
2.2 优化手段
2.2.1 增加 flush 时间间隔
2.2.2 增加refresh_interval的参数值
2.2.3 增加Buffer大小
2.2.4 关闭副本
2.2.5 禁用swap
2.2.6 使用多个工作线程
2.2.7 避免使用稀疏数据
2.2.8 max_result_window参数
3、查询调优
3.1 读写性能不可兼得
3.2 优化手段
3.2.1 避免单次召回大量数据
3.2.2 避免单个文档过大
3.2.3 单次查询10条文档 好于 10次查询每次一条
3.2.4 数据建模
3.2.5 给系统留足够的内存
3.2.6 预索引
3.2.7 使用filter代替query
3.2.8 避免深度分页
3.2.9 使用 Keyword 类型
3.2.10 避免使用脚本
4、索引结构优化
4.1 一句废话
4.2 案例
4.2.1 背景
4.2.2 痛点
4.2.3 思路及解决方案
4.3 总结
5、硬件优化
5.1 简述
5.2 节点
5.3 分片
5.3.1 分片创建策略
5.3.2 分片分配策略
5.3.3 分片的数量
5.3.4 分片的大小决策
5.4 内存
5.5 磁盘
5.6 CPU
5.7 网络
5.8 总结
6、架构优化:
7、Mpping结构和索引字段优化 性能调优是一件大而细的活儿。技术开发没有银弹也就是本质上是没有所谓可应对任何场景的通用最优配置的。如果有那么出厂何必不直接给出呢所以理解每一项优化配置的含义很重。在当前情况下为最优配置但是换一种场景就未必了。 废话不多说直接上干货
1、通用优化策略 虽然没有通用最优解但是的确存在一些通用的优化策略。
1.1 通用最小化法则 所谓通用最小化其实很好理解比如能用short绝不用int, 能用1,绝不用2。对于搜索引擎级海量数据的优化在数据存储每个bit尤为珍贵。了解 ES 内部存储机制的小伙伴一定知道其底层对倒排表的存储涉及多种压缩算法其可谓对每个bit的使用发挥到了极致举个例子
上面图片为英汉词典中截取的一个小片段英汉词典按照字典序排列这就很方便我们去发现问题。假设业务要求我们要存储一个英汉对照的数据表常规思想就是为其创建两个字段分别是“word_en” 、“word_cn”当然名字是无所谓的。但是这带来一个很大的问题搜索引擎级的数据往往是海量数据以亿为单位计算的这就要求我们必须在各个方面都不能用这种常规手段来处理。比如
在数据结构层面基于BTrees的数据结构就非常不适用于全文检索这种场景因为BTrees中节点大小是固定的当索引字段单位数据量增大就会造成节点分离进而大大加深树的深度造成不可估量的磁盘IO。这一点我将用一篇单独的文章详细讲解此处不再赘述。
其次海量数据可能涉及大量所谓“重复数据”这里的重复不仅仅指的是keyword 层面或term层面而要精细到char这种级别简单来说就是你不能说我两个字段值全完重叠才算做重复而是如果 Term B 以 Term A 为前缀后缀或者 Term B 和 Term A 有公共前缀或后缀均可视为重复存储。
试想假如列中包含 10亿 数量级的数据而英文字幕无非就 26 个也就是说字幕 a 我们可能重复存储了上亿次。即便是中文ES在底层存储的时候也会通过ASCII来转移为字幕最终以 bits 存储这种问题数量级越大越严重。实际上这些有公共前缀或公共后缀的地方我们完全可以只存储一次以追求更高的效率。
ES 在数据存储上采用的 FST 这种模型在保证了高性能的前体系带来了指数级的存储效率提升一个TB级的索引通过FST存储其构建的模型大小在1GB左右。比如下 图二 就是 图一中词项字典的 FST模型。图三为其二进制序列的十进制展示。
这里我们只借鉴思想而不探究原理FST 的模型建立过程非常负责我在关于倒排索引的讲解中会有详细的介绍。
当然此法则绝不仅仅局限于在数据存储层面思想层面的应用还可扩展更多层面如索引拆分模型拆分数据结构优化业务分离等。
举个例子在上述字符串的重复存储问题上面我们做一下思维扩展aabbc 和 aabbdd 很容易想到其中 aabb 为其公共前缀但如果是数字呢 比如数字 5和数字 10 他们的公共前缀又是什么答案是 5 10 5 5那如果是 2、5、10 呢这种情况他们的存储方式就变成了 2、3、5。因为 2 是 2、 5、10 公共前缀而 5 是 5 和 10 的公共前缀讲到这里不知道你是否理解了这种 通用最小化 层面的思想。借助这种设计思想其实还有很多可以扩展的地方。这里不一一列举了因为我也列举不完。如果你真正理解了你就会发现这样的例子遍布于和我们生活息息相关的各个场景。
面向对象的语言开发者可能在刚接触语言开发的时候听到最多的一句话就是“面向对象”什么是封装、继承、多态如何提高代码的复用效率。代码封装不仅仅为了代码美观还可以大大减小最终生成文件的大小提高代码的存储和执行效率。这本质也是“通用最小化法则”的一种实现。
再举一个例子很多重负载业务都追求极致的轻量化代码或组件一个典型的例子我们用 beats 代替 logstash最重要的原因就是 beats 的轻量化处理使其在代替 logstash 完成数据采集的前提下不挤占业务系统的资源。Logstash 虽然功能强大但是其基于 Jvm 的特性就导致了其需要通过大量的资源占用来换取。
1.2 职责单一原则 职责单一的设计是为了当某个单一职责所负责的业务的集群或节点无法满足其业务需要的时候方便定向扩展。而且可以更均衡的分配所有资源。常见的操作如
功能分离本质上也利于服务的轻量化我曾和百度负责搜索引擎开发的一位朋友聊天的时候聊过这个话题百度内部就是基于 Elasticsearch 的源码做修改删除对其业务不需要的代码对 ES做轻量化处理
业务分离最简单常见的场景当我在全文检索服务的时候应避免在服务期间去执行大量的聚合分析。
读写分离常见操作不做过多解释
冷热分离基于索引生命周期管理策略下的性能动态分配策略。
1.3 其他 避免单索引业务重耦合 命名规范 开启自适应副本选择ARS6.1版本支持7.0默认开启
2、写性能调优
2.1 基本原则 写性能调优是建立在对Elasticsearch的写入原理之上。ES 数据写入具有一定的延时性这是为了减少频繁的索引文件产生。默认情况下 ES 每秒生成一个 segment 文件当达到一定阈值的时候 会执行mergemerge 过程发生在 JVM中频繁的生成 Segmen 文件可能会导致频繁的触发 FGC导致 OOM。为了避免避免这种情况通常采取的手段是降低 segment 文件的生成频率手段有两个一个是 增加时间阈值另一个是增大 Buffer的空间阈值因为缓冲区写满也会生成 Segment 文件。
生产经常面临的写入可以分为两种情况
高频低量高频的创建或更新索引或文档一般发生在 处理 C 端业务的场景下。
低频高量一般情况为定期重建索引或批量更新文档数据。
在搜索引擎的业务场景下用户一般并不需要那么高的写入实时性。比如你在网站发布一条征婚信息或者二手交易平台发布一个商品信息。其他人并不是马上能搜索到的这其实也是正常的处理逻辑。这个延时的过程需要处理很多事情业务层面比如你的信息需要后台审核。你发布的内容在搜索服务中需要建立索引而且你的数据可能并不会马上被写入索引而是等待要写入的数据达到一定数量之后批量写入。这种操作优点类似于我们快递物流的场景只有当快递数量达到一定量级的时候比如能装满整个车的时候快递车才会发车。因为反正是要跑一趟装的越多平均成本越低。这和我们数据写入到磁盘的过程是非常相似的我们可以把一条文档数据看做是一个快递而快递车每次发车就是向磁盘写入数据的一个过程。这个过程不宜太多太多只会降低性能就是体现在运输成本上面。而对于我们数据写入而言就是体现在我们硬件性能损耗上面。
2.2 优化手段 以下为常见 数据写入的调优手段写入调优均以提升写入吞吐量和并发能力为目标而非提升写入实时性。
2.2.1 增加 flush 时间间隔 目的是减小数据写入磁盘的频率减小磁盘IO频率。
2.2.2 增加refresh_interval的参数值 目的是减少segment文件的创建减少segment的merge次数merge是发生在jvm中的有可能导致full GC增加refresh会降低搜索的实时性。
ES的 refresh 行为非常昂贵并且在正在进行的索引活动时经常调用会降低索引速度这一点在索引写入原理中介绍过了解索引的写入原理可以关注我的博客Elastic开源社区。
默认情况下Elasticsearch 每秒定期刷新索引但仅在最近 30 秒内收到一个或多个搜索请求的索引上。
如果没有搜索流量或搜索流量很少例如每 5 分钟不到一个搜索请求并且想要优化索引速度这是最佳配置。此行为旨在在不执行搜索的默认情况下自动优化批量索引。建议显式配置此配置项如 30秒。
2.2.3 增加Buffer大小 本质也是减小refresh的时间间隔因为导致segment文件创建的原因不仅有时间阈值还有buffer空间大小写满了也会创建。 默认最小值 48MB 默认值 JVM 空间的10% 默认最大无限制
2.2.4 关闭副本 当需要单次写入大量数据的时候建议关闭副本暂停搜索服务或选择在检索请求量谷值区间时间段来完成。
第一是减小读写之间的资源抢占读写分离 第二当检索请求数量很少的时候可以减少甚至完全删除副本分片关闭segment的自动创建以达到高效利用内存的目的因为副本的存在会导致主从之间频繁的进行数据同步大大增加服务器的资源占用。 具体可通过则设置index.number_of_replicas 为0以加快索引速度。没有副本意味着丢失单个节点可能会导致数据丢失因此数据保存在其他地方很重要以便在出现问题时可以重试初始加载。初始加载完成后可以设置index.number_of_replicas改回其原始值。
2.2.5 禁用swap 大多数操作系统尝试将尽可能多的内存用于文件系统缓存并急切地换掉未使用的应用程序内存。这可能导致部分 JVM 堆甚至其可执行页面被换出到磁盘。
交换对性能和节点稳定性非常不利应该不惜一切代价避免。它可能导致垃圾收集持续几分钟而不是几毫秒并且可能导致节点响应缓慢甚至与集群断开连接。在Elastic分布式系统中让操作系统杀死节点更有效。
2.2.6 使用多个工作线程 发送批量请求的单个线程不太可能最大化 Elasticsearch 集群的索引容量。为了使用集群的所有资源应该从多个线程或进程发送数据。除了更好地利用集群的资源外还有助于降低每个 fsync 的成本。
确保注意TOO_MANY_REQUESTS (429)响应代码EsRejectedExecutionException使用 Java 客户端这是 Elasticsearch 告诉我们它无法跟上当前索引速度的方式。发生这种情况时应该在重试之前暂停索引最好使用随机指数退避。
与调整批量请求的大小类似只有测试才能确定最佳工作线程数量是多少。这可以通过逐渐增加线程数量来测试直到集群上的 I/O 或 CPU 饱和。
2.2.7 避免使用稀疏数据
2.2.8 max_result_window参数 max_result_window是分页返回的最大数值默认值为10000。max_result_window本身是对JVM的一种保护机制通过设定一个合理的阈值避免初学者分页查询时由于单页数据过大而导致OOM。
在很多业务场景中经常需要查询10000条以后的数据当遇到不能查询10000条以后的数据的问题之后网上的很多答案会告诉你可以通过放开这个参数的限制将其配置为100万甚至1000万就行。但是如果仅仅放开这个参数就行那么这个参数限制的意义有何在呢如果你不知道这个参数的意义很可能导致的后果就是频繁的发生OOM而且很难找到原因设置一个合理的大小是需要通过你的各项指标参数来衡量确定的比如你用户量、数据量、物理内存的大小、分片的数量等等。通过监控数据和分析各项指标从而确定一个最佳值并非越大越好
3、查询调优
3.1 读写性能不可兼得 首先要明确一点鱼和熊掌不可兼得。读写性能调优在很多场景下是只能二选一的。牺牲 A 换 B 的行为非常常见。索引本质上也是通过空间换取时间。写生写入实时性就是为了提高检索的性能。
当你在二手平台或者某垂直信息网站发布信息之后是允许有信息写入的延时性的。但是检索不行甚至 1 秒的等待时间对用户来说都是无法接受的。满足用户的要求甚至必须做到10 ms以内。
3.2 优化手段
3.2.1 避免单次召回大量数据 搜索引擎最擅长的事情是从海量数据中查询少量相关文档而非单次检索大量文档。非常不建议动辄查询上万数据。如果有这样的需求建议使用滚动查询
3.2.2 避免单个文档过大 鉴于默认http.max_content_length设置为 100MBElasticsearch 将拒绝索引任何大于该值的文档。您可能决定增加该特定设置但 Lucene 仍然有大约 2GB 的限制。
即使不考虑硬性限制大型文档通常也不实用。大型文档对网络、内存使用和磁盘造成了更大的压力即使对于不请求的搜索请求也是如此_source因为 Elasticsearch_id在所有情况下都需要获取文档的文件系统缓存有效。对该文档进行索引可能会占用文档原始大小的倍数的内存量。Proximity Search例如短语查询和高亮查询也变得更加昂贵因为它们的成本直接取决于原始文档的大小。
有时重新考虑信息单元应该是什么是有用的。例如您想让书籍可搜索的事实并不一定意味着文档应该包含整本书。使用章节甚至段落作为文档可能是一个更好的主意然后在这些文档中拥有一个属性来标识它们属于哪本书。这不仅避免了大文档的问题还使搜索体验更好。例如如果用户搜索两个单词fooand bar则不同章节之间的匹配可能很差而同一段落中的匹配可能很好。
3.2.3 单次查询10条文档 好于 10次查询每次一条 批量请求将产生比单文档索引请求更好的性能。但是每次查询多少文档最佳不同的集群最佳值可能不同为了获得批量请求的最佳阈值建议在具有单个分片的单个节点上运行基准测试。首先尝试一次索引 100 个文档然后是 200 个然后是 400 个等。在每次基准测试运行中批量请求中的文档数量翻倍。当索引速度开始趋于平稳时就可以获得已达到数据批量请求的最佳大小。在相同性能的情况下当大量请求同时发送时太大的批量请求可能会使集群承受内存压力因此建议避免每个请求超过几十兆字节。
3.2.4 数据建模 很多人会忽略对 Elasticsearch 数据建模的重要性。
nested属于object类型的一种是Elasticsearch中用于复杂类型对象数组的索引操作。Elasticsearch没有内部对象的概念因此ES在存储复杂类型的时候会把对象的复杂层次结果扁平化为一个键值对列表。
特别是应避免连接。Nested 可以使查询慢几倍Join 会使查询慢数百倍。两种类型的使用场景应该是Nested针对字段值为非基本数据类型的时候而Join则用于 当子文档数量级非常大的时候。
关于数据建模在我的博客中有详细的讲解此处不再赘述
3.2.5 给系统留足够的内存 Lucene的数据的fsync是发生在OS cache的要给OS cache预留足够的内从大小详见JVM调优。
3.2.6 预索引 利用查询中的模式来优化数据的索引方式。例如如果所有文档都有一个price字段并且大多数查询 range 在固定的范围列表上运行聚合可以通过将范围预先索引到索引中并使用聚合来加快聚合速度。
3.2.7 使用filter代替query query和filter的主要区别在 filter是结果导向的而query是过程导向。query倾向于“当前文档和查询的语句的相关度”而filter倾向于“当前文档和查询的条件是不是相符”。即在查询过程中query是要对查询的每个结果计算相关性得分的而filter不会。另外filter有相应的缓存机制可以提高查询效率。
3.2.8 避免深度分页 避免单页数据过大可以参考百度或者淘宝的做法。es提供两种解决方案 scroll search 和 search after。关于深度分页的详细原理推荐阅读详解Elasticsearch深度分页问题
3.2.9 使用 Keyword 类型 并非所有数值数据都应映射为数值字段数据类型。Elasticsearch为 查询优化数字字段例如integeror long。如果不需要范围查找对于 term查询而言keyword 比 integer 性能更好。
3.2.10 避免使用脚本 Scripting是Elasticsearch支持的一种专门用于复杂场景下支持自定义编程的强大的脚本功能。相对于 DSL 而言脚本的性能更差DSL能解决 80% 以上的查询需求如非必须尽量避免使用 Script
4、索引结构优化
4.1 一句废话 本质上索引结构取决于业务业务场景不同最合适的索引结构也不同。下面我通过一个真实案例来解释这个问题。
4.2 案例
4.2.1 背景 某公司是提供SMS短信服务的其主要客户群体为各大银行系统。其业务主要是为客户提供短信发送服务并且要保存所有
4.2.2 痛点 痛点1索引过于庞大
就短信发送而言并无太大问题但是在项目初期在建立短信发送记录的时候并没有在意索引结构的设计而是将新产生的数据不断的追加到一个索引中但是后期发现短信发送量级过于庞大每天都产生上几百GB甚至是TB级的日志数据后期的优化手段就是把一个单独的大索引通过Rollover Index每天创建一个单独的索引。短期内问题得到了解决
痛点2索引太多
基于滚动索引的方案在短期内的确解决了单个索引过大而带来的性能下降因为80%的请求都是基于近期数据而言的但是随着时间周期的拉长剩余 20% 的请求的问题日渐突出。的确存在一部分用户需要查询跨周期范围特别大的数据比如工商银行某客户要查询 近三年以来短信发送记录造成的结果就是需要跨一千多个索引来查询。这种问题时间越久就越明显。
4.2.3 思路及解决方案 对于这种需求场景而言其实索引结构设计的很不合理。固然我们很容易将数据与时间绑定但是当前场景明显是一个垂直业务。换句话说索引的拆分不应该简单按照时间进行拆分而是按照业务属性和业务量。比如我们要查询某个手机号3年的发送记录在执行查询之前我们就能通过手机号的自身属性确定查询范围如手机号归属地、所属运营商等。北京的手机号无论如何也不会涉及到上海的数据。所以中国移动在北京和上海的数据就可以保存两个索引因为他们是互不相干的。中国移动和中国联通的数据也是互不相干的。这样一来一个索引可能就被拆成了几百个索引在检索之前就可以根据业务属性迅速确定要查询的所有数据所在的索引。
在此基础之上通过Rollover index来创建索引还要根据总量以及每日增量来确定索引创建的粒度大小。这个大小要结合群节点数量、结构分配及角色分配、分片数量的最优原则来确定。比如如果数据量每天很少那就把粒度改成周或者月让索引有一个更加合理的大小过大过小都不好。至于索引和分片大小数量的优化配置我的文章里有单独介绍。
举个例子当我们80%的请求落在近三个月90%的请求都落在近一个月那其实我们有必要为近三个月单独创建一个索引或者将数据缓存起来又或者通过冷热集群的方案来做隔离部署。把更优质的资源分配给更需要性能的业务数据上。
然而问题到此还未真正的彻底解决因为时序数据是具有流转性特点的。近三个月的数据其实等过三个月就变成了历史数据本身部署在 hot phase 的数据就要相应的流转到 warm也有可能需要对数据压缩或冷冻以提高数据的存储效率降低成本。
有些数据大概率常年是不需要提供任何查询但是我们不能丢弃比如银行的转账记录可能要保存十年甚至三十年。平常这些数据我们是用不到的对于普通用户一般能查询半年或一年最多三年的记录。但是这些数据因为有可能涉及犯罪信息当国家或政府需要银行协助调查的时候银行有保存义务需要协助国家调查提供数据。这种事情发生的概率很小但是它的确存在。所以可以通过快照或可搜索快照保存。这样代价就很低。
到这里其实还能继续优化因为即便索引已经合理拆分但是如果随着业务的继续膨胀以及时间周期的不断拉长仍然会面临以上问题那么解决方案就是我们通过数据流来创建索引的生命周期管理策略数据流在开源社区或者我的个人博客中有单独的讲解此处不再赘述。
4.3 总结
5、硬件优化
5.1 简述 es的默认配置是一个非常合理的默认配置绝大多数情况下是不需要修改的如果不理解某项配置的含义没有经过验证就贸然修改默认配置可能造成严重的后果。比如max_result_window这个设置默认值是1W这个设置是分页数据每页最大返回的数据量冒然修改为较大值会导致OOM。ES没有银弹不可能通过修改某个配置从而大幅提升ES的性能通常出厂配置里大部分设置已经是最优配置只有少数和具体的业务相关的设置事先无法给出最好的默认配置这些可能是需要我们手动去设置的。关于配置文件如果你做不到彻底明白配置的含义不要随意修改。
jvm heap分配7.x 版本默认1GB这个值太小很容易导致OOM。Jvm heap大小不要超过物理内存的50%最大也不要超过32GBcompressed oop它可用于其内部缓存的内存就越多但可供操作系统用于文件系统缓存的内存就越少heap过大会导致GC时间过长
5.2 节点 相同角色的节点避免使用差异较大的服务器配置
避免使用“超大杯”服务器SSSuper Server比如128核CPU1 T的内存2T的固态硬盘。这样可能会产生较大的资源浪费。
等量的配置使用较少的物理机好于使用较多的虚拟机。比如一个一个五台4核16G的物理机好于10甚至11台2核8G的虚拟机这里不仅仅是虚拟机本身可能也会消耗一部分性能的问题也涉及数据安全的问题。
避免在同一台服务器上部署多个节点会增加集群管理的难度。
5.3 分片
5.3.1 分片创建策略 分片产生的目的是为了实现分布式而分布式的好处之一就是实现“高可用性”还包括高性能如提高吞吐量等会在后面内容展开讲分片的分配策略极大程度上都是围绕如何提高可用性而来的如分片分配感知、强制感知等。
互联网开发没有“银弹”分片的数量分配也没有适用于所有场景的最佳值创建分片策略的最佳方法是使用您在生产中看到的相同查询和索引负载在生产硬件上对生产数据进行基准测试。分片的分配策略主要从两个指标来衡量即数量和单个分片的大小。
5.3.2 分片分配策略 ES使用数据分片shard来提高服务的可用性将数据分散保存在不同的节点上以降低当单个节点发生故障时对数据完整性的影响同时使用副本repiica来保证数据的完整性。关于分片的默认分配策略在7.x之前默认5个primary shard每个primary shard默认分配一个replica即5主1副而7.x之后默认1主1副 ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。但是实际情况取决于集群拥有的分片和索引的数量以及它们的大小不一定总是能均匀地分布。 Paimary只能在索引创建时配置数量而replica可以在任何时间分配并且primary支持读和写操作而replica只支持客户端的读取操作数据由es自动管理从primary同步。 ES不允许Primary和它的Replica放在同一个节点中并且同一个节点不接受完全相同的两个Replica 同一个节点允许多个索引的分片同时存在。
5.3.3 分片的数量 避免分片过多大多数搜索会命中多个分片。每个分片在单个 CPU 线程上运行搜索。虽然分片可以运行多个并发搜索但跨大量分片的搜索会耗尽节点的搜索线程池。这会导致低吞吐量和缓慢的搜索速度。 分片越少越好每个分片都使用内存和 CPU 资源。在大多数情况下一小组大分片比许多小分片使用更少的资源。
5.3.4 分片的大小决策 分片的合理容量10GB-50GB。虽然不是硬性限制但 10GB 到 50GB 之间的分片往往效果很好。根据网络和用例也许可以使用更大的分片。在索引的生命周期管理中一般设置50GB为单个索引的最大阈值。 堆内存容量和分片数量的关联小于20分片/每GB堆内存一个节点可以容纳的分片数量与节点的堆内存成正比。例如一个拥有 30GB 堆内存的节点最多应该有 600 个分片。如果节点超过每 GB 20 个分片考虑添加另一个节点。
5.4 内存 根据业务量不同内存的需求也不同一般生产建议不要少于16G。ES是比较依赖内存的并且对内存的消耗也很大内存对ES的重要性甚至是高于CPU的所以即使是数据量不大的业务为了保证服务的稳定性在满足业务需求的前提下我们仍需考虑留有不少于20%的冗余性能。一般来说按照百万级、千万级、亿级数据的索引我们为每个节点分配的内存为16G/32G/64G就足够了太大的内存性价比就不是那么高了。
5.5 磁盘 对于ES来说磁盘可能是最重要的了因为数据都是存储在磁盘上的当然这里说的磁盘指的是磁盘的性能。磁盘性能往往是硬件性能的瓶颈木桶效应中的最短板。ES应用可能要面临不间断的大量的数据读取和写入。生产环境可以考虑把节点冷热分离“热节点”使用SSD做存储可以大幅提高系统性能冷数据存储在机械硬盘中降低成本。另外关于磁盘阵列可以使用raid 0。
5.6 CPU CPU对计算机而言可谓是最重要的硬件但对于ES来说可能不是他最依赖的配置因为提升CPU配置可能不会像提升磁盘或者内存配置带来的性能收益更直接、显著。当然也不是说CPU的性能就不重要只不过是说在硬件成本预算一定的前提下应该把更多的预算花在磁盘以及内存上面。通常来说单节点cpu 4核起步不同角色的节点对CPU的要求也不同。服务器的CPU不需要太高的单核性能更多的核心数和线程数意味着更高的并发处理能力。现在PC的配置8核都已经普及了更不用说服务器了。
5.7 网络 ES是天生自带分布式属性的并且ES的分布式系统是基于对等网络的节点与节点之间的通信十分的频繁延迟对于ES的用户体验是致命的所以对于ES来说低延迟的网络是非常有必要的。因此使用扩地域的多个数据中心的方案是非常不可取的ES可以容忍集群跨多个机房可以有多个内网环境支持跨AZ部署但是不能接受多个机房跨地域构建集群一旦发生了网络故障集群可能直接GG即使能够保证服务正常运行维护这样跨地域单个集群的集群带来的额外成本可能远小于它带来的额外收益。
5.8 总结 集群需要多少种配置内存型/IO型/运算型每种配置需要多少数量通常需要和产品运营和运维测试商定视业务量和服务器的承载能力而定并留有一定的余量。
一个合理的ES集群配置应不少于5台服务器避免脑裂时无法选举出新的Master节点的情况另外可能还需要一些其他的单独的节点比如ELK系统中的Kibana、Logstash等。
6、架构优化: 架构层面非一言两语可详述推荐阅读从单机到百万节点Elasticsearch高可用集群架构部署方案
合理的分配角色和每个节点的配置在部署集群的时候应该根据多方面的情况去评估集群需要多大规模去支撑业务。这个是需要根据在你当前的硬件环境下测试数据的写入和搜索性能然后根据你目前的业务参数来动态评估的比如业务数据的总量、每天的增量、查询的并发以及QPS以及峰值的请求量。
节点并非越多越好会增加主节点的压力
分片并非越多越好从deep pageing 的角度来说分片越多JVM开销越大负载均衡协调节点的转发压力也越大查询速度也越慢。单个分片也并非越大越好一般来说单个分片大小控制在30-50GB。
7、Mpping结构和索引字段优化 doc_values正排索引对于不需要聚合的字段关闭正排索引可节省资源提高查询速度
fielddata可以理解为“runtime_doc_values”doc_value 为 index time 正排索引。fielddata会消耗JVM空间如果执行大量数据的聚合使用 fielddata会造成 OOM
尽量不要使用 dynamic mapping
ignore_above字段保留的长度越小越好
调整_source字段通过include和exclude过滤
store开辟另一块存储空间可以节省带宽
注意_sourse设置为false则不存储源数据可以节省磁盘并且不影响搜索。但是禁用_source必须三思而后行禁用后将导致以下后果
updateupdate_by_query和reindex不可用。
高亮失效
reindex失效原本可以修改的mapping部分参数将无法修改并且无法升级索引
无法查看元数据和聚合搜索
影响索引的容灾能力
禁用_all字段_all字段的包含所有字段分词后的Term作用是可以在搜索时不指定特定字段从所有字段中检索ES 6.0之前需要手动关闭
关闭 Norms 字段计算评分用的如果你确定当前字段将来不需要计算评分设置false可以节省大量的磁盘空间有助于提升性能。常见的比如filter和agg字段都可以设为关闭。
关闭 index_options谨慎使用高端操作此设置用于在index time过程中哪些内容会被添加到倒排索引的文件中例如TFdocCount、postion、offsets等减少option的选项可以减少在创建索引时的CPU占用率不过在实际场景中很难确定业务是否会用到这些信息除非是在一开始就非常确定用不到否则不建议删除
enabled是否创建倒排索引对于不需要查询的字段关闭正排索引可节省资源提高查询速度。
推荐阅读
从单机到百万节点的ES高可用集群架构部署方案https://es-cn.blog.csdn.net/article/details/119812971?spm1001.2014.3001.5502 详解Elasticsearch深度分页问题https://es-cn.blog.csdn.net/article/details/120800632?spm1001.2014.3001.5502