Elasticsearch集羣搭建及使用Java客戶端對數據存儲和查詢

本次博文發兩塊,前部分是怎樣搭建一個Elastic集羣,後半部分是基於Java對數據進行寫入和聚合統計。html

1、Elastic集羣搭建java

1. 環境準備。node

  該集羣環境基於VMware虛擬機、CentOS 7系統,公司目前用的服務器系統基本全是CentOS系統,所以就選了這個。Elasticsearch須要依賴的最低環境就是JDK8,且要配置好環境變量JAVA_HOME. Elasticsearch的安裝也能夠查看官網給出的安裝說明。git

  虛擬機系統採用的是最小化安裝,沒有安裝桌面程序。安裝完程序再安裝JDK,配置環境變量便可。github

2. 集羣搭建。web

  2.1 安裝包解壓spring

  下載完成後的Elastic包爲elasticsearch-6.3.2.tar.gz,對其解壓。apache

# 將elastic包加壓到目錄 /data/elastic 下
tar zxvf elasticsearch-6.3.2.tar.gz -C /data/elastic

  2.2 配置文件修改json

  解壓後的路徑爲/data/elastic/elasticsearch-6.3.2,在/data/elastic目錄下新增兩個文件夾,爲data,logs,其中data用來存儲節點數據,logs用來存儲日誌,下面在修改配置文件中須要用到。修改config/elasticsearch.yml以下。服務器

# 集羣名稱
cluster.name: elastic_test

# 節點名稱
node.name: node-1

# 數據目錄,剛纔建立的data目錄
path.data: /data/elastic/data

#日誌路徑 ,剛纔建立的logs目錄
path.logs: /data/elastic/logs

#綁定地址,修改成任何機器都能訪問
network.host: 0.0.0.0

#端口,默認9200,不作修改
#http.port: 9200

# 集羣節點,當節點啓動後平臺就會發現
discovery.zen.ping.unicast.hosts: ["172.16.106.190", "172.16.106.191", "172.16.106.192"]

# 最小主節點數量,配置2
# 該配置告訴ELasticsearch當沒有足夠的master候選節點的時候,不進行master節點選舉,等master節點足夠了才進行選舉 discovery.zen.minimum_master_nodes:
2

  2.3 其餘機器修改

  修改完一臺機器後,一樣其餘兩臺機器相似修改,注意把節點名稱改成不同的就能夠了。

  2.4 集羣啓動

    啓動說明:elasticsearch的啓動不能使用root用戶,因此要新建一個普通用戶。如下是具體操做。

# 新建一個用戶組爲elasticgp
groupadd elasticgp

# 新建一個用戶名爲elastic的用戶,而且歸屬到elasticgp用戶組
useradd -g elasticgp elastic

# 給用戶設置密碼
passwd elastic

# 上面已經減了一個文件夾,/data/elastic,該文件夾存儲了elastic軟件和數據目錄data及日誌目錄logs
# 如今將elastic目錄的歸屬組修改爲elastgp
chgrp -R elasticgp elastic/

# 將文件目錄/data/elastic所屬用戶修改成用戶elastic
chown -R elastic elastic/

  用戶配置好後切換到elastic用戶進行啓動程序。

# 切換到elastic用戶
su elastic

# 切換到程序目錄下
cd /data/elastic/elasticsearch-6.3.2

# 後臺啓動程序
./bin/elasticsearch -d

# 查看輸出日誌
tailf ../logs/elastic_test.log

  2.5 問題排查

   啓動的時候可能會出現如下兩個問題

  問題1:將當前用戶的軟硬限制調大

  修改文件 /etc/security/limits.conf

# elastic用戶的軟限制 固然也可用*代替,標識修改全部用戶
elastic soft nofile 65535
# elastic用戶的硬限制 固然也可用*代替,標識修改全部用戶
elastic hard nofile 65537

  問題2:修改/etc/sysctl.conf

vm.max_map_count=262144

  問題3: 啓動內存設置

  在內存不充足的狀況下,能夠修改elastic的初始內存,在/data/elastic/elasticsearch-6.3.2/config目錄下有配置文件

# 將內存使用設置爲512M
-Xms512M
-Xmx512M

  問題4:端口是否開放

  elastic須要用到9200和9300兩個端口,能夠用telnet來查看端口是否開放,如下是修改防火牆打開端口的命令。

  集羣中的節點經過端口 9300 彼此通訊。若是這個端口沒有打開,節點將沒法造成一個集羣。

# 永久開放9200端口
firewall-cmd --permanent --zone=public --add-port=9200/tcp
# 永久開放9300端口
firewall-cmd --permanent --zone=public --add-port=9300/tcp

#從新加載防火牆配置,使開放端口生效
firewall-cmd --reload

  2.6 集羣狀態查看

  以下圖,經過訪問某一個節點,查看全部的節點,其中node-1爲主節點。

  以下圖,查看集羣健康狀態

  以上爲elasticsearch集羣具體安裝過程。具體的API調用說明能夠查看官網CAT_APICluster_APIs等等。

 

2.7 kibana 使用

  集羣搭建好以後,可用經過kibana來訪問集羣的一個節點,而後作一下簡單的測試。先去官網下載kibana安裝包       

  https://www.elastic.co/downloads/kibana

  我是下載的mac客戶端,其餘客戶端應該也是同樣的。

  解壓kibana安裝包後,在bin目錄下執行

# 查看kibana命令幫助
./bin/kibana -h

  會看到以下提示:

Usage: bin/kibana [command=serve] [options]

  Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch.

  Commands:
    serve  [options]  Run the kibana server
    help  <command>   Get the help for a specific command

  "serve" Options:

    -h, --help                 output usage information
    -e, --elasticsearch <uri>  Elasticsearch instance
    -c, --config <path>        Path to the config file, can be changed with the CONFIG_PATH environment variable as well. Use multiple --config args to include multiple config files.
    -p, --port <port>          The port to bind to
    -q, --quiet                Prevent all logging except errors
    -Q, --silent               Prevent all logging
    --verbose                  Turns on verbose logging
    -H, --host <host>          The host to bind to
    -l, --log-file <path>      The file to log to
    --plugin-dir <path>        A path to scan for plugins, this can be specified multiple times to specify multiple directories
    --plugin-path <path>       A path to a plugin which should be included by the server, this can be specified multiple times to specify multiple paths
    --plugins <path>           an alias for --plugin-dir

  其中咱們須要用的就是 -e 參數,來鏈接指定的elasticsearch

# 啓動kibana,鏈接到制定的Elastic服務節點
./bin/kibana -e http://172.16.106.201:9200

  啓動成功後能夠訪問localhost:5601,以下圖,點擊監控菜單看到集羣的一些狀態信息。indices是索引數量,除了本身新建的索引Elasticsearch自己也有一些索引。

  以下圖,點擊DevTools菜單,能夠對集羣節點上的數據進行查詢了。

 

 


 

2、Java客戶端對數據存儲和查詢

 1. 客戶端配置,能夠查看官網詳細配置

採用maven管理,添加依賴的pom配置便可

    <!-- Java High Level REST Client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>6.3.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch</groupId>
                    <artifactId>elasticsearch</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- Client 包缺乏一些東西,所以引入此包
            能夠具體查看ISSUE https://github.com/elastic/elasticsearch/issues/26959
         -->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>6.3.2</version>
        </dependency>

2. 如下是測試主要代碼

package com.woasis.elastic.demo;

import org.apache.http.HttpHost;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@RestController
public class IndexController {


    private static RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(
                    new HttpHost("172.16.106.201",9200, "http"),
                    new HttpHost("172.16.106.202",9200, "http"),
                    new HttpHost("172.16.106.203",9200, "http")
            )
    );

    /**
     * 向索引下增長數據
     * @param indexName
     * @param type
     * @return
     */
    @GetMapping("/putdata")
    public String putDataForIndex(String indexName, String type){

        if (StringUtils.isEmpty(indexName)){
            return "請指定索引名稱";
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        StringBuilder indexBuilder = new StringBuilder();
        indexBuilder.append(indexName);
        indexBuilder.append("-");
        indexBuilder.append(simpleDateFormat.format(new Date()));

        String fullIndexName = indexBuilder.toString();
        System.out.println("索引名稱是:"+fullIndexName);

        Random random = new Random();

        try {
            XContentBuilder contentBuilder = XContentFactory.jsonBuilder();
            contentBuilder.startObject();
            contentBuilder.field("name", "people"+System.currentTimeMillis());
            contentBuilder.field("age", random.nextInt(30));
            contentBuilder.field("createDate", new Date());
            contentBuilder.endObject();

            //索引請求
            IndexRequest indexRequest = new IndexRequest(fullIndexName, type).source(contentBuilder);

            IndexResponse indexResponse = client.index(indexRequest);

            System.out.println(indexResponse.getIndex());

//            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "SUCCESS";
    }


    /**
     * 根據索引名稱,type,id獲取數據
     * @return
     */
    @GetMapping("/getdata")
    public String getData(){

        //Get請求
        GetRequest getRequest = new GetRequest("people-2018-07-31","student", "DfLL72QBGxN1JyvW1KG4");

        try {
            GetResponse response = client.get(getRequest);
            System.out.println("index:"+response.getIndex());
            System.out.println("type:"+response.getType());
            System.out.println("id:"+response.getId());
            System.out.println("sourceString:"+response.getSourceAsString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "SUCCESS";
    }

    /**
     * 搜索數據
     * @return
     */
    @GetMapping("/searchdata")
    public String searchData(){

        //Search請求
        SearchRequest searchRequest = new SearchRequest("people-2018-07-31");

        //查詢過濾條件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("name","people1533031470255"));
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = client.search(searchRequest);

            SearchHits searchHits = searchResponse.getHits();

            for (SearchHit hit : searchHits){
                System.out.println("index:"+hit.getIndex());
                System.out.println("type:"+hit.getType());
                System.out.println("id:"+hit.getId());
                System.out.println("sourceString:"+hit.getSourceAsString());
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "SUCCESS";
    }

}

  官方在各個API使用方式上都有詳細的講解,有用到的能夠在官網查看。跳轉地址

 

  該demo程序使用spring boot搭建,能夠查看Github源碼https://github.com/liuzwei/elastic-demo

相關文章
相關標籤/搜索