一 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());
}
}
}