ES1_1使用ES

Elasticsearch 是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据。ElasticSearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
Elasticsearch 是一个分布式、可扩展、实时的搜索与数据分析引擎。大致上,它有以下重要特征:

  • 面向文档
  • Lucene 索引
  • 分布式

这篇文档主要介绍如何配置测试环境、搭建ES集群。

开始使用 ES

使用包管理安装

  1. 使用包管理器安装比较方便,但是需要添加一个源,默认的版本比较低可能出现启动服务失败或启动了服务也不能访问的情况
    1
    2
    3
    4
    wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - # 横杠替代文件名,可以从标准收入读取
    sudo apt-get install apt-transport-https # 安装[apt-transport-https](https://packages.debian.org/wheezy/apt-transport-https)后包管理器可以解析/etc/apt/sources.list文件中 'deb https://foo distro main' 这样的项,即可以通过https来访问包的元数据及下载
    echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list # 将仓库的定义保存到一个.list文件
    sudo apt-get update && sudo apt-get install elasticsearch
  2. 如果没有包管理器,或者只有 yum 不方便安装 apt,可以用 wget 下载 deb 包安装
    1
    2
    3
    4
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.3.deb
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.3.deb.sha512
    shasum -a 512 -c elasticsearch-6.1.3.deb.sha512
    sudo dpkg -i elasticsearch-6.1.3.deb
  3. 修改配置文件/etc/elasticsearch/elasticsearch.yml
    1
    2
    # network.host: 192.168.0.1
    network.host: 0.0.0.0
  4. 启动服务
    elasticsearch 默认安装在/usr/share/elasticsearch,日志在/var/log/elasticsearch 目录,启动时的错误信息可以在/var/log/elasticsearch/elasticsearch.log 中看到,数据在/var/lib/elasticsearch 目录
    1
    2
    service elasticsearch start
    elasticsearch -d # 如果是通过安装包运行的,加上-d作为守护进程运行
  5. 安装 Kibana Sense
    1
    apt-get install kibana
    修改配置文件/etc/kibana/kibana.yml,修改服务监听:
    1
    2
    #server.host: "localhost"
    server.host: "0.0.0.0"
    启动:
    1
    service kibana start
  6. 访问
    1
    2
    3
    4
    5
    6
    7
    8
    curl -i -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
    curl -i -XGET 'http://localhost:9200/_count?pretty' -d '
    {
    "query": {
    "match_all": {}
    }
    }
    '

使用 Docker 运行 Elasticsearch

创建网络:

1
docker network create -d bridge --attachable network_es

查找可用的镜像,以 elasticsearch 为例:

1
docker search elasticsearch

Docker Hub查看可用的Tag,然后就可以下载及运行容器了:

1
2
3
4
5
# 单机单节点
mkdir -p /opt/elasticsearch/config
mkdir -p /opt/elasticsearch/data
echo "http.host: 0.0.0.0" >> /opt/elasticsearch/config/elasticsearch.yml
docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -v /opt/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /opt/elasticsearch/data:/usr/share/elasticsearch/data --network network_es --name es elasticsearch:5.6.11

为了方便起见,跑一个 Kibana 作为控制台来操作:

ELASTICSEARCH_URL 必须是容器的 IP,不能是 127.0.0.1 或 localhost,如果启动 kibana 的时候 ELASTICSEARCH_URL 写的 localhost:9200 那么 kibana 可以启动,但进入页面就会显示连接不上 elasticsearch。所以就需要进入 es 容器中查看 es 容器 ip(ip addr),然后将 ELASTICSEARCH_URL 改为 es 容器 ip 地址才行。

1
docker run -d -p 5601:5601 -e ELASTICSEARCH_URL=http://172.19.0.1:9200 --network network_es kibana:5.6.11

如果启动失败,一般是 Elasticsearch 的bootstrap checks没有通过,先找到镜像 ID 然后再查看日志:

1
2
docker ps -a
docker logs <Container ID>

如果碰到类似:[blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];这样的异常
可以运行下面的命令解决:

1
curl -XPUT -H "Content-Type: application/json" http://localhost:9204/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'

需要注意的点:

  1. kibana的版本要和elasticsearch匹配;
  2. 如果是在本地启动es和kibana,那么kibana的参数ELASTICSEARCH_URL不要设置为localhost,而是用ifconfig确定网卡的IP。

调试debug ES

从github上下载源码,切到5.6分支(我读的版本),在debug模式下运行ES:

1
./gradlew run --debug-jvm

然后启动Idea的远程调试,端口选8000,模块选择elasticsearch
在源码的RestSearchAction里打断点,再在url里执行:
http://localhost:9200/_search
就可以看到执行到断点中断了。
单机下只用到一个9200端口,9200用于开放HTTP服务,而9300用于节点间的通信。

创建索引,并为索引分配分片

  1. 创建索引
    下面的请求创建了一个索引,并且为其分配了 3 个主分片和一份副本(每个主分片拥有一个副本分片):
    1
    2
    3
    4
    5
    6
    7
    PUT /blogs
    {
    "settings" : {
    "number_of_shards" : 3,
    "number_of_replicas" : 1
    }
    }
  2. 健康检查
    下面的请求查询集群的健康状况,此时 status 的值为 yellow,因为副分片还没有被分配,因为在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
    1
    2
    3
    4
    5
    6
    # 节点情况
    GET /_nodes/stats
    # 集群情况
    GET /_cluster/health
    # 打印更紧凑的集群信息
    GET /_cat/health

创建多个节点,一个主节点及一个副节点备份

  1. 创建配置文件目录
    一个在/etc/esconf/esins1/,一个在/etc/esconf/esins2/,保证下面参数相等:
    1
    2
    3
    4
    5
    6
    cluster.name: es_prod
    node.master: true
    node.data: true
    network.host: 0.0.0.0
    discovery.zen.minimum_master_nodes: 2
    node.max_local_storage_nodes: 2
    下面参数由节点名确定:
    1
    2
    3
    4
    node.name: node1
    path.data: /var/lib/es/esins1/data
    path.logs: /var/log/es/esins1/logs
    discovery.zen.ping.unicast.hosts: ["host1:post"] # 副结点的 ip:post 数组:["host1:post", "host2:port"]
  2. 分配用户
    Elasticsearch 不允许以 root 权限执行,这是由于 Elasticsearch 可以接收用户输入的脚本并且执行,为了系统安全考虑,创建一个单独的用户用来运行 Elasticsearch:
    1
    2
    3
    4
    groupadd es
    useradd es -g es -p 123456
    usermod -g es es
    chown -R es:es /etc/esconf/esins1/ # 将相关的文件的权限分配给这个用户
  3. 修改文件描述符的限制,编辑/etc/security/limits.conf,然后注销重新登入这个用户

es soft nofile 65536
es hard nofile 65536

1
2
1. 启动节点
当第二个节点加入到集群后,3 个 副本分片 将会分配到这个节点上——每个主分片对应一个副本分片。

export ES_PATH_CONF=/etc/esconf/esins1/ # 修改环境变量,指定配置文件位置
export ES_HEAP_SIZE=1g # 默认是 1g,-Xms=-Xmx,且最小值也是 1g
./elasticsearch -d -p /etc/esconf/esins1.pid
1
2
3
1. 查看节点情况

http://59.110.172.126:9200/_nodes

使用logstash导入数据

节点配置

分片副本配置

  • number_of_shards
    每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改
  • number_of_replicas
    每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改,比如使用 API 动态修改:
    1
    2
    3
    4
    PUT /my_temp_index/_settings
    {
    "number_of_replicas": 1
    }

Cluster

1
cluster.name: es_prod # 用于区分节点属于哪个集群,默认为elasticsearch

Node

1
2
3
node.name: es_001_data # 节点名一般在记录日志时使用,默认随机生成
node.master: true # 是否让这个节点作为默认的master,若不是,默认会选择集群里面的第一个作为master,es有一套选择那个节点作为master的机制
node.data: false #

Paths

1
2
path.data: /var/lib/es1,/var/lib/es2 # 数据会被以条带化(简单地说就是把数据分段,然后把属于不同磁盘的数据并发地写入)的方式写入到两个目录中,但是坏掉一个就肯定会丢失掉一部分数据,所以Elasticsearch会将一个分片的数据仅保存到一个磁盘上,大部分时候一个节点只有一个分片,所以这种条带化并不会带来性能提升,除非为一个节点分配了多个分片
path.logs: /var/log/elasticsearch # 节点日志存放目录

Memory

TODO

Network

1
2
3
network.host: 0.0.0.0 # 配置节点绑定的地址,全0表示可以绑定任何地址,当然这里,本机可以是127.0.0.1回环地址,也可以是ifconfig看到的eth1的地址。
http.port: 9200 # 配置当前节点对外http访问的端口号,默认是9200,不配的话,es会从9200-9299当中找一个未用过的。
transport.tcp.port: 9300 #es集群节点之间的通信端口号。默认9300

Discovery

  1. 最小主节点数
    1
    discovery.zen.minimum_master_nodes: 2 # 告诉 Elasticsearch 当没有足够 master 候选节点的时候,就不要进行 master 节点选举,等 master 候选节点足够了才进行选举。这个值应该=(候选主节点数 / 2) + 1,候选主节点即准备成为主节点的节点,。在设定后,节点必须"看到"集群范围内运作的一定数量的节点才会执行动作
    也可以通过请求动态配置,这对集群的弹性扩展是很有帮助的:
    1
    2
    3
    4
    5
    6
    PUT /_cluster/settings
    {
    "persistent" : {
    "discovery.zen.minimum_master_nodes" : 2
    }
    }
  2. 使用单播代替组播
    Elasticsearch 默认使用单播,组播容易受到错误的组播信号影响,可能是一个节点意外的加入到了你的生产环境。
    使用单播,你可以为 Elasticsearch 提供一些它应该去尝试连接的节点列表。 当一个节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系 master 节点,并加入集群。
    这意味着你的单播列表不需要包含你的集群中的所有节点, 它只是需要足够的节点,当一个新节点联系上其中一个并且说上话就可以了。
    1
    discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]

集群恢复

假设你有 10 个节点,每个节点只保存一个分片,这个分片是一个主分片或者是一个副本分片,或者说有一个有 5 个主分片/1 个副本分片的索引。有时你需要为整个集群做离线维护(比如,为了安装一个新的驱动程序), 当你重启你的集群,恰巧出现了 5 个节点已经启动,还有 5 个还没启动的场景。
假设其它 5 个节点出问题,或者他们根本没有收到立即重启的命令。不管什么原因,你有 5 个节点在线上,这五个节点会相互通信,选出一个 master,从而形成一个集群。 他们注意到数据不再均匀分布,因为有 5 个节点在集群中丢失了,所以他们之间会立即启动分片复制。
最后,你的其它 5 个节点打开加入了集群。这些节点会发现 它们 的数据正在被复制到其他节点,所以他们删除本地数据(因为这份数据要么是多余的,要么是过时的)。 然后整个集群重新进行平衡,因为集群的大小已经从 5 变成了 10。

1
2
3
gateway.recover_after_nodes: 8
gateway.recover_after_time: 5m
gateway.expected_nodes: 10
  • 存在至少 8 个节点(数据节点或者 master 节点)并等待 5 分钟才进行数据恢复。
  • 或者 10 个节点上线后,才进行数据恢复,这取决于和上面那个条件哪个条件先达到。

Various

1
node.max_local_storage_nodes: 2 #默认情况下,是不建议单机启动多个node的,这里这个参数,就是告知es单机上启动了几个实例,这里我们配置2个,若是要配置3个或者更多实例,修改这个数字即可

参考

文档及安装

  1. Elastic Stack and Product Documentation
  2. Install Elasticsearch with Debian Package
  3. Running an Elasticsearch cluster with Docker
  4. Elasticsearch Cluster with Docker Engine Swarm Mode

elasticsearch 中的 field data(正排索引)
官方文档 fielddata

Cluster

  1. Backing Up Your Cluster

Client

  1. Java High Level REST Client
  2. Spring Data Elasticsearch

Kibana

  1. Kibana Guide

logstash

  1. Logstash Reference

数据迁移

  1. Is it worth migrating from MySQL to Elasticsearch?

配置

  1. Configuring Elasticsearch
  2. Important Elasticsearch configuration
  3. Important System Configuration
  4. Production Deployment
  5. Network Settings

应用

  1. elasticsearch项目踩坑记
  2. “搜索”的原理,架构,实现,实践
    介绍了fetch阶段合并结果的几种算法