介绍
elasticsearch
集群的搭建教程很多。网上一搜都是,但是,搭建不难。更重要的是明白集群原理,性能以及运维知识点。所以,本文将从这些点着重介绍。
配置参数详解
在elasticsearch
配置文件中有以下这些参数,将逐一介绍(其实配置文件中英文描述已经非常清楚):
-
集群名,自定义集群名,默认为elasticsearch,建议修改,因为低版本多播模式下同一网段下相同集群名会自动加入同一集群,如生产环境这样易造成数据运维紊乱。cluster.name
-
节点名,同一集群下要求每个节点的节点名不一致,起到区分节点和辨认节点作用node.name
-
是否为主节点,选项为true或false,当为true时在集群启动时该节点为主节点,在宕机或任务挂掉之后会选举新的主节点,恢复后该节点依然为主节点node.master
-
是否处理数据,选项为true或false。负责数据的相关操作node.data
-
默认数据路径,可用逗号分隔多个路径path.data
-
默认日志路径path.logs
-
内存锁,选项为true或false,用来确保用户在es-jvm中设置的bootstrap.mlockall
ES_HEAP_SIZE
参数内存可以使用一半以上而又不溢出 -
对外暴露的host,network.host
0.0.0.0
时暴露给外网 -
对外访问的端口号,默认为http.port
9200
,所以外界访问该节点一般为http://ip:9200/
-
集群间通信的端口号,默认为transport.tcp.port
9300
-
集群的ip集合,可指定端口,默认为discovery.zen.ping.unicast.hosts
9300
,如["192.168.1.101","192.168.1.102"]
-
最少的主节点个数,为了防止脑裂,最好设置为discovery.zen.minimum_master_nodes
(总结点数/2 + 1)
个 -
主节点选举超时时间设置discovery.zen.ping_timeout
-
值为n,网关控制在gateway.recover_after_nodes
n
个节点启动之后才恢复整个集群 -
值为n,一个系统中最多启用节点个数为node.max_local_storage_nodes
n
-
选项为true或false,删除indices是否需要现实名字action.destructive_requires_name
理解主节点、副节点、分片与复制分片
关系
起初创建节点与分片的关系,设置shards=2,replicas=1
解析
-
集群中用于元数据(metadata)的请求处理,比如确定分片位置,索引的新增、删除请求分配等node-master
主节点 -
包括node
client node
和data node
1. `client node` node.master=true,node.data=false 用于转发请求,起到平衡负载的作用2. `data node` node.master=flase,node.data=true> 节点上保存了数据分片。它负责数据相关操作,比如分片的 CRUD,以及搜索和整合操作。这些操作都比较消耗 CPU、内存和 I/O 资源
-
在设置索引时默认(5)或自己设置的分片数量,即indices(1)--shards(n),而每插入一条数据都会在唯一主分片中,即Document(n)--shards(1)shards
分片 -
同样在设置索引时会默认(1)或自定义复制分片数量,该数量对应关系为每个主分片对应的复制分片,即shards(1)--replicas(n)replicas
复制分片
要点
- 当集群健康状态为
yello
表示存在复制分片未被分配(unassigned)到节点中(或者分配的复制节点个数少于设置的个数),这时如果硬件有故障将无法找回数据。 - 在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
- 主分片数量一般是在建立索引时就固定的,一般是不作修改的,如果减少分片数量意味着数据将要丢失
- 复制分片一定意义上可以起到负载的功能,提高数据的冗余量。但如果只是在相同节点数目的集群上增加更多的副本分片并不能提高性能,因为每个分片从节点上获得的资源会变少。 你需要增加更多的硬件资源来提升吞吐量
节点与分片模型
同样设置shards=2,replicas=1
分布式文档存储的关系原理
这个由于在官网指南中写的很清楚了,直接贴出章节。
集群搭建
配置集群
修改配置文件
# vi /etc/elasticsearch/elasticsearch.yml# 统一的集群名cluster.name: syncwt-es# 当前节点名node.name: syncwt-es-node-1# 对外暴露端口使外网访问network.host: 0.0.0.0# 对外暴露端口http.port: 9200# ...还有很多可以设置,这些是基础的。具体看上面的配置参数说明
重启并查看集群健康状态:
# sudo systemctl start elasticsearch.service# curl -XGET 'http://localhost:9200/_cat/health?v'
集群可视化插件安装elasticsearch-head
# cd ${elasticsearch_HOME}# ./plugin install mobz/elasticsearch-head
页面访问效果(单节点):
http://47.105.74:9200/_plugin/head/
注意
- 集群中es的版本应保持一致,最好内网部署,外网不是很稳定。
- 可用容器(如docker)封装统一部署集群各节点以保持配置一致性
- 可在一台机器上运行多个节点来构建集群,只是性能会和机器配置相关
总结
- 集群中节点选型策略。node-data节点(随着数据增加而增加),note-client(随着查询压力而增加)节点
- 集群节点数量上升时,多关注配置参数,如
gateway.recover_after_nodes
等,会带来很多效率的提高 - 当集群数量较大时,建议横向扩展集群。单纯增加es节点的内存和CPU不会有很大提升,建议多增加节点
下面配置信息来源于网络:
1.1. 基本配置
elasticsearch的config文件夹里面有两个配置文 件:elasticsearch.yml和logging.yml,第一个是es的基本配置文件,第二个是日志配置文件,es也是使用log4j来记录日 志的,所以logging.yml里的设置按普通log4j配置文件来设置就行了。下面主要讲解下elasticsearch.yml这个文件中可配置的东西。 cluster.name: elasticsearch 配置es的集群名称,默认是elasticsearch,es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。 node.name: "Franz Kafka" 节点名,默认随机指定一个name列表中名字,该列表在es的jar包中config文件夹里name.txt文件中,其中有很多作者添加的有趣名字。 node.master: true 指定该节点是否有资格被选举成为node,默认是true,es是默认集群中的第一台机器为master,如果这台机挂了就会重新选举master。 node.data: true 指定该节点是否存储索引数据,默认为true。 index.number_of_shards: 5 设置默认索引分片个数,默认为5片。 index.number_of_replicas: 1 设置默认索引副本个数,默认为1个副本。 path.conf: /path/to/conf 设置配置文件的存储路径,默认是es根目录下的config文件夹。 path.data: /path/to/data 设置索引数据的存储路径,默认是es根目录下的data文件夹,可以设置多个存储路径,用逗号隔开,例: path.data: /path/to/data1,/path/to/data2 path.work: /path/to/work 设置临时文件的存储路径,默认是es根目录下的work文件夹。 path.logs: /path/to/logs 设置日志文件的存储路径,默认是es根目录下的logs文件夹 path.plugins: /path/to/plugins 设置插件的存放路径,默认是es根目录下的plugins文件夹 bootstrap.mlockall: true 设置为true来锁住内存。因为当jvm开始swapping时es的效率会降低,所以要保证它不swap,可以把ES_MIN_MEM和 ES_MAX_MEM两个环境变量设置成同一个值,并且保证机器有足够的内存分配给es。同时也要允许elasticsearch的进程可以锁住内存,Linux下可以通过`ulimit -l unlimited`命令。 network.bind_host: 192.168.0.1 设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0。 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", "host2:port", "host3[portX-portY]"] 设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。 下面是一些查询时的慢日志参数设置 index.search.slowlog.level: TRACE index.search.slowlog.threshold.query.warn: 10s index.search.slowlog.threshold.query.info: 5s index.search.slowlog.threshold.query.debug: 2s index.search.slowlog.threshold.query.trace: 500ms index.search.slowlog.threshold.fetch.warn: 1s index.search.slowlog.threshold.fetch.info: 800ms index.search.slowlog.threshold.fetch.debug:500ms index.search.slowlog.threshold.fetch.trace: 200ms1.2. 高级配置(线程池)
一个Elasticsearch节点会有多个线程池,但重要的是下面四个: 索引(index):主要是索引数据和删除数据操作(默认是cached类型) 搜索(search):主要是获取,统计和搜索操作(默认是cached类型) 批量操作(bulk):主要是对索引的批量操作(默认是cached类型) 更新(refresh):主要是更新操作(默认是cached类型) 可以通过给设置一个参数来改变线程池的类型(type),例如,把索引的线程池改成blocking类型: min: 1 size: 30 wait_time: 30s下面是三种可以设置的线程池的类型:
cache cache线程池是一个无限大小的线程池,如果有很多请求的话都会创建很多线程,下面是个例子: threadpool: index: type: cachedfixed
fixed线程池保持固定个数的线程来处理请求队列。 size参数设置线程的个数,默认设置是cpu核心数的5倍 queue_size可以控制待处理请求队列的大小。默认是设置为-1,意味着无限制。当一个请求到来但队列满了的时候,reject_policy参数可以控制它的行为。默认是abort,会使那个请求失败。设置成caller会使该请求在io线程中执行。 threadpool: index: type: fixed size: 30 queue: 1000 reject_policy: callerblocking
blocking线程池允许设置一个最小值(min,默认为1)和线程池大小(size,默认为cpu核心数的5倍)。它也有一个等待队列,队列的大小(queue_size )默认是1000,当这队列满了的时候。它会根据定好的等待时间(wait_time,默认是60秒)来调用io线程,如果超时没有执行就会报错。 threadpool: index: type: blocking min: 1 size: 30 wait_time: 30s笔者在实际工作中,由于程序启动时即产生大量请求,导致队列大小溢出的情况,从而查询请求报错,可以在以下2个解决方法权衡处理:
1、增加队列长度,但随之带来的是CPU消耗高。 2、优化程序,适当控制程序的并发请求量。1.3. 操作系统配置
1、文件句柄限制:ES在索引过程中,尤其是有很多分片和副本时,会创建若干文件。因此操作系统对打开文件数量的限制不能少于32000。对于linux服务器,通过可以在/etc/security/limits.conf中进行修改,并且可以用ulimit命令来查看当前值。 2、节点内存配置:ES每个节点默认的2014M内存空间可能是不够的。如果日志文件中有out of memory error错误,则应将环境变量ES_HEAP_SIZE设为大于1024的值。注意该值应超过总可用物理内存的50%,剩余内存可用作磁盘高速缓存,可大大提高搜索性能。 作者:syncwt 链接:https://www.jianshu.com/p/149a8da90bbc 來源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。