优化
es的安装和配置是⾮常轻量级的,为满⾜多种不同的应⽤场景,底层提供多种数据结构⽀持,并做了⼤量的默认配置优化,部分配置针对具体的⽤户使⽤场景可能是冗余的,甚⾄可能造成性能的下降,需要根据实际业务场景做适当取舍,我们结合⾃⾝使⽤场景做了如下优化(⽂章中有疏漏或不正确的地⽅也欢迎点评指正)。⼀、环境配置
sudo swapoff -a
# 禁⽤swapping,开启服务器虚拟内存交换功能会对es产⽣致命的打击vm.max_map_count
# 在/etc/sysctl.conf⽂件中找到该参数,修改为655300后 执⾏sysctl -p,不然启动时会报值太⼩
⼆、内存优化
常⽤的配置在两个⽂件⾥,分别是 elasticsearch.yml 和 jvm.options(配置内存)
jvm.options主要是进⾏内存相关配置,elasticsearch默认给的1g,官⽅建议分配给es的内存不要超出系统内存的50%,预留⼀半给Lucene,因为Lucene会缓存segment数据提升检索性能;内存配置不要超过32g,如果你的服务器内存没有远远超过g,那么不建议将es的jvm内存设置为32g,因为超过32g后每个jvm对象指针的长度会翻倍,导致内存与cpu的开销增⼤。
-Xms10g-Xmx10g
三、基础配置
修改配置⽂件elasticsearch.yml
cluster.name: elasticsearch
集群名称,es服务会通过⼴播⽅式⾃动连接在同⼀⽹段下的es服务,通过多播⽅式进⾏通信,同⼀⽹段下可以有多个集群,通过集群名称这个属性来区分不同的集群。
node.name: \"test\"
当前配置所在机器的节点名,你不设置就默认随机指定⼀个name列表中名字,该name列表在es的jar包中config⽂件夹⾥name.txt⽂件中,其中有很多作者添加的有趣名字。
node.master: true
指定该节点是否有资格被选举成为node(注意这⾥只是设置成有资格, 不代表该node⼀定就是master),默认是true,es是默认集群中的第⼀台机器为master,如果这台机挂了就会重新选举master。node.data: true
指定该节点是否存储索引数据,默认为true。index.number_of_shards: 5
设置默认索引分⽚个数,默认为5⽚。
index.number_of_replicas: 1
设置默认索引副本个数,默认为1个副本。如果采⽤默认设置,⽽你集群只配置了⼀台机器,那么集群的健康度为yellow,也就是所有的数据都是可⽤的,但是某些复制没有被分配。
path.conf: /path/to/conf
设置配置⽂件的存储路径,默认是es根⽬录下的config⽂件夹。
path.data: /path/to/data
设置索引数据的存储路径,默认是es根⽬录下的data⽂件夹,可以设置多个存储路径,⽤逗号隔开,例:path.data: /path/to/data1,/path/to/data2path.work: /path/to/work
设置临时⽂件的存储路径,默认是es根⽬录下的work⽂件夹。path.logs: /path/to/logs
设置⽇志⽂件的存储路径,默认是es根⽬录下的logs⽂件夹
path.plugins: /path/to/plugins
设置插件的存放路径,默认是es根⽬录下的plugins⽂件夹, 插件在es⾥⾯普遍使⽤,⽤来增强原系统核⼼功能。
bootstrap.mlockall: true
设置为true来锁住内存不进⾏swapping。因为当jvm开始swapping时es的效率 会降低,所以要保证它不swap,可以把ES_MIN_MEM和
ES_MAX_MEM两个环境变量设置成同⼀个值,并且保证机器有⾜够的内存分配给es。 同时也要允许elasticsearch的进程可以锁住内存,linux下启动es之前可以通过`ulimit -l unlimited`命令设置。
network.bind_host: 192.168.0.1
设置绑定的ip地址,可以是ipv4或ipv6的,默认为127.0.0.1。network.publish_host: 192.168.0.1
设置其它节点和该节点交互的ip地址,如果不设置它会⾃动判断,值必须是个真实的ip地址。network.host: 192.168.0.1
这个参数是⽤来同时设置bind_host和publish_host上⾯两个参数。transport.tcp.port: 9300
设置节点之间交互的tcp端⼝,默认是9300。
transport.tcp.compress: true
设置是否压缩tcp传输时的数据,默认为false,不压缩。http.port: 9200
设置对外服务的http端⼝,默认为9200。http.max_content_length: 100mb设置内容的最⼤容量,默认100mb
http.enabled: false
是否使⽤http协议对外提供服务,默认为true,开启。
gateway.type: local
gateway的类型,默认为local即为本地⽂件系统,可以设置为本地⽂件系统,分布式⽂件系统,hadoop的HDFS,和amazon的s3服务器等。gateway.recover_after_nodes: 1
设置集群中N个节点启动时进⾏数据恢复,默认为1。gateway.recover_after_time: 5m
设置初始化数据恢复进程的超时时间,默认是5分钟。
gateway.expected_nodes: 2
设置这个集群中节点的数量,默认为2,⼀旦这N个节点启动,就会⽴即进⾏数据恢复。cluster.routing.allocation.node_initial_primaries_recoveries: 4初始化数据恢复时,并发恢复线程的个数,默认为4。cluster.routing.allocation.node_concurrent_recoveries: 2添加删除节点或负载均衡时并发恢复线程的个数,默认为4。indices.recovery.max_size_per_sec: 0
设置数据恢复时的带宽,如⼊100mb,默认为0,即⽆。
indices.recovery.concurrent_streams: 5
设置这个参数来从其它分⽚恢复数据时最⼤同时打开并发流的个数,默认为5。
discovery.zen.minimum_master_nodes: 1
设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点。默认为1,对于⼤的集群来说,可以设置⼤⼀点的值(2-4)discovery.zen.ping.timeout: 3s
设置集群中⾃动发现其它节点时ping连接超时时间,默认为3秒,对于⽐较差的⽹络环境可以⾼点的值来防⽌⾃动发现时出错。discovery.zen.ping.multicast.enabled: false设置是否打开多播发现节点,默认是true。
discovery.zen.ping.unicast.hosts: [\"host1\
设置集群中master节点的初始列表,可以通过这些节点来⾃动发现新加⼊集群的节点。 三、集群优化
1、集群规划优化实践
1.1 基于⽬标数据量规划集群
在业务初期,经常被问到的问题,要⼏个节点的集群,内存、CPU要多⼤,要不要SSD?最主要的考虑点是:你的⽬标存储数据量是多⼤?可以针对⽬标数据量反推节点多少。1.2 要留出容量Buffer
注意:Elasticsearch有三个警戒⽔位线,磁盘使⽤率达到85%、90%、95%。不同警戒⽔位线会有不同的应急处理策略。
这点,磁盘容量选型中要规划在内。控制在85%之下是合理的。当然,也可以通过配置做调整。
1.3 ES集群各节点尽量不要和其他业务功能复⽤⼀台机器。除⾮内存⾮常⼤。
举例:普通服务器,安装了ES+Mysql+redis,业务数据量⼤了之后,势必会出现内存不⾜等问题。1.4 磁盘尽量选择SSD
Elasticsearch官⽅⽂档肯定推荐SSD,考虑到成本的原因。需要结合业务场景,如果业务对写⼊、检索速率有较⾼的速率要求,建议使⽤SSD磁盘。阿⾥的业务场景,SSD磁盘⽐机械硬盘的速率提升了5倍。但要因业务场景⽽异。
1.5 内存配置要合理
官⽅建议:堆内存的⼤⼩是官⽅建议是:Min(32GB,机器内存⼤⼩/2)。
Medcl和wood⼤叔都有明确说过,不必要设置32/31GB那么⼤,建议:热数据设置:26GB,冷数据:31GB。总体内存⼤⼩没有具体要求,但肯定是内容越⼤,检索性能越好。
经验值供参考:每天200GB+增量数据的业务场景,服务器⾄少要GB内存。除了JVM之外的预留内存要充⾜,否则也会经常OOM。
1.6 CPU核数不要太⼩
CPU核数是和ESThread pool关联的。和写⼊、检索性能都有关联。建议:16核+。
1.7 超⼤量级的业务场景,可以考虑跨集群检索
除⾮业务量级⾮常⼤,例如:滴滴、携程的PB+的业务场景,否则基本不太需要跨集群检索。
1.8 集群节点个数⽆需奇数
ES内部维护集群通信,不是基于zookeeper的分发部署机制,所以,⽆需奇数。
但是discovery.zen.minimum_master_nodes的值要设置为:候选主节点的个数/2+1,才能有效避免脑裂。1.9 节点类型优化分配
集群节点数:<=3,建议:所有节点的master:true, data:true。既是主节点也是路由节点。集群节点数:>3, 根据业务场景需要,建议:逐步独⽴出Master节点和协调/路由节点。1.10 建议冷热数据分离
热数据存储SSD和普通历史数据存储机械磁盘,物理上提⾼检索效率。2、索引优化实践
Mysql等关系型数据库要分库、分表。Elasticserach的话也要做好充分的考虑。
2.1 设置多少个索引?
建议根据业务场景进⾏存储。
不同通道类型的数据要分索引存储。举例:知乎采集信息存储到知乎索引;APP采集信息存储到APP索引。2.2 设置多少分⽚?建议根据数据量衡量。
经验值:建议每个分⽚⼤⼩不要超过30GB。
2.3 分⽚数设置?
建议根据集群节点的个数规模,分⽚个数建议>=集群节点的个数。5节点的集群,5个分⽚就⽐较合理。
注意:除⾮reindex操作,分⽚数是不可以修改的。
2.4副本数设置?
除⾮你对系统的健壮性有异常⾼的要求,⽐如:银⾏系统。可以考虑2个副本以上。否则,1个副本⾜够。
注意:副本数是可以通过配置随时修改的。
2.5不要再在⼀个索引下创建多个type
即便你是5.X版本,考虑到未来版本升级等后续的可扩展性。
建议:⼀个索引对应⼀个type。6.x默认对应_doc,5.x你就直接对应type统⼀为doc。
2.6 按照⽇期规划索引
随着业务量的增加,单⼀索引和数据量激增给的⽭盾凸显。按照⽇期规划索引是必然选择。
好处1:可以实现历史数据秒删。很对历史索引delete即可。注意:⼀个索引的话需要借助delete_by_query+force_merge操作,慢且删除不彻底。好处2:便于冷热数据分开管理,检索最近⼏天的数据,直接物理上指定对应⽇期的索引,速度快的⼀逼!操作参考:模板使⽤+rollover API使⽤。
2.7 务必使⽤别名
ES不像mysql⽅⾯的更改索引名称。使⽤别名就是⼀个相对灵活的选择。
3、数据模型优化实践
3.1 不要使⽤默认的Mapping
默认Mapping的字段类型是系统⾃动识别的。其中:string类型默认分成:text和keyword两种类型。如果你的业务中不需要分词、检索,仅需要精确匹配,仅设置为keyword即可。根据业务需要选择合适的类型,有利于节省空间和提升精度,如:浮点型的选择。3.2 Mapping各字段的选型流程在这⾥插⼊图⽚描述
3.3 选择合理的分词器
常见的开源中⽂分词器包括:ik分词器、ansj分词器、hanlp分词器、结巴分词器、海量分词器、“ElasticSearch最全分词器⽐较及使⽤⽅法” 搜索可查看对⽐效果。如果选择ik,建议使⽤ik_max_word。因为:粗粒度的分词结果基本包含细粒度ik_smart的结果。3.4 date、long、还是keyword
根据业务需要,如果需要基于时间轴做分析,必须date类型;如果仅需要秒级返回,建议使⽤keyword。
4、数据写⼊优化实践4.1 要不要秒级响应?
Elasticsearch近实时的本质是:最快1s写⼊的数据可以被查询到。
如果refresh_interval设置为1s,势必会产⽣⼤量的segment,检索性能会受到影响。所以,⾮实时的场景可以调⼤,设置为30s,甚⾄-1。4.2 减少副本,提升写⼊性能。写⼊前,副本数设置为0,
写⼊后,副本数设置为原来值。4.3 能批量就不单条写⼊
批量接⼝为bulk,批量的⼤⼩要结合队列的⼤⼩,⽽队列⼤⼩和线程池⼤⼩、机器的cpu核数。4.4 禁⽤swap
在Linux系统上,通过运⾏以下命令临时禁⽤交换:
sudo swapoff -a1
5、检索聚合优化实战
5.1 禁⽤ wildcard模糊匹配
数据量级达到TB+甚⾄更⾼之后,wildcard在多字段组合的情况下很容易出现卡死,甚⾄导致集群节点崩溃宕机的情况。后果不堪设想。替代⽅案:
⽅案⼀:针对精确度要求⾼的⽅案:两套分词器结合,standard和ik结合,使⽤match_phrase检索。⽅案⼆:针对精确度要求不⾼的替代⽅案:建议ik分词,通过match_phrase和slop结合查询。5.2极⼩的概率使⽤match匹配
中⽂match匹配显然结果是不准确的。很⼤的业务场景会使⽤短语匹配“match_phrase\"。match_phrase结合合理的分词词典、词库,会使得搜索结果精确度更⾼,避免噪⾳数据。5.3 结合业务场景,⼤量使⽤filter过滤器
对于不需要使⽤计算相关度评分的场景,⽆疑filter缓存机制会使得检索更快。举例:过滤某邮编号码。
5.3控制返回字段和结果
和mysql查询⼀样,业务开发中,select * 操作⼏乎是不必须的。同理,ES中,_source 返回全部字段也是⾮必须的。
要通过_source 控制字段的返回,只返回业务相关的字段。
⽹页正⽂content,⽹页快照html_content类似字段的批量返回,可能就是业务上的设计缺陷。显然,摘要字段应该提前写⼊,⽽不是查询content后再截取处理。5.4 分页深度查询和遍历分页查询使⽤:from+size;遍历使⽤:scroll;
并⾏遍历使⽤:scroll+slice。斟酌集合业务选型使⽤。
5.5 聚合Size的合理设置
聚合结果是不精确的。除⾮你设置size为2的32次幂-1,否则聚合的结果是取每个分⽚的Top size元素后综合排序后的值。实际业务场景要求精确反馈结果的要注意。
尽量不要获取全量聚合结果——从业务层⾯取TopN聚合结果值是⾮常合理的。因为的确排序靠后的结果值意义不⼤。5.6 聚合分页合理实现
聚合结果展⽰的时,势必⾯临聚合后分页的问题,⽽ES官⽅基于性能原因不⽀持聚合后分页。如果需要聚合后分页,需要⾃开发实现。包含但不限于:⽅案⼀:每次取聚合结果,拿到内存中分页返回。⽅案⼆:scroll结合scroll after集合redis实现。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务