优化不必要字段
有些时候,最开始设计索引的人可能没有注意,就把一些根本不会被搜索到的字段也存储到了Elasticsearch。更加可怕的是还是用了动态的mapping,这可能无意间索引了很多新字段。
在实践中最常见错误,就是把数据库里存储的数据全量同步到Elasticsearch上,但是其实根本没有必要。所以这种优化手段就是只把要被查询的字段同步到Elasticsearch上,而把数据的主体部分留在原本的数据库里。
少同步一些数据,就意味着你的索引所需的内存、磁盘更少,所以查询速度也会更快。紧接着补充一个reindex的改进计划。
这种同步部分数据的手段,在日志检索中也很常见。毕竟日志一般都非常长,而搜索一般都是根据业务ID之类的来查询。
还可以尝试在这个地方把话题引导到分库分表中间表上。
冷热分离
基本思路是同一个业务里面数据也有冷热之分,而对于冷数据来说,可以考虑使用运行在廉价服务器上Elasticsearch来存储;对于热数据来说,可以使用运行在昂贵的高性能服务器上的Elasticsearch。
利用生命周期管理功能实现冷热数据分离操作起来还是很简单的,你可以考虑通过Kibana来直接在界面傻瓜式操作,或是使用云服务厂商提供的功能。
最好是根据自己的业务来定制这个回答,这种冷热分离的思路不仅仅可以在Elasticsearch中使用,在微服务治理、缓存中中也有类似的思路,有机会的话也可以尝试引导话题。
常规优化
优化垃圾回收
如果本身是Java开发,非常建议使用这个优化,能展示在JVM上的深厚功底。
一般Elasticsearch优化垃圾回收的第一个思路就是调整垃圾回收算法。Elasticsearch需要一个很大的堆,那么CMS是肯定撑不住的,停顿时间会非常长。
可以考虑把垃圾回收算法换成G1,或是更加激进的ZGC。现在一般用G1比较多。
使用这个方案的核心就是把话题引导到垃圾回收这个主题上
优化swap
Elasticsearch也是一个内存依赖非常严重的中间件,在触发了swap的时候,性能下降的很快。
这里有两种做法:
- 在操作系统层面上直接禁用了swap,或者把vm.swappness设置成一个非常小的值。
- 在Elasticsearch里把bootstrap.memory_lock 设置为true
在面试的时候要注意把Elasticsearch和其他中间件联系在一起,以kafka为例
知识补充
在Linux操作系统中,swap 是一种内存管理功能,它允许系统将当前不活跃的内存页面移动到磁盘上,以便为活跃的进程腾出内存空间。这种机制使得Linux能够运行需要更多内存的程序,即使物理内存(RAM)不足以容纳它们。
Swap的工作原理:
- 页面替换算法: 当系统检测到物理内存不足时,它会使用页面替换算法(如LRU - 最近最少使用算法)来决定哪些页面应该被移动到swap空间。
- 磁盘空间: swap空间通常是一个专门的磁盘分区或文件,操作系统在这个空间中存储被交换出去的内存页面。
- 性能影响: 虽然swap可以提供额外的内存空间,但频繁地使用swap会降低系统性能,因为磁盘I/O比RAM访问要慢得多。
- 交换区和交换文件:
- 交换区(Swap partition):在磁盘上专门划分一个分区作为swap空间。
- 交换文件(Swap file):在磁盘上创建一个大文件作为swap空间,大小固定。
Swap的使用和管理:
- 查看swap空间:使用 free -h 命令可以查看系统的总swap空间以及已使用和空闲的swap空间。
- 启用交换空间:在Linux启动时,swap空间会自动挂载。如果需要手动挂载,可以使用 swapon 命令。
- 添加交换文件:使用 fallocate 创建交换文件,然后使用 mkswap 初始化它,最后使用 swapon 启用它。
- 调整交换行为:通过 /proc/sys/vm/swappiness 文件可以调整系统倾向于使用swap的倾向性。值越高,系统越倾向于使用swap空间。
- 监控swap使用:使用 sar、vmstat、top 或 htop 等工具可以监控swap的使用情况。
Swap的注意事项: - 不要过度依赖swap:虽然swap可以提供额外的内存空间,但频繁的页面交换(swap thrashing)会导致系统响应变慢。
- 合理配置swap空间:根据系统的实际需求配置适量的swap空间。一般建议物理内存的1.5倍,但对于有大量内存需求的服务器,可能需要更多。
- 监控系统性能:定期监控系统性能,确保swap的使用在可接受的范围内。
总的来说,swap是Linux系统中重要的内存管理特性,它允许系统在物理内存不足时继续运行程序。然而,依赖swap可能会影响性能,因此需要合理规划内存和swap的使用。
文件描述符
Elasticsearch需要非常多的文件描述符,所以正常来说需要把文件描述符的数量调大,比如调到65536,甚至更多。
可以用解决Bug的思路来面试,比如问你Elasticsearch什么Bug的时候,也可以用这个回答。
隔离也可以把话题引导到微服务的隔离上。
知识补充
Elasticsearch 使用文件描述符(File Descriptors,FDs)来实现多种功能,主要包括:
-
索引存储: Elasticsearch 将索引数据存储在磁盘上,每个索引文件都通过文件描述符进行管理。
-
网络通信: Elasticsearch 节点之间以及与客户端之间的通信通过 TCP/IP 协议实现,每个网络连接都使用文件描述符来跟踪。
-
日志记录: Elasticsearch 会将日志信息写入到磁盘文件中,这些文件操作同样需要使用文件描述符。
-
缓存实现: Elasticsearch 使用文件描述符来管理其缓存机制,比如请求缓存和字段数据缓存。
-
父进程与子进程间通信: 在某些操作(如分片恢复)中,Elasticsearch 可能会使用 fork 来创建子进程,这时文件描述符用于父子进程间的通信。
-
临时文件: 在执行某些操作(如查询的某些阶段)时,Elasticsearch 可能会创建临时文件,这些文件也需要文件描述符来访问。
-
插件和脚本: Elasticsearch 支持插件和脚本,这些插件和脚本在运行时可能会打开文件,同样需要文件描述符。
-
配置文件: Elasticsearch 读取配置文件(如 elasticsearch.yml)时,也需要使用文件描述符。
最大文件描述符限制: 操作系统对每个进程可以打开的文件描述符数量有限制。如果超过这个限制,Elasticsearch 将无法打开新的文件或网络连接,可能会导致节点不稳定或无法正常工作。
配置建议: 通常建议为 Elasticsearch 节点配置适当的文件描述符限制,例如,可以通过设置 bootstrap.memory_lock 来锁定内存,并确保 Elasticsearch 进程有足够的文件描述符可用。
监控和管理: 可以使用 ulimit -n 命令来查看和设置文件描述符的限制。在生产环境中,应监控 Elasticsearch 节点的文件描述符使用情况,确保不会达到操作系统的限制。
最佳实践: 在部署 Elasticsearch 集群时,考虑到性能和稳定性,应根据节点的物理内存和预期负载来合理配置文件描述符的限制,并在必要时调整操作系统的默认设置。
总之,文件描述符在 Elasticsearch 中扮演着重要的角色,用于管理节点的多种资源和通信。正确地管理和配置文件描述符对于确保 Elasticsearch 集群的健康和性能至关重要。
总结
一般性的性能优化方案可以做个总结
- 优化查询本身:可能涉及到改写SQL、优化索引等
- 优化中间件本身:调整中间件的各种参数
- 优化操作系统:调整内存、网络IO和磁盘方面有关的参数