Elasticsearch入门实践


官网:https://www.elastic.co/
下载:https://www.elastic.co/downloads/elasticsearch
文档:https://www.elastic.co/guide/index.htmlhtml

一. 系统环境

操做系统:CentOS release 6.8 (Final)
ES版本:6.1.1java

二. 安装

先确认安装了Java运行时环境:node

[es@localhost]$ java -version
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

解压ES压缩包:linux

[es@localhost]$ curl -L -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.1.1.zip
[es@localhost]$ unzip elasticsearch-6.1.1.zip

三. 启动

1. 启动ES单节点

[es@localhost]$ cd elasticsearch-6.1.1
[es@localhost]$ ./bin/elasticsearch      # 在前台启动,能够经过CTRL + C中止
[es@localhost]$ ./bin/elasticsearch -d   # 在后台以守护进程模式运行,经过信号通知关闭: kill -SIGTERM $pid

固然,对于在后台以守护进程模式运行的ES,能够在启动时将进程ID保存到指定文件,在中止时读取进程ID,发送SIGTERM信号给进程进行关闭。git

[es@localhost]$ cd elasticsearch-6.1.1
[es@localhost]$ ./bin/elasticsearch -p /tmp/elasticsearch-pid -d
[es@localhost]$ kill -SIGTERM `cat /tmp/elasticsearch-pid`

实际上,咱们还能够直接将这个启动和中止ES的操做命令写到一个脚本文件中来实现,这样就避免了每次都输入命令。
注意: 在Shell脚本不能直接使用信号SIGRTMIN,须要使用信号编号15代替,如:程序员

#!/bin/bash
pid=`cat /tmp/elasticsearch-pid`
kill -15 $pid

验证是否启动成功:github

[es@localhost]$ curl http://localhost:9200/?pretty
{
  "name" : "4t5PbHS",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "l7iMk0Y2QOWWu5UG-MWlpA",
  "version" : {
    "number" : "6.1.1",
    "build_hash" : "bd92e7f",
    "build_date" : "2017-12-17T20:23:25.338Z",
    "build_snapshot" : false,
    "lucene_version" : "7.1.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

另外,须要注意的是经过上述方式启动的ES只能在本地访问,即:只能经过localhost方式访问。web

[es@localhost]$ netstat -anpt|grep 92
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 192.168.80.133:22           192.168.80.1:52710          ESTABLISHED -                   
tcp        0      0 192.168.80.133:22           192.168.80.1:52730          ESTABLISHED -                   
tcp        0     64 192.168.80.133:22           192.168.80.1:52742          ESTABLISHED -                   
tcp        0      0 ::ffff:127.0.0.1:9200       :::*                        LISTEN      4512/java           
tcp        0      0 ::1:9200                    :::*                        LISTEN      4512/java

一般咱们的ES是须要可以在外部访问的,因此须要修改elasticsearch.yml中的network.host参数为network.host: 0.0.0.0算法

2. 启动ES集群

节点(node)是一个运行着的Elasticsearch实例。集群(cluster)是一组具备相同cluster.name的节点集合,他们协同工做,共享数据并提供故障转移和扩展功能,固然一个节点也能够组成一个集群。必须设置一个合适的名字来替代cluster.name的默认值,这样能够防止一个新启动的节点加入到相同网络中的另外一个同名的集群中。能够经过修改文件elasticsearch.yml中参数cluster.name值,而后重启ES来作到这一点。
ES默认的集群名称为:elasticsearch。spring

四. ES应用实践

1. 如何与ES进行交互

关于与ES的交互方式,总结起来为2种:Java API和RESTful接口。
其中,Java API比较混乱,不一样版本之间没法兼容。下面,咱们对在不一样版本的客户端进行详细说明。

1.1 Java API

(1)[v0.90, v2.2]:在ES2.2及以前的版本中,ES为Java用户提供了两种内置客户端:

  • 节点客户端(Node Client)
    节点客户端以无数据节点身份加入集群,换言之,它本身不存储任何数据,可是它知道数据在集群中的具体位置,而且可以直接转发请求到对应的节点上。

  • 传输客户端(Transport Client)
    这个更轻量的传输客户端可以发送请求到远程集群。它本身不加入集群,只是简单转发请求给集群中的节点。

两种Java客户端都经过9300端口与集群交互,使用ES传输协议(ElasticsearchTransport Protocol)。集群中的节点之间也经过9300端口进行通讯。若是此端口未开放,你的节点将不能组成集群。
具体来讲这两种Java客户端的使用方式不相同:

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.5.1</version>
</dependency>
使用节点客户端:
// Embedded node clients behave just like standalone nodes,
// which means that they will leave the HTTP port open!
Settings settings = Settings.settingsBuilder()
                .put("http.enabled", false)
                .put("path.home","D:\\elasticsearch-2.2.2")
                .build();
Node node = new NodeBuilder()
        .settings(settings )
        .clusterName("elasticsearch")
        .client(true) // should not hold data
        .node();
Client client = node.client();

// 添加文档
Map<String, Object> source = new HashMap<String, Object>();
source.put("first_name", "John");
source.put("last_name", "Smith");
source.put("age", 25);
source.put("about", "I love to go rock climbing");
source.put("interests", Arrays.asList(new String[] {"sports", "music"}));
IndexRequest req = new IndexRequest().index("megacorp").type("employee")
        .id("1")
        .source(source);
client.index(req);

// on shutdown
node.close();

关于节点客户端,须要作几点说明:

  1. 节点客户端将做为一个节点加入ES集群,故须要明确设置属性:"cluster.name": "elasticsearch"。
  2. 一般咱们不须要使用在该节点上存储数据,设置属性"node.client": "true"。
  3. 默认配置下节点客户端将要负责响应外部对于ES集群的请求,即:全部其余客户端对ES集群的操做都须要节点客户端进行响应,若是不但愿承担这样的工做,须要设置属性:"http.enabled": false。

    另外,使用节点客户端还须要注意一个问题:频繁起动和中止一个或多个节点客户端会致使没必要要的ES集群抖动。
使用传输客户端:
Settings settings = Settings.settingsBuilder()
        .put("cluster.name", "elasticsearch")
        .put("client.transport.sniff", true)
        .build();
Client client = TransportClient.builder().settings(settings).build()
        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300));
        //.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("test.com"), 9300));

// 添加文档
Map<String, Object> source = new HashMap<String, Object>();
source.put("first_name", "Jane");
source.put("last_name", "Smith");
source.put("age", 32);
source.put("about", "I like to collect rock albums");
source.put("interests", Arrays.asList(new String[] {"music"}));
IndexRequest req = new IndexRequest().index("megacorp").type("employee")
        .id("2")
        .source(source);
client.index(req);

// on shutdown
client.close();

很显然,传输客户端实际上是使用轮训算法与ES集群中的全部节点创建链接,从而达到负载均衡的效果。

(2)[v2.3, v2.4]:在ES2.3和2.4版本中,ES提供的Java客户端被分别叫作:

  • Transport Client
  • Client Node

这里的Transport Client与以前的传输客户端是同一个东西。相比起ES2.2及以前的版本,在ES2.3和ES2.4版本中引入了一个专门用于路由请求的客户端节点Client Node,暂且称之为“路由客户端节点”。这个“路由客户端节点”与以前的节点客户端相似,须要加入ES集群,可是其不能参与Master选举,也不能保存数据,本质上来说它就是一个轻量级的“节点客户端”。可是它不能独立为客户端服务,而是经过Transport Client链接到Client Node
Client Node的使用模式:

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.5.1</version>
</dependency>
/**
 * 启动路由客户端节点
 */
public static void startClientNode() {
    Settings settings = Settings.settingsBuilder()
            .put("node.master", false)
            .put("node.data", false)
            .put("path.home","D:\\elasticsearch-2.4.1")
            .build();
    Node node = new NodeBuilder()
            .settings(settings )
            .clusterName("elasticsearch")
            .node();
    node.start();
    System.out.println("Client Node Started");
}

/**
 * 传输客户端与客户端节点通讯
 * @throws UnknownHostException
 */
public static void transportClient() throws UnknownHostException {
    System.out.println("Do transport client");
    // 传输客户端直接与"路由客户端节点"通讯
    Client client = TransportClient.builder().build()
            .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9301));

    // 添加文档
    Map<String, Object> source = new HashMap<String, Object>();
    source.put("first_name", "John");
    source.put("last_name", "Smith");
    source.put("age", 25);
    source.put("about", "I love to go rock climbing");
    source.put("interests", Arrays.asList(new String[] {"sports","music"}));
    IndexRequest req = new IndexRequest().index("megacorp").type("employee")
            .id("1")
            .source(source);
    client.index(req);

    // on shutdown
    client.close();
}

(3)[v5.0,v6.1]:从ES5.0版本开始,到如今的6.1版本,ES提供的Java客户端被统一为以下2种:

  • Transport Client
  • Coordinating Only Node

从ES5.0版本开始,引入了一个新的协调节点:Coordinating Only Node,专门用于路由请求,分发批量索引操做。与Client Node相似,该协调节点不能参与master选举,也不能保存数据。

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>6.1.1</version>
</dependency>
/**
 * 从5.0版本开始,传输客户端的使用方式与以前不一样(不一样版本的ES Java API使用方式可能不一样)
 * @throws UnknownHostException
 */
public static void transportClient() throws UnknownHostException {
    System.out.println("Do transport client");
    TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
            .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));

    // 添加文档
    Map<String, Object> source = new HashMap<String, Object>();
    source.put("first_name", "John");
    source.put("last_name", "Smith");
    source.put("age", 25);
    source.put("about", "I love to go rock climbing");
    source.put("interests", Arrays.asList(new String[] {"sports","music"}));
    IndexRequest req = new IndexRequest().index("megacorp").type("employee")
            .id("1")
            .source(source);
    client.index(req);
    
    // on shutdown
    client.close();
}

总结起来,关于ES提供的Java API,到目前(v6.1.1)为止一共提供了4种客户端:Transport ClientNode ClientClient NodeCoordinating Only Node,他们分别对应在不一样的版本中使用。其中,Transport ClientNode Client均可以独立使用,而Client NodeCoordinating Only Node都不能独立提供查询服务,他们做为一个功能节点加入ES集群,而后经过Transport Client进行链接。

注意:

  • 如上所说的Java API版本必须与集群中ES节点版本一致,不然,它们可能互相没法识别。
  • 根据ES官方的计划,TransportClient客户端将在7.0版本被标记为废弃,在8.0版本将完全被移除,官方建议使用Java High Level REST Client。

另外,从ES5.0版本开始,还提供了一个Java REST Client,这个客户端能够兼容全部的ES版本。而且,从ES5.6版本开始,这个Java REST Client又细分为两个版本:Java Low Level REST ClientJava High Level REST Client
其中,Java Low Level REST Client能兼容全部ES版本;而Java High Level REST Client只能兼容主版本号与之相同的ES版本,而且ES的小版本号必须大于等于Java High Level REST Client的对应小版本号。举个例子,6.0版本的Java High Level REST Client能够兼容全部6.x版本的ES,可是6.1版本的Java High Level REST Client可能没法兼容6.0版本的ES,由于ES的小版本号(0)小于Java High Level REST Client的小版本号(1)。关于更多Java REST Client信息,详见:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/5.0/index.html。

Java API虽然对Java程序员提供了必定的便利性,可是并不友好,对于非Java栈的应用来讲就不能使用Java API。与之相对应的,RESTful风格的API就不能再这个限制,并且更加灵活,自由度更大。固然,ES官方提供了多种程序语言的客户端,如:Groovy,JavaScript,.NET,PHP,Perl,Python以及Ruby。关于Java API的更多信息详见:https://www.elastic.co/guide/en/elasticsearch/client/index.html

1.2 RESTful API

基于HTTP协议,以JSON为数据交互格式的RESTful API。
其余全部程序语言均可以使用RESTful API,经过9200端口的与ES进行通讯,可使用任何你喜欢的WEB客户端。事实上,如你所见,你甚至能够经过curl命令与ES通讯。

1.3 其余交互方式

上面谈到的ES交互方式都是ES官方提供的API或接口,基于这些API或接口还存在一些第三方组件,对于在应用开发或调试过程当中很是有用。
(1)spring-data-elasticsearch
该组件是Spring官方提供的一个与ES交互的组件库,便于在基于Spring框架的应用程序中操做ES。
详见:https://github.com/spring-projects/spring-data-elasticsearch

(2)ElasticSearch Query Builder
这是一个Chrome插件,在进行简单的调试查询时使用该插件很是便利和高效。
https://chrome.google.com/webstore/detail/elasticsearch-query-build/cioobgbmiehdijndbmjkbjlkdeijdibp?utm_source=chrome-ntp-icon

(3)ElasticSearch Head
Chrome插件,用于编写DSL查询,对于学习DSL查询很是有帮助。
https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm

2. ES操做实践

2.1 添加文档

以下示例均已RESTful接口说明。
语法:PUT http://host:port/index/type/id,文档内容使用json格式做为http请求body。

curl -i -XPUT http://localhost:9200/megacorp/employee/1 -d '
{
    "first_name": "John",
    "last_name": "Smith",
    "age": 25,
    "about": "I love to go rock climbing",
    "interests": [
        "sports",
        "music"
    ]
}
'

2.2 搜索文档

2.2.1 简单搜索
  • 语法1:GET http://host:port/index/type/id,查询指定id的文档
curl -i -XGET http://localhost:9200/megacorp/employee/1

返回:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 205

{
  "_index": "megacorp",
  "_type": "employee",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "about": "I love to go rock climbing",
    "last_name": "Smith",
    "interests": [
      "sports",
      "music"
    ],
    "first_name": "John",
    "age": 25
  }
}
  • 语法2:GET http://host:port/index/type/_search,查询所有文档
curl -i -XGET http://localhost:9200/megacorp/employee/_search

返回:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 501

{
  "took": 16,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "2",
        "_score": 1,
        "_source": {
          "about": "I like to collect rock albums",
          "last_name": "Smith",
          "interests": [
            "music"
          ],
          "first_name": "Jane",
          "age": 32
        }
      }
    ]
  }
}
2.2.2 查询字符串搜索

语法:http://host:port/index/type/_search?q=querystring

示例:查询姓氏为Smith的员工

curl -i -XGET http://localhost:9200/megacorp/employee/_search?q=last_name:Smith

返回:

HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Content-Length: 522

{
  "took": 9,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.30685282,
    "hits": [
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "2",
        "_score": 0.30685282,
        "_source": {
          "about": "I like to collect rock albums",
          "last_name": "Smith",
          "interests": [
            "music"
          ],
          "first_name": "Jane",
          "age": 32
        }
      }
    ]
  }
}
2.2.3 使用DSL语句查询

查询字符串搜索便于经过命令行完成特定(ad hoc)的搜索,可是它也有局限性。Elasticsearch提供丰富且灵活的查询语言叫作DSL查询(Query DSL),它容许你构建更加复杂、强大的查询。DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。咱们能够这样表示以前关于“Smith”的查询:

curl -i -H 'Content-Type: application/json' -XPOST http://localhost:9200/megacorp/employee/_search -d '
{
    "query": {
        "match": {
            "last_name": "Smith"
        }
    }
}
'

这会返回与以前查询相同的结果。你能够看到有些东西改变了,咱们再也不使用查询字符串作为参数,而是使用请求体代替。这个请求体使用JSON表示,其中使用了match语句。
显然,在DSL查询中,须要传递消息体,因此只能使用POST方法。

五. 启动报错&解决方案

Q1. can not run elasticsearch as root

[root@localhost ~]# ./bin/elasticsearch
[2017-12-22T19:08:28,283][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:125) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:112) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:85) ~[elasticsearch-6.1.1.jar:6.1.1]
Caused by: java.lang.RuntimeException: can not run elasticsearch as root
    at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:104) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:171) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:322) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:121) ~[elasticsearch-6.1.1.jar:6.1.1]
    ... 6 more

缘由: ES不能使用root用户启动
解决: 使用非ROOT用户登陆并启动ES便可

Q2: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed

[es@localhost]$ ./bin/elasticsearch
[2017-12-22T19:20:25,868][WARN ][o.e.b.JNANatives         ] unable to install syscall filter: 
java.lang.UnsupportedOperationException: seccomp unavailable: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed
    at org.elasticsearch.bootstrap.SystemCallFilter.linuxImpl(SystemCallFilter.java:341) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.SystemCallFilter.init(SystemCallFilter.java:616) ~[elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.JNANatives.tryInstallSystemCallFilter(JNANatives.java:258) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Natives.tryInstallSystemCallFilter(Natives.java:113) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:109) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:171) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:322) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:121) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:112) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) [elasticsearch-cli-6.1.1.jar:6.1.1]
    at org.elasticsearch.cli.Command.main(Command.java:90) [elasticsearch-cli-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) [elasticsearch-6.1.1.jar:6.1.1]
    at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:85) [elasticsearch-6.1.1.jar:6.1.1]

当咱们使用非root用户启动ES时,在启动日志中看到一段异常日志:CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed

缘由: seccomp是linux kernel从2.6.23版本开始所支持的一种安全机制,详见:https://en.wikipedia.org/wiki/Seccomp
而个人主机操做系统是:CentOS release 6.8 (Final)

[root@localhost ~]# cat /etc/redhat-release 
CentOS release 6.8 (Final)
[root@localhost ~]# uname -a
Linux centosx64_tomcat1 2.6.32-642.el6.x86_64 #1 SMP Tue May 10 17:27:01 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

虽然我使用的CentOS 6.8 Final使用的内核版本为2.6.32-642,可是彷佛没有支持seccomp。然而ES默认将利用内核的seccomp机制,因此报错,详见:https://github.com/elastic/elasticsearch/issues/22899

解决: ES是经过配置参数bootstrap.system_call_filter: true使用内核seccomp机制的,在开发环境下能够将该参数值设为false。

[es@localhost]$ vim config/elasticsearch.yml
bootstrap.system_call_filter: false # 默认该参数值不在elasticsearch.yml配置文件中,添加并设置为false便可。

Q3:bootstrap checks failed
当修改了参数network.host: 0.0.0.0以后再启动ES时将会报错:

[es@localhost]$ ./bin/elasticsearch
[2017-12-22T23:16:23,511][INFO ][o.e.n.Node               ] initialized
[2017-12-22T23:16:23,515][INFO ][o.e.n.Node               ] [4t5PbHS] starting ...
[2017-12-22T23:16:24,421][INFO ][o.e.t.TransportService   ] [4t5PbHS] publish_address {192.168.80.133:9300}, bound_addresses {[::]:9300}
[2017-12-22T23:16:24,494][INFO ][o.e.b.BootstrapChecks    ] [4t5PbHS] bound or publishing to a non-loopback or non-link-local address, enforcing bootstrap checks
[2017-12-22T23:16:24,509][ERROR][o.e.b.Bootstrap          ] [4t5PbHS] node validation exception
[3] bootstrap checks failed
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
[2]: max number of threads [1024] for user [es] is too low, increase to at least [4096]
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[2017-12-22T23:16:24,524][INFO ][o.e.n.Node               ] [4t5PbHS] stopping ...
[2017-12-22T23:16:24,620][INFO ][o.e.n.Node               ] [4t5PbHS] stopped
[2017-12-22T23:16:24,620][INFO ][o.e.n.Node               ] [4t5PbHS] closing ...
[2017-12-22T23:16:24,672][INFO ][o.e.n.Node               ] [4t5PbHS] closed

缘由: 在启动日志中给出了很是清楚的提示:

[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
[2]: max number of threads [1024] for user [es] is too low, increase to at least [4096]
[3]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

详见:https://serverfault.com/questions/681745/unable-to-change-vm-max-map-count-for-elasticsearch

解决: 以root用户身份登陆
1.修改最大文件描述符数

# 先查看一下当前的最大文件描述符数
[root@localhost]# ulimit -n
1024

# 修改最大文件描述符数
[root@localhost]# vim /etc/security/limits.conf
# 添加以下2行配置
es               hard    nofile          65536
es               soft    nofile          65536

2.修改最大线程数:非root用户容许的最大线程数默认为1024

[root@localhost]# vim /etc/security/limits.conf
# 添加如2行配置
es               hard    nproc           4096
es               soft    nproc           4096

上述2项修改完毕以后须要重启系统。

3.修改vm.max_map_count:在虚拟机上运行ES时才须要修改这个值

# 先查看当前值
[root@localhost]# cat /proc/sys/vm/max_map_count
65530

# 修改
[root@localhost]# echo 262144 > /proc/sys/vm/max_map_count

该参数在修改以后重启系统后又恢复为默认值了,每次都须要从新设置。

总结

  1. ES基于Luence,可是使用上比Luence更加简单,存储文档对象。
  2. ES天生就是分布式的,易于扩展,具有良好的容错性,很是适合用于存储并检索海量数据的场景,如构建日志分析系统。

【参考】 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html Elasticsearch: 权威指南 https://www.gitbook.com/book/looly/elasticsearch-the-definitive-guide-cn/details es gitbook https://www.gitbook.com/book/fuxiaopang/learnelasticsearch/details Elasticsearch 权威指南 http://itindex.net/detail/54168-elasticsearch-%E4%BC%98%E5%8C%96 亿级规模的Elasticsearch优化实战 https://www.elastic.co/guide/index.html Elastic Stack and Product Documentation

相关文章
相关标签/搜索