栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

elasticsearch下载安装及简单使用

elasticsearch下载安装及简单使用

# elasticsearch

## 下载与安装

### ES

> 下载:https://www.elastic.co/cn/downloads/elasticsearch

![image-20211004171406953](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004171406953.png)

>下载后解压即安装,需要在配置文件中添加以下配置

```yml
作用:添加以下配置后可以使用ES-head来操作ES
http.cors.enabled: true
http.cors.allow-origin: "*"
```

>修改配置文件后可能出现的启动闪退的情况,这是只需要检查拼写、编码、分割符即可

### ES-head(辅助工具)

> https://github.com/mobz/elasticsearch-head

![image-20211004171735604](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004171735604.png)

> 解压后进入文件夹打开命令窗口,执行以下命令。即可访问

```
npm install
npm start
```

### kibana(辅助工具)

> https://www.elastic.co/cn/kibana

```
修改配置文件(中文)
i18n.locale: "zh-CN"
```

>双击bin目录下的.bat文件即可启动

## ES的概念

**索引(index)**:ElasticSearch存储数据的地方,可以理解成关系型数据库中的数据库概念。

**映射(mapping)**:mapping定义了每个字段的类型、字段所使用的分词器等。相当于关系型数据库中的表结构。

**文档(document)**:   Elasticsearch中的最小数据单元,常以json格式显示。一个document相当于关系型数据库中的一行数据。

**倒排索引**:   一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,对应一个包含它的文档id列表。

**类型(type)**:   一种type就像一类表。如用户表、角色表等。在Elasticsearch7.X默认type为_doc

     - ES 5.x中一个index可以有多种type。
    
      - ES 6.x中一个index只能有一种type。
    
      - ES 7.x以后,将逐步移除type这个概念,现在的操作已经不再使用,默认_doc

**分片(shard)**:索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中。

**分片与自平衡**:当节点挂掉后,挂掉的节点分片会自平衡到其他节点中

注意:分片数量一旦确定好,不能修改。

**主分片(Primary shard)**:相对于副本分片的定义。

**副本分片(Replica shard)**每个主分片可以有一个或者多个副本,数据和主分片一样。

## RESTful风格介绍

(Representational State Transfer),表述性状态转移,是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。就是一种定义接口的规范。

## 分词器

> 什么是分词器

![image-20211004175113386](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004175113386.png)

如果要使用中文,建议使用ik分词器

> https://elasticsearch.cn/download/

下载完成之后在ES的plugins目录下把压缩包解压即可

![image-20211004180635761](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004180635761.png)

给ik分词器增加自己的配置

![image-20211004181104361](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004181104361.png)

添加之前

![image-20211004181159483](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004181159483.png)

添加之后

![image-20211004181504945](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004181504945.png)

## ES数据类型

1. **简单数据类型**

- 字符串

聚合:相当于mysql 中的sum(求和)

```text
text:会分词,不支持聚合

keyword:不会分词,将全部内容作为一个词条,支持聚合
```

- 数值
- 布尔:boolean

- 二进制:binary
- 范围类型


```
integer_range, float_range, long_range, double_range, date_range 
```

- 日期:date

2. **复杂数据类型**

•数组:[ ]  Nested: `nested` (for arrays of JSON objects 数组类型的JSON对象)  

•对象:{ } Object: object(for single JSON objects 单个JSON对象)

## 关于索引的基本操作

![image-20211004200327907](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004200327907.png)

 ## 关于文档的操作

### 简单操作

所有的查询都用GET

> 添加数据

```
PUT /hezhong/user/1
{
  "name":"秦始皇",
  "age":25,
  "desc":"吃饭睡觉打游戏"
}
```

![image-20211004202023774](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004202023774.png)

> 查询数据 GET

```
GET hezhong/user/1
```

> 更新数据 put

![image-20211004202542932](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004202542932.png)

用put更新数据时没有写的字段会被置空

> 使用post的updat方法可以避免

其他值不会被覆盖,灵活性更高

![image-20211004202928556](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004202928556.png)

![image-20211004203005298](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004203005298.png)

![image-20211004205409734](C:UserslenovoAppDataRoamingTyporatypora-user-imagesimage-20211004205409734.png)

score:分数,匹配度越高,值越大,越靠前

### 复杂操作(搜索)

#### matchAll

```
# 默认情况下,es一次展示10条数据,通过from和size来控制分页
# 查询结果详解
GET goods/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 100
}

GET goods
```

```java

    @Test
    public void matchAll() throws IOException {

        //2. 构建查询请求对象,指定查询的索引名称
        SearchRequest searchRequest=new SearchRequest("goods");

        //4. 创建查询条件构建器SearchSourceBuilder
        SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();

        //6. 查询条件
        QueryBuilder queryBuilder= QueryBuilders.matchAllQuery();
        //5. 指定查询条件
        sourceBuilder.query(queryBuilder);

        //3. 添加查询条件构建器 SearchSourceBuilder
        searchRequest.source(sourceBuilder);
        // 8 . 添加分页信息  不设置 默认10条
//        sourceBuilder.from(0);
//        sourceBuilder.size(100);
        //1. 查询,获取查询结果

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        //7. 获取命中对象 SearchHits
        SearchHits hits = searchResponse.getHits();

        //7.1 获取总记录数
      Long total= hits.getTotalHits().value;
        System.out.println("总数:"+total);
        //7.2 获取Hits数据  数组
        SearchHit[] hits1 = hits.getHits();
            //获取json字符串格式的数据
        List goodsList = new ArrayList<>();
        for (SearchHit searchHit : hits1) {
            String sourceAsString = searchHit.getSourceAsString();
            //转为java对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            goodsList.add(goods);
        }

        for (Goods goods : goodsList) {
            System.out.println(goods);
        }

    }
```

#### termQuery

查询text类型的数据时:只要其中出现了查询的关键字就会返回结果

查询keyword时:因为关键字不分词,需要查询条件和字段值完全匹配才可以

term Query 会去倒排索引中寻找确切的term,它并不知道分词器的存在。适合keyword、numeric、date

#### matchQuery

会对条件进行分词、将分词后的查询条件和词条进行匹配、默认取交集(OR)

match Query 知道分词器的存在。并且理解时如何被分词的

#### 模糊查询

wildcard查询:会对查询条件进行分词。还可以使用通配符 ?(任意单个字符) 和  * (0个或多个字符)

```
"*华*"  包含华字的
"华*"   华字后边多个字符
"华?"  华字后边多个字符
"*华"或"?华" 会引发全表(全索引)扫描 注意效率问题
```

```json
# wildcard 查询。查询条件分词,模糊查询
GET goods/_search
{
  "query": {
    "wildcard": {
      "title": {
        "value": "华*"
      }
    }
  }
}
```

#### 正则查询

```
W:匹配包括下划线的任何单词字符,等价于 [A-Z a-z 0-9_]   开头的反斜杠是转义符

+号多次出现

(.)*为任意字符
正则查询取决于正则表达式的效率
```

```json
GET goods/_search
{
  "query": {
    "regexp": {
      "title": "\w+(.)*"
    }
  }
}

```

#### 前缀查询

 对keyword类型支持比较好

```json
# 前缀查询 对keyword类型支持比较好
GET goods/_search
{
  "query": {
    "prefix": {
      "brandName": {
        "value": "三"
      }
    }
  }
}
```

#### 范围&排序查询

```json
# 范围查询

GET goods/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 2000,
        "lte": 3000
      }
    }
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}
```

#### queryString查询

 queryString 多条件查询

•会对查询条件进行分词。

•然后将分词后的查询条件和词条进行等值匹配

•默认取并集(OR)

•可以指定多个查询字段

query_string:识别query中的连接符(or 、and)

```
# queryString

GET goods/_search
{
  "query": {
    "query_string": {
      "fields": ["title","categoryName","brandName"], 
      "query": "华为 AND 手机"
    }
  }
}
```

simple_query_string:不识别query中的连接符(or 、and),查询时会将 “华为”、"and"、“手机”分别进行查询

```
GET goods/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["title","categoryName","brandName"], 
      "query": "华为 AND 手机"
    }
  }
}
```

query_string:有default_operator连接符的脚本

```json
GET goods/_search
{
  "query": {
    "query_string": {
      "fields": ["title","brandName","categoryName"],
      "query": "华为手机 "
      , "default_operator": "AND"
    }
  }
}

```

注意:query中的or   and 是查询时 匹配条件是否同时出现----or 出现一个即可,and 两个条件同时出现

default_operator的or   and 是对结果进行 并集(or)、交集(and)

#### 布尔查询-脚本

 boolQuery:对多个查询条件连接。连接方式:

•must(and):条件必须成立

•must_not(not):条件必须不成立

•should(or):条件可以成立

•filter:条件必须成立,性能比must高。不会计算得分

**得分:**即条件匹配度,匹配度越高,得分越高

```json 
# boolquery
#must和filter配合使用时,max_score(得分)是显示的
#must 默认数组形式
GET goods/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "brandName": {
              "value": "华为"
            }
          }
        }
      ],
      "filter":[ 
        {
        "term": {
          "title": "手机"
        }
       },
       {
         "range":{
          "price": {
            "gte": 2000,
            "lte": 3000
         }
         }
       }
      
      ]
    }
  }
}
#filter 单独使用   filter可以是单个条件,也可多个条件(数组形式)
GET goods/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brandName": {
              "value": "华为"
            }
          }
        }
      ]
    }
  }
}
```

#### 聚合查询-脚本

•指标聚合:相当于MySQL的聚合函数。max、min、avg、sum等

•桶聚合:相当于MySQL的 group by 操作。不要对text类型的数据进行分组,会失败。

```json
# 聚合查询

# 指标聚合 聚合函数

GET goods/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "aggs": {
    "max_price": {
      "max": {
        "field": "price"
      }
    }
  }
}

# 桶聚合  分组

GET goods/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "aggs": {
    "goods_brands": {
      "terms": {
        "field": "brandName",
        "size": 100
      }
    }
  }
}
```

#### 高亮查询-脚本

高亮三要素:

•高亮字段

•前缀

•后缀

默认前后缀 :em

```html
手机
```

```json
GET goods/_search
{
  "query": {
    "match": {
      "title": "电视"
    }
  },
  "highlight": {
    "fields": {
      "title": {
        "pre_tags": "",
        "post_tags": "
"
      }
    }
  }
}
```

#### 重建索引&索引别名

```json
#查询别名 默认别名无法查看,默认别名同索引名
GET goods/_alias/
#结果
{
  "goods" : {
    "aliases" : { }
  }
}

```

1.新建student_index_v1索引

```json
# -------重建索引-----------

# 新建student_index_v1。索引名称必须全部小写

PUT student_index_v1
{
  "mappings": {
    "properties": {
      "birthday":{
        "type": "date"
      }
    }
  }
}
#查看 student_index_v1 结构
GET student_index_v1
#添加数据
PUT student_index_v1/_doc/1
{
  "birthday":"1999-11-11"
}
#查看数据
GET student_index_v1/_search

#添加数据
PUT student_index_v1/_doc/1
{
  "birthday":"1999年11月11日"
}
```

2.重建索引:将student_index_v1 数据拷贝到 student_index_v2

```json
# 业务变更了,需要改变birthday字段的类型为text

# 1. 创建新的索引 student_index_v2
# 2. 将student_index_v1 数据拷贝到 student_index_v2

# 创建新的索引 student_index_v2
PUT student_index_v2
{
  "mappings": {
    "properties": {
      "birthday":{
        "type": "text"
      }
    }
  }
}
# 将student_index_v1 数据拷贝到 student_index_v2
# _reindex 拷贝数据
POST _reindex
{
  "source": {
    "index": "student_index_v1"
  },
  "dest": {
    "index": "student_index_v2"
  }
}

GET student_index_v2/_search

PUT student_index_v2/_doc/2
{
  "birthday":"1999年11月11日"
}

```

3.创建索引库别名:

注意:DELETE student_index_v1 这一操作将删除student_index_v1索引库,并不是删除别名

```json
# 思考: 现在java代码中操作es,还是使用的实student_index_v1老的索引名称。
# 1. 改代码(不推荐)
# 2. 索引别名(推荐)

# 步骤:
# 0. 先删除student_index_v1
# 1. 给student_index_v2起个别名 student_index_v1

# 先删除student_index_v1
#DELETE student_index_v1 这一操作将删除student_index_v1索引库
#索引库默认的别名与索引库同名,无法删除

# 给student_index_v1起个别名 student_index_v11
POST student_index_v2/_alias/student_index_v11
#测试删除命令
POST /_aliases
{
    "actions": [
        {"remove": {"index": "student_index_v1", "alias": "student_index_v11"}}
    ]
}
DELETE student_index_v1
# 给student_index_v2起个别名 student_index_v1
POST student_index_v2/_alias/student_index_v1

#查询别名
GET goods/_alias/


GET student_index_v1/_search
GET student_index_v2/_search

```

### ES集群

ES天然支持集群、设计隐藏了分布式本身的复杂性

集群:多个人做同一件事

分布式:多个人做不同的事

集群解决的问题:让系统高可用、分担请求压力

分布式解决的问题:分担存储和计算压力,提速

#### 相关概念

•集群(cluster):一组拥有共同的 cluster name 的 节点。

•节点(node)  :集群中的一个 Elasticearch 实例

•索引(index) :es存储数据的地方。相当于关系数据库中的database概念

•分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中

•主分片(Primary shard):相对于副本分片的定义。

•副本分片(Replica shard)每个主分片可以有一个或者多个副本,数据和主分片一样。

##### 路由原理

•文档存入对应的分片,ES计算分片编号的过程,称为路由。

•Elasticsearch 是怎么知道一个文档应该存放到哪个分片中呢?

•查询时,根据文档id查询文档, Elasticsearch 又该去哪个分片中查询数据呢?

•路由算法 :shard_index = hash(id) % number_of_primary_shards

##### 脑裂

ES集群的正常状态

• 一个正常es集群中只有一个主节点(Master),主节点负责管理整个集群。如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。

•集群的所有节点都会选择同一个节点作为主节点。

什么是脑裂现象

• 一个正常es集群中只有一个主节点(Master),主节点负责管理整个集群。如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。

•集群的所有节点都会选择同一个节点作为主节点。

**脑裂产生的原因:**

1.网络原因:网络延迟

一般es集群会在内网部署,也可能在外网部署,比如阿里云。

内网一般不会出现此问题,外网的网络出现问题的可能性大些。

2.节点负载

主节点的角色既为master又为data。数据访问量较大时,可能会导致Master节点停止响应(假死状态)。

​        •node.master: true

​        •node.data: false

3.JVM内存回收

当Master节点设置的JVM内存较小时,引发JVM的大规模内存回收,造成ES进程失去响应。

**避免脑裂**:

1.网络原因:discovery.zen.ping.timeout 超时时间配置大一点。默认是3S

2.节点负载:角色分离策略

​    •候选主节点配置为

​        •node.master: true

​        •node.data: false

​    •数据节点配置为

​        •node.master: false

​        •node.data: true

3.JVM内存回收:修改 config/jvm.options 文件的 -Xms 和 -Xmx 为服务器的内存一半。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/300807.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号