- Elasticsearch优化
- 硬件选择:
- 分片策略
- 路由选择:
- 写入速度优化:
- 内存设置:
- 重要配置:
$ vim config/elasticsearch.yml # 本地存储路径相关配置 # path.data: /path/to/data # path.logs: /path/to/logs - 优化 I/O方案: (-) 使用 SSD (-) 使用 RAID0(又称条带化). RAID会提高磁盘 I/O, 代价是当一块硬盘故障时整个就故障了. 不要使用镜像或奇偶校验 RAID, 因为副本已经提供了这个功能 (-) 另外, 使用多块硬盘, 并允许 ES通过多个 path.data目录配置, 把数据`条带化`分配到它们上面 (-) 不要使用远程挂载的存储, 如 NFS或 SMB/CIFS分片策略
- 分片(或副本)分配多后产生的问题: 1. 分片(或副本)是可以无限分配的, 而每一个请求都会命中索引中的分片(或副本), 那些分片处在不同的节点(独立的物理机)还好, 但如果单一节点分配了太多的分片(或副本), 会出现严重的资源竞争现象, 因为每个分片(或副本)都会消耗一定文件的句柄, 内存& CPU算力 2. 副本分配多了, 会提升搜索的效率, 而会影响写索引的效率(因为默认写 *** 作, 需要同步到所有副本后才算完成并结束 *** 作) - 分配时, 需遵循的原则: (1) 控制每个分片硬盘容量不超过 ES的最大 JVM的堆空间设置(建议设置不超过 32G), 因此, 如果索引的总容量在 500G左右, 那分片大小在 16个左右即可(500/32)& 同时考虑原则(2) (2) 考虑节点的数量& 每个节点最好是独立的物理机. 当分片数过多& 大大超出了节点的数量时, 可能会导致一个节点上存在多个分片, 此时一旦该节点异常停止工作, 即使它保持了1个以上的副本, 同样也有可能会导致数据丢失, 集群无法恢复. 所以, 建议设置分片数不超过节点数的3倍 (3) 分配主分片, 副本和节点数的, 参考关系: 节点数 <= 主分片数 x (副本数 + 1) - 推迟分片分配: > 当节点瞬时中断的时, 默认情况, 集群会等待一分钟来查看节点是否会重新加入, 如果这个节点在此期间重新加入, 重新加入的节点会保持其现有的分片数据, 不触发新的分片分配 通过修改参数 delayed_timeout, 可以延长再均衡的时间, 可以全局设置也可以在索引级别进行修改: PUT /_all/_settings { "settings": { "index.unassigned.node_left.delayed_timeout": "5m" } } *注: 索引的分片数是创建索引的同时做的, 由于索引的路由机制, 分片数量是无法修改的, 此时只能修改副本数来提升搜索效率路由选择:
- 锁定分片的计算公式: shard = hash(routing) % number_of_primary_shards routing默认是文档的 id, 也可以采用自定义值 - 不带 routing查询: 查询时, 分为2个步骤 (-) 分发: 请求到达协调节点后, 协调节点将查询请求分发到每个分片上 (-) 聚合: 协调节点搜集到每个分片上查询结果, 将结果进行排序, 最后返回给用户 - 带 routing查询: 查询时, 可以直接根据 routing信息定位分片查询, 无需查询所有的分片, 再经过协调节点排序写入速度优化:
> 相比搜索写入要求较高的场景, 可以考虑以下几个方面 (-) 加大 Translog Flush, 目的是降低 Iops, Writeblock (-) 增加 Index Refresh间隔, 目的是减少 Segment Merge的次数 (-) 调整 Bulk线程池和队列 (-) 优化节点间的任务分布 (-) 优化 Lucene层的索引建立, 目的是降低 CPU及 IO - 批量数据提交: 使用 Bulk API进行批量写入. Bulk默认批量提交的数据量不能超过100M. 数据条数一般是根据文档的大小和服务器性能而定 - 优化存储设备: ES在段合并的时候会频繁 *** 作磁盘, 所以一旦磁盘的性能提高, ES集群的整体性能也会大幅度增加 - 合理使用合并: Lucene以段的形式存储数据. 当有新的数据写入索引时, Lucene就会自动创建一个新的段 随着数据量的变化, 段的数量会越来越多, 消耗的多文件句柄数及 CPU就越多, 查询效率就会下降 由于 Lucene段合并的计算量庞大, 会消耗大量的 I/O, 所以 ES默认采用较保守的策略, 让后台定期进行段合并 - 减少 Refresh的次数: Lucene在新增数据时, 采用了延迟写入的策略, 默认情况下索引的 refresh_interval为1秒. Lucene将待写入的数据先写到内存中, 超过1秒(默认)时, 就会触发一次 Refresh, 然后把内存中的的数据刷新到 *** 作系统的文件缓存系统中 如果我们对搜索的实效性要求不高, 可以将 Refresh周期延长, 如30秒. 这样还可以有效地减少段刷新次数, 但这意味着需要消耗更多的 Heap内存 - 加大 Flush设置: Flush的作用是把文件缓存系统中的段持久化到磁盘中, 当 Translog的数据量达到512MB或到了30分钟时, 会触发一次 Flush. index.translog.flush_threshold_size参数的默认值是512MB - 减少副本的数量: 为了保证集群的可用性, ES提供 Replicas(副本)的支持, 然而每个副本也会执行分析, 索引及可能的合并过程, 所以 Replicas的数量会严重影响写索引的效率. `*在大批量写入 *** 作时, 可以先禁止 Replica复制, 设置 index.number_of_replicas: 0关闭副本直到写入完成后, 再开启 Replica`内存设置:
- 配置 ES堆内存的两个原则: (-) 不要超过物理内存的50%: Lucene的设计目的是把底层 OS里的数据缓存到内存中. Lucene的段是分别存储到单个文件中的, 这些文件都是不会变化的, 所以很利于缓存, 同时 *** 作系统也会把这些段文件缓存起来, 以便更快的访问. 如果我们设置的堆内存过大, Lucene可用的内存将会减少, 就会严重影响降低 Lucene的全文本查询性能 (-) 堆内存的大小最好不要超过32GB: 在 Java中, 所有对象都分配在堆上, 然后有一个 Klass Pointer指针指向它的类元数据. 这个指针在64位的 *** 作系统上为64位, 64位的 *** 作系统可以使用更多的内存(2^64). 在32位的系统上为32位, 32位的 *** 作系统的最大寻址空间为4GB(2^32). 但是64位的指针意味着更大的浪费, 因为你的指针本身大了, 浪费内存不算, 更糟糕的是, 更大的指针在主内存和缓存器(例如 LLC, L1等)之间移动数据的时候, 会占用更多的带宽 *机器内存为64G时, 可以将31G用于 一个 ES节点; vim config/jvm.option -Xms 31g -Xmx 31g *ES的堆内存默认配置是1GB重要配置:
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)