Fork me on GitHub

Elasticsearch集群部署

简介

Elasticsearch是一款稳定高效的分布式搜索和分析引擎,它的底层基于 Lucene,并提供了友好的RESTful API来对数据进行操作。Elasticsearch 在搭建企业级搜索(如日志搜索、商品搜索等)平台中很广泛,官网也提供了不少案例

基本概念

Index (索引):Index 是名词,一个 Index 就像是传统关系数据库的 Database,它是 Elasticsearch 用来存储数据的逻辑区域
Document (文档):Elasticsearch 使用 JSON 文档来表示一个对象,就像是关系数据库中一个 Table 中的一行数据
Type (类型):文档归属于一种 Type,就像是关系数据库中的一个 Table
Field (字段):每个文档包含多个字段,类似关系数据库中一个 Table 的列

Node (节点):node 是一个运行着的 Elasticsearch 实例,一个 node 就是一个单独的 server
Cluster (集群):cluster 是多个 node 的集合
Shard (分片):数据分片,一个 index 可能会存在于多个 shard

配置环境

操作系统:Ubuntu14.04
JDK:jdk1.8.0_121
Elasticsearch:2.3.3

节点 IP master 数据节点
node-mater 192.168.1.10
node-1 192.168.1.11
node-2 192.168.1.12

安装与部署

下载不同版本地址:elasticsearch

当前以2.3.3版本为例

用户/目录/权限设置

创建用户

useradd es -s /sbin/nologin

新建目录, 假如/data/目录挂载的硬盘最大(100G以上)

mkdir -p /data/elstaticsearch/logs
mkdir -p /data/elstaticsearch/data

chown -R es:es /data/elstaticsearch/logs
chown -R es:es /data/elstaticsearch/data

配置内存

修改文件./bin/elasticsearch.in.sh:

if [ "x$ES_MIN_MEM" = "x" ]; then
    ES_MIN_MEM=5g  //最小内存,根据机器内存来定
fi
if [ "x$ES_MAX_MEM" = "x" ]; then
    ES_MAX_MEM=8g  //最大内存,根据机器内存来定,最好不要超过机器物理内存的50%
fi

linux配置文件/etc/profile中设置:

export ES_HEAP_SIZE=8g //根据机器内存来定,一般分配不超过50%

配置系统”最大打开文件数”

解决es启动的警告信息:Too many open files的问题

 vi /etc/security/limits.conf
root soft nofile 65535
root hard nofile 65535  #或者合并为:root - nofile 65535
* soft nofile 65535
* hard nofile 65535  #或者合并为:* - nofile 65535

修改配置文件

修改elstaticsearch的配置文件

config/elasticsearch.yml

主节点配置

#集群名,自定义集群名
cluster.name: jasontest

#节点名,同一集群下要求每个节点的节点名不一致
node.name: node-master
#指定该节点是否有资格被选举成为master节点
node.master: true
#允许该节点存储数据
node.data: false

#数据路径,可用逗号分隔多个路径
path.data: /data/elstaticsearch/data
#日志路径
path.logs: /data/elstaticsearch/logs

#内存锁,选项为true或false,允许 JVM 锁住内存,禁止操作系统交换出去
bootstrap.mlockall: true
#用于设置缓存类型为Soft Reference,它的主要特点是据有较强的引用功能,只有当内存不够的时候,
#才进行回收这类内存,因此在内存足够的时候,它们通常不被回收
index.cache.field.type: soft
#用于设置缓存field的最大值
index.cache.field.max_size: 50000
#用于设置filters缓存大小,可以是百分比或者确切的值,如512mb
indices.cache.filter.size: 2014mb
用于设置field data缓存大小,可以是百分比或者确切的值,如512mb
indices.fielddata.cache.size: 1024mb
#用于设置field data缓存超时时间
indices.fielddata.cache.expire: 10m

#设置绑定的ip地址,可以是ipv4或ipv6的
network.bind_host: 192.168.0.10
#设置其它节点和该节点交互的ip地址,如果不设置它会自动设置,值必须是个真实的ip地址
network.publish_host: 192.168.0.10
#同时设置bind_host和publish_host上面两个参数,一般设置其即可
network.host: 192.168.0.10
#设置对外服务的http端口,默认为9200 
http.port: 9200
#设置节点间交互的tcp端口
transport.tcp.port: 9300
#配置是否允许跨域请求
http.cors.enabled: true
#定义允许哪些源请求。可以使用正则表达式,设置为*即任何来源都可访问
http.cors.allow-origin: "*"

#设置当前结点等待其他结点的ping信号的超时时间,提高一点以应对网络不好的时候,防止脑裂
discovery.zen.ping.timeout: 100s
#设置当前结点发送ping信号后等待目标结点响应的时间,超过该时间,当前结点认为目标结点无法响应
discovery.zen.fd.ping_timeout: 120s
#设置重试次数,超过此次数之后,判定目标结点出现故障,停止工作
discovery.zen.fd.ping_retries: 10
#设置结点之间互相ping信号的时间间隔
discovery.zen.fd.ping_interval: 30s
#设置是否打开多播发现节点。当多播不可用或集群跨网段的时候集群通信还是选择单播
discovery.zen.ping.multicast.enabled: false
#集群中的主节点的初始列表,当节点(主节点或者数据节点)启动时使用这个列表进行探测
discovery.zen.ping.unicast.hosts: ["192.168.1.10:9300","192.168.1.11:9300","192.168.1.12:9300"]
#决定了要选举一个Master需要多少个节点(最少候选节点数),为了防止脑裂,最好设置为(集群中节点的数量/2 + 1)个
discovery.zen.minimum_master_nodes: 2

从节点配置,以下是一些关键配置项,其他的配置参考主节点配置并保持一致性,防止出现问题

cluster.name: jasontest

node.name: node-1 #另一台节点即node.name: node-2,其他参数配置保持一致
node.master: false
node.data: true

path.data: /data/elstaticsearch/data
path.logs: /data/elstaticsearch/logs

以上主从节点据配置好之后,在各个节点服务器内以创建的低级权限的用户(例如:es)启动elasticsearch:

su es
cd /opt/elasticsearch/
./bin/elasticsearch -d # -d 后台以守护进程模式运行

Elasticsearch 启动后,也启动了两个端口 9200 和 9300:

9200 端口:HTTP RESTful 接口的通讯端口
9300 端口:TCP 通讯端口,用于集群间节点通信和与 Java 客户端通信的端口

基本API

1.查看集群健康状态

curl -XGET 'http://localhost:9200/_cluster/health?pretty'

查询结果即:

{
  "cluster_name" : "jasontest",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 2,
  "active_primary_shards" : 300,
  "active_shards" : 600,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 10.0
}

各参数说明:

cluster_name:这是集群的名称。
timeout:这是一个布尔值,指示REST API是否触发了调用中设置的超时。
number_of_nodes:这表示集群中的节点数。
number_of_data_nodes:可以存储数据的节点数
active_primary_shards:活动的主分片数; 执行写操作的master分片的数量
active_shards:显示活动分片的数量。 这些分片可以用于搜索。
relocating_shards:显示正在重定位的分片数,从节点迁移到另一个节点。 这主要是由于集群节点的平衡。
initializing_shards:显示初始化状态下的分片数。 初始化过程在分片启动时完成。 在变得活跃状态之前,这是一个暂态,它由几个步骤组成,其中最重要的是如下:
    复制分片数据复制(如果是另一个副本)
    检查Lucene索引
    根据需要处理事务日志
unassigned_shards:未分配给节点的分片数。 这通常是由于设置的副本数大于节点数。 在启动期间,尚未初始化或初始化的分片将在此计数。
delayed_unassigned_shards:这将显示分配的分片数,但是它们的节点被配置为延迟分配。 您可以访问https://www.elastic.co/guide/en/elasticsearch/reference/5.0/delayed-allocation.html获取有关延迟分片分配的更多信息。
number_of_pending_tasks:这是集群级别的待处理任务数,例如集群状态更新,创建索引和分片重定位。 它很少是0以外的任何东西。
number_of_in_flight_fetch:必须在分片中执行的集群更新数。 因为集群更新是异步的,这个数字是跟踪分片中还需要执行的数量。
task_max_waiting_in_queue_millis:这是某些集群任务在队列中等待的最长时间。 它很少是0以外的任何东西。如果值不同于0,这意味着集群的某些资源饱和了或者类似的问题
active_shards_percent_as_number:这是集群中,集群所需要的活动分片数量占总数的百分比。 在生产环境中,除了一些搬迁和分片初始化之外,它几乎与100%不同。

elasticsearch 集群健康状况返回颜色取值:

green
    所有的主分片和副本分片都已分配。你的集群是 100% 可用的。
yellow
    所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。不过,你的高可用性在某种程度上被弱化。如果更多的分片消失,你就会丢数据了。把yellow想象成一个需要及时调查的警告。
red
    至少一个主分片(以及它的全部副本)都在缺失中。这意味着你在缺少数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常。

2.查看集群节点情况

curl -XGET 'http://localhost:9200/_cat/nodes?v' # v代表输出表头

查询结果即:

host        ip          heap.percent ram.percent load node.role master name        
192.168.1.12 192.168.1.12           29          99 2.93 d         -      node-2      
192.168.1.10 192.168.1.10           27          86 0.67 -         *      node-master 
192.168.1.11 192.168.1.11           22          99 7.36 d         -      node-1

3.查看节点详细信息

curl -XGET http://localhost:9200/_nodes/process?pretty

查询结果即:

{
  "cluster_name" : "jasontest",
  "nodes" : {
    "WaqiU7wS3ObAc5f5mgf8Q" : {
      "name" : "node-2",
      "transport_address" : "192.168.1.11:9300",
      "host" : "192.168.1.11",
      "ip" : "192.168.1.11",
      "version" : "2.3.3",
      "build" : "218bdf1",
      "http_address" : "192.168.1.11:9200",
      "attributes" : {
        "master" : "false"
      },
      "process" : {
        "refresh_interval_in_millis" : 1000,
        "id" : 20891,
        "mlockall" : false
      }
    },
    "Ac9Wd8dpSwGymkUOsU6RYg" : {
    ......
    "attributes" : {
       "master" : "true"
    },
    "EdSfAdEWR5fSDGse8bgsl" : {
    ......

4.查看unassigned shards

curl -s http://localhost:9200/_cat/shards | grep UNASSIGNED
curl -X GET localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason| grep UNASSIGNED #unassigned shards的详情

查询结果即(第一列表示索引名,第二列表示分片编号,第三列p是主分片、r是副本):

es1     3 r UNASSIGNED
es1     2 r UNASSIGNED
es1     1 r UNASSIGNED
es1     0 r UNASSIGNED    

5.处理中Elasticsearch集群yellow和red状态

查看是哪个索引的status是red/yellow导致了集群都red/yellow了,查找API即:

curl -X GET 'http://localhost:9200/_cluster/health?level=indices&pretty' #格式化显示, 或者使用python -m json.tool格式化
curl -X GET 'http://localhost:9200/_cluster/health?level=indices' | grep red #可以看到索引信息

修复导致了集群状态red/yellow的unassigned shards索引:

curl -XPOST 'http://localhost:9200/_cluster/reroute' -d '{
    "commands" : [ {
          "allocate" : {
              "index" : "es1",
              "shard" : 0,
              "node" : "EdSfAdEWR5fSDGse8bgsl",
              "allow_primary" : true
          }
        }
    ]
}'        

注意:其中_cluster/reroute这个API中参数node,可根据_nodes/process接口查询到,尝试使用其中的数据节点

6.删除索引
1)命令格式:

curl -XDELETE http://localhost:9200/索引名称

例如:删除索引”data-2018.08.10”

$ curl -XDELETE http://localhost:9200/data-2018.08.10
{"acknowledged":true} #表示删除成功

2)一次删除多个索引,中间用逗号隔开
例如:删除index1,index2两个索引

$ curl -XDELETE http://localhost:9200/index1,index2
{"acknowledged":true} #表示删除成功

3)模糊匹配删除
例如:删除以”data-2018.08”为前缀的索引即”data-2018.08.*”

$ curl -XDELETE http://localhost:9200/data-2018.08.*
{"acknowledged":true} #表示删除成功

4)使用通配符,删除所有的索引
命令:

curl -XDELETE http://localhost:9200/_all
或 curl -XDELETE http://localhost:9200/*

_all , 通配所有的索引, 通常不建议使用通配符,误删了后果就很严重了。
为了安全起见,可以在配置文件中设置禁用_all和
通配符

action.destructive_requires_name = true 
轻轻的我走了,正如我轻轻的来