Elastic Search

一 Elastic Search

1 介绍

参考资料

2 安装

2.1 第一步安装

##1. 解压
[root@qphone01 software]# tar -zxvf elasticsearch-6.5.3.tar.gz -C /opt/apps/

##2. 配置环境变量
[root@qphone01 elasticsearch-6.5.3]# vi /etc/profile
#envrioment
export JAVA_HOME=/opt/apps/jdk1.8.0_45
export HADOOP_HOME=/opt/apps/hadoop-2.6.0-cdh5.7.6
export SCALA_HOME=/opt/apps/scala-2.11.8
export SPARK_HOME=/opt/apps/spark-2.2.0
export HIVE_HOME=/opt/apps/hive-1.1.0-cdh5.7.6
export ZOOKEEPER_HOME=/opt/apps/zookeeper-3.4.5-cdh5.7.6
export KAFKA_HOME=/opt/apps/kafka-2.11
export FLUME_HOME=/opt/apps/flume-1.9.0
export REDIS_HOME=/opt/apps/redis-3.2.8
export REDIS_CONF=$REDIS_HOME/conf
export ELASTICSEARCH_HOME=/opt/apps/elasticsearch-6.5.3
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$SCALA_HOME/bin:$HIVE_HOME/bin:$REDIS_HOME/bin
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin:$ZOOKEEPER_HOME/bin:$KAFKA_HOME/bin:$FLUME_HOME/bin:$ELASTICSEARCH_HOME/bin

##3. 配置es的elasticsearch.yml

cluster.name: es-hzbigdata2002
node.name: qphone01
node.master: true
node.data: true
path.data: /opt/apps/elasticsearch-6.5.3/data
path.logs: /opt/apps/elasticsearch-6.5.3/logs
network.host: 0.0.0.0
discovery.zen.ping.unicast.hosts: ["qphone01", "qphone02", "qphone03"]

##4. 建立一个普通用户

[root@qphone01 config]# useradd qphone01
[root@qphone01 config]# passwd qphone01
更改用户 qphone01 的密码 。

##5. 授权
[root@qphone01 config]# vi /etc/sudoers

## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL
qphone01 ALL=(ALL)       ALL

##6. 对整个目录授权
[root@qphone01 apps]# chown -R qphone01:qphone01 elasticsearch-6.5.3/

2.2 第二步解决环境问题

[qphone01@qphone01 bin]$ sudo vi /etc/security/limits.conf
*       soft    nofile  65536
*       hard    nofile  131072
*       soft    nproc   2048
*       hard    nproc   4096

[qphone01@qphone01 bin]$ sudo vi /etc/security/limits.d/20-nproc.conf

*          soft    nproc     4096
root       soft    nproc     unlimited

[bigdata@qphone01 limits.d]$ sudo vi /etc/sysctl.conf

vm.max_map_count=262144
tip:
修改完之后重启

2.3 测试

http://192.168.49.111:9200/

{
  "name" : "qphone01",
  "cluster_name" : "es-hzbigdata2002",
  "cluster_uuid" : "iUEJ5-BRRsieI0vd7Uooww",
  "version" : {
    "number" : "6.5.3",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "159a78a",
    "build_date" : "2018-12-06T20:11:28.826501Z",
    "build_snapshot" : false,
    "lucene_version" : "7.5.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

2.4 安装head插件-谷歌浏览器

2.4.1 下载谷歌浏览器

2.4.2 安装head插件

3 使用

3.1 RESTFul简介

看资料

3.2 curl

3.2.1 在es当中的增删改查的method type

资源 一组资源的URI,比如:http://example.com/res/ 单个资源的URI,比如:http://example.com/res/123
GET 列出URI,以及该资源组中每个资源的详细信息(后者可选) 获取指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等)
PUT 使用给定的一组资源替换当前整组资源 替换/创建指定的资源。并将其追加到相应的资源组中。
POST 在本组资源中创建/追加一个新的资源。该操作往往返回新的URL 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。
DELETE 删除整组资源 删除指定的元素

3.2.2 curl

  • 特殊指令
URL 描述
/index/_search 搜索指定索引下的数据
/_aliases 获取或操作索引的别名
/index/ 查看指定索引的详细信息
/index/type/ 创建或操作类型
/index/_mapping 创建或操作mapping
/index/_setting 创建或操作设置(比如number_of_shards分片数)
/index/_open 打开指定被关闭的索引
/index/_close 关闭指定索引
/index/_refresh 刷新索引(使新加内容对搜索可见,不保证数据被写入磁盘)
/index/flush 刷新索引(会触发Lucene提交)
  • 基本用法:3大参数
-X 指定http的请求方式:head、put、get、post、delete
-D 要传输的数据
-H 指定请求头信息
  • 入门例子:创建了一个索引库
curl -XPUT 'http://hbase1:9200/bigdata' ## 向es的集群发送put请求(新建),bigdata的索引库

3.3 操作es的crud

3.3.1 put

 curl -H "Content-Type:application/json" -XPUT 'http://qphone01:9200/bigdata/emp/1' -d '{"name":"lixi", "age":34}'
{"_index":"bigdata","_type":"emp","_id":"1","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":0,"_primary_term":1}

curl -H "Content-Type:application/json" -XPUT 'http://qphone01:9200/bigdata/emp/3' -d '{"name":"苍老师", "age":40}'
{"_index":"bigdata","_type":"emp","_id":"3","_version":2,"result":"updated","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1}

tip:
1. 一个索引库中只能由一个type,index/type视为一张表
2. 1表示doc_id,表示的一个文档的编号,在es中一条数据表示一个文档
3. 一个index/type可以由多个doc
4. 一个doc中的数据一定是一个json,并且多个doc之间的json是非对称的

"_index":"bigdata" : 索引库的库名
"_type":"emp" : 类型是emp,你可以理解为bigdata库下有一个表,这个表叫做emp
"_id":"1" : 表示doc的编号
"_shards":{"total":2,"successful":1,"failed":0} : 分片,有个副本

默认的分片是5,默认的副本因子是1
状态 描述
绿色 所有主分片和副本分片都可用
黄色 所有的主分片都可用,不是所有的副本分片可用
红色 不是所有主分片和副本分片可用

3.3.2 post操作,创建/修改索引库

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/bigdata/emp/1' -d '{"name":"程志远", "age":18}'
{"_index":"bigdata","_type":"emp","_id":"1","_version":2,"result":"updated","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1}

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/bigdata/emp/4' -d '{"name":"李洪良", "age":22}'
{"_index":"bigdata","_type":"emp","_id":"4","_version":1,"result":"created","_shards":{"total":2,"successful":2,"failed":0},"_seq_no":1,"_primary_term":1}

tip:
put和post都是既可以添加数据又可以修改数据。但是post还能修改其他的设置

3.3.3 Get

##1. 查询指定的一个文档
curl -H "Content-Type:application/json" -XGET 'http://qphone01:9200/bigdata/emp/1'
{"_index":"bigdata","_type":"emp","_id":"1","_version":2,"found":true,"_source":{"name":"程志远", "age":18}}

##2. 查询并优化查询的json的格式
curl -H "Content-Type:application/json" -XGET 'http://qphone01:9200/bigdata/emp/1?pretty'
{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "1",
  "_version" : 2,
  "found" : true,
  "_source" : {
    "name" : "程志远",
    "age" : 18
  }
}


##3. 查询所有
curl -H "Content-Type:application/json" -XGET 'http://qphone01:9200/bigdata/_search?pretty'
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 4,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "rock",
          "age" : 35
        }
      },
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "李洪良",
          "age" : 22
        }
      },
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "程志远",
          "age" : 18
        }
      },
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "苍老师",
          "age" : 40
        }
      }
    ]
  }
}

##4. 条件查询
curl -XGET 'http://qphone01:9200/bigdata/_search?q=name:rock&pretty'
{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.87138504,
    "hits" : [
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "2",
        "_score" : 0.87138504,
        "_source" : {
          "name" : "rock",
          "age" : 35
        }
      }
    ]
  }
}

##5. 条件查询
curl -XGET 'http://qphone01:9200/bigdata/_search?q=name:rock&_source=name&pretty'
{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.87138504,
    "hits" : [
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "2",
        "_score" : 0.87138504,
        "_source" : {
          "name" : "rock"
        }
      }
    ]
  }
}

##6. 分页显示
curl -XGET 'http://qphone01:9200/bigdata/_search?from=0&size=2&pretty'
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 4,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "rock",
          "age" : 35
        }
      },
      {
        "_index" : "bigdata",
        "_type" : "emp",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "李洪良",
          "age" : 22
        }
      }
    ]
  }
}

3.3.4 Post:局部修改

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/bigdata/emp/4/_update?pretty' -d '{"doc": {"name":"lixi"}}'

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 2,
  "_primary_term" : 1
}

3.3.5 Delete

##1. 删除docid(索引)
curl -H "Content-Type:application/json" -XDELETE 'http://qphone01:9200/bigdata/emp/3?pretty'
##2. 索引库
curl -H "Content-Type:application/json" -XDELETE 'http://qphone01:9200/bigdata?pretty'

3.3.6 batch

  • 批量插入
curl -H 'Content-Type:application/json' -i -XPUT 'http://qphone01:9200/qphone/student/_bulk?pretty' \
-d '
{"index":{"_id":"3"}}
{"name":"李洪浪", "sex":"男", "age":32}
{"index":{"_id":"4"}}
{"name":"李洪风", "sex":"男", "age":45}
{"index":{"_id":"5"}}
{"name":"李洪云", "sex":"男", "age":67}
{"index":{"_id":"6"}}
{"name":"李洪雨", "sex":"男", "age":8}
{"index":{"_id":"7"}}
{"name":"李洪雷", "sex":"男", "age":56}
{"index":{"_id":"8"}}
{"name":"李洪火", "sex":"男", "age":15}
'

4 ES的插件管理之Kibana

4.1 安装

##1. 解压
[root@qphone01 software]# tar -zxvf kibana-6.5.3-linux-x86_64.tar.gz -C /opt/apps/
##2. 环境变量
export KIBANA_HOME=/opt/apps/kibana-6.5.3
export PATH=$PATH:$KIBANA_HOME/bin
##3. kibana.yml

server.port: 5601
server.host: "192.168.49.111"
server.name: "qphone01"
elasticsearch.url: "http://qphone01:9200"

##4. 启动
nohup kibana serve > /dev/null 2>&1 &

4.2 测试结果

001.png

二 ES的概念

1 通用概念

1.1 Index库和Index

    索引(index)是ElasticSearch中的对逻辑数据的逻辑存储。所以它可以分为更小的部分,你可以直接把它理解为RDBMS中的Table的数据的主键
    索引库可以理解为RDBMS中的DATABASE。ES可以把索引存放在一个机器或者分散到多台服务器,每个索引有一个或者多个分片(shard),每个分片有多个副本。

1.2 Document: 文档

    存储在ElasticSearch中的主要实体叫做文档(document)。用RDBMS来对比的话,一个文档相当于数据库表中的一行记录。
    一个doc是一个可被索引的基本信息单元。这些文档都是以json格式来表示的。在index/type里面存储的。

1.2.1 创建文档

    文档通过index API被索引——使数据可以被存储和搜索。但是首先要先决定文档所在,如何确定:通过index\type\id来唯一确定。
语法:
    PUT {index}/{type}/{id} -d '{"":""}'
    POST {index}/{type} -d '{"":""}' 自定id
e.g.

[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -XPUT 'http://hbase1:9200/bigdata/emp/4' -d '{"name":"wyl", "age":18}'

1.2.2 获取文档

1. 普通查询
通过index\type\id,但是请求方式改为GET来获取文档
e.g.
curl -H 'Content-Type:application/json' -XGET 'http://hbase1:9200/bigdata/emp/4?pretty'
{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "name" : "wyl",
    "age" : 18
  }
}

tip:
pretty : 在任意的查询字符串中添加pretty参数,都会然让es美化输出,让json在响应的时候更容易阅读。
_source : 字段不会被美化,它的样子于输入的时候一致,这个source存放的就是文档的数据
"found" : true : 表示你的文旦给已经被查找到了。如果我们请求一个不存在的文旦给,依旧会得到一个json,found为false


2. 带响应码的查询
curl -H 'Content-Type:application/json' -i -XGET 'http://hbase1:9200/bigdata/emp/4?pretty'

[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XGET 'http://hbase1:9200/bigdata/emp/4?pretty'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 153

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "name" : "wyl",
    "age" : 18
  }
}

3. 检索文档一部分
[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XGET 'http://hbase1:9200/bigdata/emp/4?_source=name&pretty'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 137

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "name" : "wyl"
  }
}

1.2.3 更新文档

//1. 是以覆盖的方式修改数据,版本叠加1
[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XPOST 'http://hbase1:9200/bigdata/emp/4?pretty' \
> -d '{"name":"yl", "age":27}'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 220

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 5,
  "_primary_term" : 2
}

//2. 局部更新
[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XPOST 'http://hbase1:9200/bigdata/emp/4/_update?pretty' \
> -d '{"doc":{"name":"wyl"}}'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 220

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 6,
  "_primary_term" : 2
}

1.2.4 删除文档

[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XDELETE 'http://hbase1:9200/bigdata/emp/4?pretty'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 220

{
  "_index" : "bigdata",
  "_type" : "emp",
  "_id" : "4",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 7,
  "_primary_term" : 2
}

1.2.5 批量插入

[root@hbase1 kibana-6.5.3]# curl -H 'Content-Type:application/json' -i -XPOST 'http://hbase1:9200/blog/emp/_bulk?pretty' \
> -d '
> {"index":{"_id":"1"}}
> {"name":"James", "sex":"man", "salary":50000000}
> {"index":{"_id":"2"}}
> {"name":"Kobe", "sex":"man", "salary":60000000}
> '

1.2.6 检索多个文档

curl -H 'Content-Type:application/json' -i -XGET 'http://qphone01:9200/_mget?pretty' \
-d '{
"docs":[
{
"_index":"qphone",
"_type":"student",
"_id":1,
"_source":"name"
},
{
"_index":"qphone",
"_type":"student",
"_id":2
}
]
}'
HTTP/1.1 200 OK
content-type: application/json; charset=UTF-8
content-length: 437

{
  "docs" : [
    {
      "_index" : "qphone",
      "_type" : "student",
      "_id" : "1",
      "_version" : 1,
      "found" : true,
      "_source" : {
        "name" : "程志远"
      }
    },
    {
      "_index" : "qphone",
      "_type" : "student",
      "_id" : "2",
      "_version" : 1,
      "found" : true,
      "_source" : {
        "name" : "李洪良",
        "sex" : "男",
        "age" : 19
      }
    }
  ]
}

1.3 Type

文档类型
    在es中,一个索引对象可以存储很多不同用途的对象。例如,一个博客可以保存文章和评论。文档类型让我们可以轻易的区分单个索引中的不同的对象。每个文档可以有不同的结构,但是在实际部署中,对文档按类型区分对于操作有很大的帮助。但有一个限制,不同的文档类型不能为相同的属性设置不同的类型。例如,在同一个索引中的所有的文档类型中,一个叫title的字段必须具有相同的类型。
    在es6之后,一个index只能有一个type
    
curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog/article/1' -d '{"title":"lijieweishenmzhemshuai", "content":"yinweitabenlaijiuhenshuai"}'

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog/comment/1' -d '{"title":"lijieweishenmzhemshuai", "content":"yinweitayongpiaorou", "user":"wangyushan"}'

{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"Rejecting mapping update to [blog] as the final mapping would have more than 1 type: [comment, article]"}],"type":"illegal_argument_exception","reason":"Rejecting mapping update to [blog] as the final mapping would have more than 1 type: [comment, article]"},"status":400}[root@hbase1 elasticsearch-6.5.3]#

1.4 Field(数据类型)

1.4.1 基本数据类型

字符串:text、keyword
数值:long、integer、short、byte、double、float、half_float、scaled_float
日期:date
布尔类型:boolean
二进制类型:binary
范围类型:integer_range、float_range、long_range、double_range、date_range

1.4.2 复杂的数据类型

数组:array
对象:object
嵌套类型:nested object

1.4.3 地理位置数据类型

geo_point(点)、geo_shape(形状)

1.4.4 专用类型

记录ip:ip
自动补全:completion
记录分词:token_count

1.4.5 通过mapping映射手动指定你插入的字段类型

##1. 执行命令,发现以下的信息
curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog/article/2' -d '{"title":"qphoneshizuihaodepeixunjigou", "content":"bigdatashizuihaodexuek", "author":"lixi", "dt":"2020-09-04"}'

##2. 查询如下索引信息
002.png

003.png
他自动的将json中的字段转换唯es中的对应的字段类型,这个转换是自动完成的

##3. 手动指定类型
curl -XPUT -H "Content-Type:application/json" 'http://qphone01:9200/spark?pretty' -d \
'{
"mappings":{
"sparkcore":{
"properties":{
"scala":{
"type":"double"
}
}
}
}
}'


tip:
##1) 手动的指定我们的field的类型是可以的,但是必须得是新建的索引库
##2) 必须通过mappings的映射的去指定
##3) 可以自动映射的
##4)  我们的自定义字段只是一个申请,我们可以选择用或不用,但是在实际生产中,定义好的字段就是一种规范,一般在没有得批准的前提是不允许随意的添加字段的。

##4. 以下代码我们发现这个日期不是date,是text。因为我们没有指定识别日期的格式
curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog/article/5' -d '{"title":"qphoneshizuihaodepeixunjigou", "content":"bigdatashizuihaodexuek", "author":"rock", "dt2":"20200904"}'

##5. 添加日期识别格式
curl -XPUT -H "Content-Type:application/json" 'http://qphone01:9200/blog2?pretty' -d \
'{
"mappings":{
"article":{
"dynamic_date_formats":["yyyyMMdd"]
}
}}'

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog2/article/1?pretty' -d '{"title":"qphoneshizuihaodepeixunjigou", "content":"bigdatashizuihaodexuek", "author":"rock", "dt":"20200904"}'

##6. 关闭自动识别日期
curl -XPUT -H "Content-Type:application/json" 'http://qphone01:9200/blog2?pretty' -d \
'{"mappings":{
"article":{
"date_detection":false
}
}}'


##7. 开启将字符串全是数字的情况识别为long类型
curl -XPUT -H "Content-Type:application/json" 'http://qphone01:9200/blog3?pretty' -d \
'{
"mappings":{
"article":{
"numeric_detection":true
}
}}'

curl -H "Content-Type:application/json" -XPOST 'http://qphone01:9200/blog3/article/1?pretty' -d '{"title":"qphoneshizuihaodepeixunjigou", "content":"bigdatashizuihaodexuek", "author":"rock", "dt":"20200904", "num":"111"}'

1.5 核心概念

1.5.1 Cluster :集群

    表示es的集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点都是对于集群内部来说的。因为ES本身其实有一个概念:去中心化。字面理解上是表示es集群是没有主节点,但是这个没有主节点是对外部来说的。也就是我们可以认为es在逻辑上是一个整体,你与任何一个节点通信都与整个es集群通信时等价的。
    主节点的职责时负责管理整个集群的状态,包括管理分片的状态和副本的状态。新节点的发现,节点的删除。
    只要在同一个网段之内启动多个es节点,就可以自动组成一个集群(es2.0之前可以自动发现,es2.0之后就不可以了)
    如何查看集群的状态:
[root@hbase1 config]# curl -XGET -H "Content-Type:application/json" 'http://hbase1:9200/_cluster/health?pretty'
{
  "cluster_name" : "bigdata-etc",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 3,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 6,
  "active_shards" : 12,
  "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" : 100.0

1.5.2 分片

    可以在创建索引库的时候指定分片,相当于rdd或者kafka中的partition的概念。
如:
curl -XPUT 'ip:port/index' -d {"settings":{"number_of_shards":3}}
    默认每个索引库都是5个分片
    需要注意的是,索引库一旦被创建,分片的个数是不能修改的。

1.5.3 副本

    代表索引库的副本。副本的作用是提供系统的容错性,当某节点挂点可以从副本中恢复数据。
如:
curl -XPUT 'ip:port/index' -d {"settings":{"number_of_replicas":3}}

1.5.4 数据重分布

    代表数据恢复或者叫做数据重新分布。es在有节点加入或者退出的时候会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动的时候也会进行数据恢复。

1.5.5 数据持久化

    代表的是es的持久化存储方式,es默认是先把索引存放到内存中,当内存满了的时候再存储到硬盘。当这个es集群再关闭的时候、重启的时候就会从gateway中读取索引数据
    es本身支持多种类型的gateway,由本地的文件系统(默认),分布式文件系统:HDFS、amazon。。。

1.5.6 自动发现机制

    代表es的自动发现节点的机制。es是一个基于p2p的系统,他先通过广播寻找存在的节点,再通过多广播协议来进行节点与节点之间的通信,同时支持点对点的交互。
    禁用自动发现机制:
    discovery.zen.ping.multicast.enabled : true/false
    设置新节点被启动时能够发现的列表
    discovery.zen.ping.unicast.hosts: ["hbase1", "hbase2", "hbase3"]

三 Java API

1 导入依赖

<dependencies>
    <!-- es -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>transport</artifactId>
        <version>6.5.3</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>

    <!-- json -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.71</version>
    </dependency>
</dependencies>

2 入门

2.1 elasticSearchUtils

package cn.qphone.es.api;

import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.net.InetAddress;

public class ElasticSearchUtils {
    private static TransportClient client;

    static {
        try {
            //1. 配置对象
            Settings settings = Settings.builder()
                    .put("cluster.name", "es-hzbigdata2002")
                    .build();
            //2. Transport对象
            client = new PreBuiltTransportClient(settings);
            //3. 创建es的集群地址
            TransportAddress[] trans = {
                    new TransportAddress(InetAddress.getByName("qphone01"), 9300),
                    new TransportAddress(InetAddress.getByName("qphone02"), 9300),
                    new TransportAddress(InetAddress.getByName("qphone03"), 9300)
            };
            //4. 连接es的服务器
            client.addTransportAddresses(trans);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接的es的客户端对象
     */
    public static TransportClient getClient()  {
        return client;
    }
}

2.2 quickstart

package cn.qphone.es.api;

import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.client.transport.TransportClient;

import java.net.UnknownHostException;
import java.util.Map;

public class Demo1_quickstart {
    public static void main(String[] args) throws UnknownHostException {
        //1. 获取到操作es的核心类
        TransportClient client = ElasticSearchUtils.getClient();

        //2. 操作es
        //2.1 创建索引库
        // curl -XPUT -H 'json/application' 'xxxxxx/index/type' -d '{"name":"lixi"}'
//        String json = "{\"name\":\"wyl\", \"age\":18}";
//        IndexResponse response = client.prepareIndex("hadoop", "hdfs")
//                .setSource(json, XContentType.JSON)
//                .get();
//        System.out.println("create json version:" + response.getVersion());
//        System.out.println(response.getIndex());
//        System.out.println(response.getType());

        //2.2 删除索引
//        DeleteResponse deleteResponse = client.prepareDelete("hadoop", "hdfs", "2")
//                .get();
//        System.out.println(deleteResponse.getIndex() + "/" + deleteResponse.getType() + "/" + deleteResponse.getId());

        //2.3 get
        GetResponse getResponse = client.prepareGet("hadoop", "hdfs", "ZZFVZnQBTuYsqQgZhqPE")
                .get();
        Map<String, Object> parm = getResponse.getSourceAsMap();
        System.out.println(parm.get("name"));
        System.out.println(parm.get("age"));
    }
}

四 中文分词

1 测试es的默认分词器

curl -H 'Content-Type: application/json' -XGET 'http://qphone01:9200/_analyze?&pretty' -d '{
"text":"i am a big big boy"
}'

curl -H 'Content-Type: application/json' -XGET 'http://qphone01:9200/_analyze?&pretty' -d '{
"text":"这里是好记性不如烂笔头感叹号的博客们"
}'

2 中文分词器:ik分词器

2.1 安装

##1. 安装解压工具
yum -y install unzip

##2. 上传ik分词器
##3. 将ik分词器拷贝到es的plugins目录
mkdir -p /opt/apps/elasticsearch-6.5.3/plugins/ik && mv /opt/software/elasticsearch-analysis-ik-6.5.3.zip /opt/apps/elasticsearch-6.5.3/plugins/ik && cd /opt/apps/elasticsearch-6.5.3/plugins/ik

##4. 解压
unzip elasticsearch-analysis-ik-6.5.3.zip && rm -f elasticsearch-analysis-ik-6.5.3.zip

##5. 分发
scp -r ik qphone02:/opt/apps/elasticsearch-6.5.3/plugins/ && scp -r ik qphone03:/opt/apps/elasticsearch-6.5.3/plugins/

##6. 重启es集群

2.2 测试

curl -H 'Content-Type: application/json' -XGET 'http://qphone01:9200/_analyze?&pretty' -d \
'{
"analyzer":"ik_max_word",
"text":"这里是好记性不如烂笔头感叹号的博客们"
}'

curl -H 'Content-Type: application/json' -XGET 'http://qphone01:9200/_analyze?&pretty' -d \
'{
"analyzer":"ik_max_word",
"text":"i am a big big girl"
}'

##2. 创建chinese的索引库,并指定其分词器的策略
curl -H 'Content-Type: application/json' -XPUT 'http://qphone01:9200/chinese?pretty' -d \
'
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "analysis": {
      "analyzer": {
        "ik": {
          "tokenizer": "ik_max_word"
        }
      }
    }
  },
  "mappings": {
    "test1":{
      "properties": {
        "content": {
          "type": "text",
          "analyzer": "ik_max_word",
          "search_analyzer": "ik_max_word"
        }
      }
    }
  }
}'

##3. 向chinese导入数据
curl -H 'Content-Type: application/json' -XPUT 'http://qphone01:9200/chinese/test1/1?pretty' -d \
'
{
  "content": "里皮是一位牌面足够大、支持率足够高的教练"
}
'

curl -H 'Content-Type: application/json' -XPUT 'http://qphone01:9200/chinese/test1/2?pretty' -d \
'
{
  "content": "他不仅在意大利国家队取得过成功"
}
'

curl -H 'Content-Type: application/json' -XPUT 'http://qphone01:9200/chinese/test1/3?pretty' -d \
'
{
  "content": "教练还带领广州恒大称霸中超并首次夺得亚冠联赛冠军"
}
'

##4. 向chinese检索教练关键词
curl -H 'Content-Type: application/json' -XGET 'http://qphone01:9200/chinese/_search?pretty' -d \
'
{
  "query": {
    "match": {
      "content": "教练"
    }
  }
}
'

3 全文检索的java api

package cn.qphone.es.api;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;

public class Demo2_Search {

    private static final String  INDEX = "chinese";

    public static void main(String[] args) {
        //1. 获取核心对象
        TransportClient client = ElasticSearchUtils.getClient();

        //2. 查询_search
        /*
         * matchAll --> select * from t
         * matchQuery --> select * from t where name like "%baby%"
         * termQuery --> select * from t where name = baby
         */
        SearchResponse response = client.prepareSearch(INDEX)
                .setSearchType(SearchType.QUERY_THEN_FETCH)
                .setQuery(QueryBuilders.matchQuery("content", "意大利"))
                .get();

        //3. 获取到搜索的记录
        SearchHits hits = response.getHits();
        long totalHits = hits.totalHits; // 总的记录
        float maxScore = hits.getMaxScore(); // 最大分数
        System.out.println("total hits: " + totalHits);
        System.out.println("max socres : " + maxScore);
        SearchHit[] searchHits = hits.getHits(); // 包含了具体的记录
        for (SearchHit hit : searchHits) {
            System.out.println("index : " + hit.getIndex());
            System.out.println("当前分数:" + hit.getScore());
            System.out.println("content : " + hit.getSourceAsString());
        }

    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容