ES


1.1 Elasticsearch 是什么
Elasticsearch 是一个基于 Apache Lucene™ 的开源搜索引擎。无论在开源还是专有领域,Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
主要特点:

  1. 分布式的实时文件存储,每个字段都被索引并可被搜索
  2. 分布式的实时分析搜索引擎–做不规则查询
  3. 可以扩展到上百台服务器,处理 PB 级结构化或非结构化数据
    Elasticsearch 使用 Java 开发并使用 Lucene 作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API 来隐藏 Lucene 的复杂性,从而让全文搜索变得简单。
    ES能做什么?
    全文检索(全部字段)、模糊查询(搜索)、数据分析(提供分析语法,例如聚合)
    关于什么是 REST API, 参考: https://www.zhihu.com/question/28557115

1.2 ElasticSearch 使用案例

  1. 2013年初,GitHub抛弃了Solr,采取 ElasticSearch 来做 PB 级的搜索。 “GitHub使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码”
  2. 维基百科:启动以 elasticsearch 为基础的核心搜索架构SoundCloud:“SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务”
  3. 百度:百度目前广泛使用 ElasticSearch 作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据
  4. 新浪使用 ES 分析处理 32 亿条实时日志
  5. 阿里使用 ES 构建挖财自己的日志采集和分析体系

1.3 与其他数据存储比较


第 2 章 ElasticSearch 基础知识


2.1 ElasticSearch 数据存储方式
2.1.1 几个重要的概念
概念 解释
cluster 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。
node 集群中的一个节点,一般只一个进程就是一个node
shard 分片,即使是一个节点中的数据也会通过 hash 算法,分成多个片存放,默认是 5 片。(7.0 默认是 1 片)
index 相当于EDBMS 的 database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个 shard 存放,也可能存放在多个 node 中。
type 类似于 rdbms 的 table,但是与其说像 table,其实更像面向对象中的 class , 同一Json 的格式的数据集合。((6.x只允许建一个,7.0被废弃,造成index实际相当于table级))
document 类似于 rdbms 的 row、面向对象里的object
field 相当于字段、属性


ES本身也是一个数据库:index 类似 databases; type: 类似与表
Document: 多行

特点:

2.3 倒排索引
要学习 ElasticSearch 必须学习倒排索引
什么是倒排索引呢?
请背出带“前”字的诗句, 你会发现自己几乎想不出来有哪些诗句.
请背下李白的的“静夜思”: “窗前明月光, 疑是地上霜, …”. 再背下李白的“望庐山瀑布”: “日照香炉生紫烟, 遥看瀑布挂前川,…” 很容易就背出来了. 为什么呢?
是因为你脑袋里面使用“题目”为诗句创建了索引, 通过这些索引你在脑海里面很检索出来具体的诗句.
如果我们也使用“前”为这些诗句建立索引, 是不是也会容易的检索出来这些诗句呢, 答案是肯定的! 这就是“倒排索引”
普通索引(正排索引)
普通的索引是以诗名作为 key, 诗的内容作为 value 来建立的索引的.

倒排索引
如果以“前”作为 key 和以诗的内容作为 value 来建立索引, 则就是倒排索引

也可为其他的字词建立倒排索引.


2.2 ElasticSearch 特点
2.2.1 天然分片, 天然集群
es 把数据分成多个 shard,下图中的 P0-P2,多个shard可以组成一份完整的数据,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,已达到负载均衡,横向扩展。

在实际运算过程中,每个查询任务提交到某一个节点,该节点必须负责将数据进行整理汇聚,再返回给客户端,也就是一个简单的节点上进行 Map 计算,在一个固定的节点上进行 Reduces 得到最终结果向客户端返回。

这种集群分片的机制造就 elasticsearch 强大的数据容量及运算扩展性。
2.2.2 天然索引

  1. ES 所有数据都是默认进行索引的,这点和 mysql 正好相反. (mysql 是默认不加索引,要加索引必须特别说明,ES 只有不加索引才需要说明。)
  2. 而 ES 使用的是倒排索引和 Mysql 的 B+Tree 索引不同。

第 3 章 ElasticSearch 安装
步骤 1: 下载安装包
我们使用 6.3.1 版本
https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-3-1
步骤 2: 解压
tar -zxvf elasticsearch-6.3.1.tar.gz -C /opt/module
步骤 3: 修改配置文件config/elasticsearch.yml
配置的时候需要注意: 每行必须顶格, 不能有前置空格. “:”后面必须有一个空格.

  1. 配置集群名

  2. 当前节点名: 每个节点的名字不能相同, 当分发到其他节点的时候, 需要改成不同的名字

  3. 给当前节点绑定 ip 地址, 端口号保持默认 9200 就行

  4. 关掉 bootstrap 自检程序

  5. 集群个节点IP地址,也可以使用域名,需要各节点能够解析

步骤 4: 分发 ElasticSearch
注意修改每个节点的名

步骤 5: 修改 linux 配置 ==》这里3台都要改
默认 elasticsearch 是单机访问模式,就是只能自己访问自己。 但是我们之后一定会设置成允许应用服务器通过网络方式访问。这时,elasticsearch 就会因为嫌弃单机版的低端默认配置而报错,甚至无法启动。 所以我们在这里就要把服务器的一些限制打开,能支持更多并发
注意: 修改以下配置的时候需要切换到 root 用户, 每个节点都要修改.
问题1: max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536] elasticsearch
原因:系统允许 Elasticsearch 打开的最大文件数需要修改成 65536 解决:vim /etc/security/limits.conf 添加内容: ==>一个一行

  • soft nofile 65536
  • hard nofile 131072
  • soft nproc 2048
  • hard nproc 65536

注意:“*” 不要省略掉
问题2:max number of threads [1024] for user [judy2] likely too low, increase to at least [2048] (CentOS7.x 不用改)
原因:允许最大进程数修该成4096 解决:vim /etc/security/limits.d/90-nproc.conf
修改如下内容: * soft nproc 1024
修改为
• soft nproc 4096 ==》任意用户4096个线程
》可以设备root的bug: 不受限unlimited

问题3:max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144] (CentOS7.x 不用改)
原因:一个进程可以拥有的虚拟内存区域的数量。 解决: 在 /etc/sysctl.conf 文件最后添加一行 vim /etc/sysctl.conf
vm.max_map_count=262144
即可永久修改
步骤 6 教学环境启动优化
ES是用在Java虚拟机中运行的,虚拟机默认启动占用2G内存。但是如果是装在PC机学习用,实际用不了2个G。所以可以改小一点内存。
》改成1G
vim config/jvm.options

注意: 注意别忘了分发修改后的配置文件jvm.options
步骤 7 启动 ElasticSearch
分别在 3 台设备上启动 ElasticSearch ==》打印输出在前台
bin/elasticsearch &
步骤 8 查看 ElasticSearch 是否启动成功

步骤 9 测试是否可以连接到 ElasticSearch
curl http://hadoop102:9200/_cat/nodes?v

或者在浏览器中输入地址: http://hadoop1:9200/_cat/nodes?v


第 4 章 Kibana 安装


4.1 ElasticSearch 交互方式

  1. 基于 HTTP 协议,以 JSON 为数据交互格式的 RESTful API
    GET POST PUT DELETE HEAD
  2. Elasticsearch 官方提供了多种程序语言的客户端— java,Javascript,.NET,PHP,Perl,Python,以及 Ruby——还有很多由社区提供的客户端和插件
    在学习测试阶段使用 Kibana 操作 ElasticSearch 是最方便的. 下面学习如何安装和使用 Kibana.
    Kibana 可以看出是一个操作 ElasticSeach 的客户端.

4.2 安装 Kibana
步骤 1: 下载 Kibana
https://www.elastic.co/cn/downloads/past-releases/kibana-6-3-1
步骤 2: 解压 Kibana
tar -zxvf kibana-6.3.1-linux-x86_64.tar.gz -C /opt/module
步骤 3: 配置config/kibana.yml ==>(0,0,0,0) 或hadoop102也可以

步骤 4: 启动 Kibana
bin/kibana
步骤 5: 在浏览器中打开 Kibana
http://hadoop102:5601


4.3 Kibana 功能简介


第 5 章 制作 Elastic 和 Kibana 的统一启停脚本
为了方便启动 ElasticSearch 和 Kibana, 制作统一启动脚本
#!/bin/bash
es_home=/opt/module/elasticsearch-6.3.1
kibana_home=/opt/module/kibana-6.3.1
case $1 in
“start”) {
for i in hadoop102 hadoop202 hadoop203
do
ssh i " s o u r c e / e t c / p r o f i l e ; i "source /etc/profile; i"source/etc/profile;{es_home}/bin/elasticsearch >$es_home/logs/es.log 2>&1 &"

    done

    nohup ${kibana_home}/bin/kibana >$kibana_home/kibana.log 2>&1 &

};;
"stop") {
    ps -ef|grep ${kibana_home} |grep -v grep|awk '{print $2}'|xargs kill

    for i in hadoop102 hadoop202 hadoop203
    do
        ssh $i "ps -ef|grep $es_home |grep -v grep|awk '{print \$2}'|xargs kill" >/dev/null 2>&1
    done


};;
*){
    echo "你启动的姿势不正确, 请使用参数 start 来启动es集群, 使用参数 stop 来关闭es集群"
};;

esac


第 6 章 Elastic Restfull Api


6.1 ElasticSearch 中保存的数据结构
假设有两个对象:
public class Movie {
String id;
String name;
Double doubanScore;
List actorList;
}

public class Actor{
String id;
String name;
}
这两个对象如果放在关系型数据库保存,会被拆成 2 张表,但是 elasticsearch 是用一个 json 来表示一个 document。
所以在 ES 中是这样保存的:
{
“id”:”1”,
“name”:”operation red sea”,
“doubanScore”:”8.5”,
“actorList”:[
{“id”:”1”,”name”:”zhangyi”},
{“id”:”2”,”name”:”haiqing”},
{“id”:”3”,”name”:”zhanghanyu”}
]
}


6.2 操作 ElasticSearch 中的数据


6.2.1 查看 ES 中有哪些索引
GET /_cat/indices?v
结果:

表头含义:
health green(集群完整) yellow(单点正常、集群不完整) red(单点不正常)
status 是否能使用
index 索引名
uuid 索引统一编号
pri 主节点几个
rep 从节点几个
docs.count 文档数
docs.deleted 文档被删了多少
store.size 整体占空间大小
pri.store.size 主节点占


6.2.2 增加索引
PUT /movie_index


6.2.3 删除索引
DELETE /movie_index


6.2.4 新增文档 ==》默认的type: _doc
PUT /movie_index/movie/1
{ “id”:1,
“name”:“operation red sea”,
“doubanScore”:8.5,
“actorList”:[
{“id”:1,“name”:“zhang yi”},
{“id”:2,“name”:“hai qing”},
{“id”:3,“name”:“zhang han yu”}
]
}
PUT /movie_index/movie/2
{
“id”:2,
“name”:“operation meigong river”,
“doubanScore”:8.0,
“actorList”:[
{“id”:3,“name”:“zhang han yu”}
]
}

PUT /movie_index/movie/3
{
“id”:3,
“name”:“incident red sea”,
“doubanScore”:5.0,
“actorList”:[
{“id”:4,“name”:“zhang chen”}
]
}
注意: 如果之前没建过 index 或者 type,es 会自动创建。


6.2.5 搜索 type 全部数据
GET /movie_index/movie/_search
{
“took”: 129,
“timed_out”: false,
“_shards”: {
“total”: 5,
“successful”: 5,
“skipped”: 0,
“failed”: 0
},
“hits”: {
“total”: 3,
“max_score”: 1,
“hits”: [
{
“_index”: “movie_index”,
“_type”: “movie”,
“_id”: “2”,
“_score”: 1,
“_source”: {
“id”: 2,
“name”: “operation meigong river”,
“doubanScore”: 8,
“actorList”: [
{
“id”: 3,
“name”: “zhang han yu”
}
]
}
},
{
“_index”: “movie_index”,
“_type”: “movie”,
“_id”: “1”,
“_score”: 1,
“_source”: {
“id”: 1,
“name”: “operation red sea”,
“doubanScore”: 8.5,
“actorList”: [
{
“id”: 1,
“name”: “zhang yi”
},
{
“id”: 2,
“name”: “hai qing”
},
{
“id”: 3,
“name”: “zhang han yu”
}
]
}
},
{
“_index”: “movie_index”,
“_type”: “movie”,
“_id”: “3”,
“_score”: 1,
“_source”: {
“id”: 3,
“name”: “incident red sea”,
“doubanScore”: 5,
“actorList”: [
{
“id”: 4,
“name”: “zhang chen”
}
]
}
}
]
}
}


6.2.2 查找指定 id 的 document 数据 ==》有一个id
GET /movie_index/movie/1
{
“_index”: “movie_index”,
“_type”: “movie”,
“_id”: “1”,
“_version”: 1,
“found”: true,
“_source”: {
“id”: 1,
“name”: “operation red sea”,
“doubanScore”: 8.5,
“actorList”: [
{
“id”: 1,
“name”: “zhang yi”
},
{
“id”: 2,
“name”: “hai qing”
},
{
“id”: 3,
“name”: “zhang han yu”
}
]
}
}


6.2.7 修改 document ==》2个参数是不一样的
修改分两种: 整体替换和只修改某个字段
整体替换
和新增文档没有区别
PUT /movie_index/movie/3
{
“id”:“3”,
“name”:“incident red sea”,
“doubanScore”:“8.0”,
“actorList”:[
{“id”:“1”,“name”:“zhang chen”}
]
}
只修改某个字段 ==》只对字段进行更改
使用post方法 ==》doc修改某个字段: 格式
POST /movie_index/movie/3/_update
{
“doc”: {
“doubanScore”:“8.1”
}
}


6.2.8 删除一个 document
DELETE /movie_index/movie/3


6.2.9 按条件查询(全部)
GET /movie_index/movie/_search
{
“query”: {
“match_all”: {}
}
}


6.2.10 按照字段的分词查询
GET /movie_index/movie/_search
{
“query”: {
“match”: {
“name”: “sea”
}
}
}


6.2.11 按照分词子属性查询
GET /movie_index/movie/_search
{
“query”: {
“match”: {
“actorList.name”: “zhang”
}
}
}


6.2.12 按照短语查询
安装短语查询的意思是指, 匹配某个 field 的整个内容, 不再利用分词技术
GET /movie_index/movie/_search
{
“query”: {
“match_phrase”: {
“name”: “operation red”
}
}
}
说明: 把operation red作为一个整体来看待
对比:
下面的表示包含 operation 或者 red 的都会被查找出来
GET /movie_index/movie/_search
{
“query”: {
“match”: {
“name”: “operation red”
}
}
}


6.2.13 模糊查询
校正匹配分词,当一个单词都无法准确匹配,es 通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。 ==》fuzzy: 模糊匹配
GET /movie_index/movie/_search
{
“query”: {
“fuzzy”: {
“name”: “red”
}
}
}


6.2.14 过滤(查询后过滤) ==》查询后过滤: post_filter : 这种用的比较多
GET /movie_index/movie/_search
{
“query”: {
“match”: {
“name”: “red”
}
}, ==》json,这里用,
“post_filter”: {
“term”: { ==》term默认格式:用哪一个term进行过滤
“actorList.id”: “3”
}
}
}


6.1.15 查询前过滤(推荐使用) ==》 推荐使用
GET movie_index/movie/_search
{
“query”: {
“bool”: { ==》bool类型
“filter”: [ ==》数组里面放多个对象,这里用【】
{“term”:
{“actorList.id”: 3}
},
{
“term”:
{“actorList.id”: 1}
}
],
“must”: ==》相当于&& ; 先过滤再匹配
{“match”: {
“name”: “zhang”
}}

}

}
}


6.1.16 按范围过滤 ==》比如豆瓣分数
GET movie_index/movie/_search
{
“query”: {
“bool”: {
“filter”: {
“range”: {
“doubanScore”: {
“gt”: 5,
“lt”: 9
}
}
}
}
}
}


6.1.17 排序
GET movie_index/movie/_search
{
“query”:{
“match”: {“name”:“red operation”}
}
, “sort”: [
{
“doubanScore”: {
“order”: “desc”
}
}
]
}


6.1.18 分页查询 ===》默认索引0(from)
GET movie_index/movie/_search
{
“query”: { “match_all”: {} },
“from”: 1,
“size”: 1
}
==》从这一页的第n条开始:From:


6.2.19 指定查询的字段 ==》指定的字段
GET movie_index/movie/_search
{
“query”: { “match_all”: {} },
“_source”: [“name”, “doubanScore”] ==》查询某一个字段
}


6.2.20 聚合
每个演员参演了多少部电影 ==》keyword: 不分词 aggs:聚合

GET movie_index/movie/_search
{
“aggs”: {
“groupby_actor”: { ==》按那个字段聚合,相当于别名
“terms”: { ==》聚合的类型,没有加:默认是count
“field”: “actorList.name.keyword”
}
}
}
}
每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/movie/_search
{
“aggs”: {
“groupby_actor_id”: { ==》相对与groupby ,聚合都在这个下面
“terms”: {
“field”: “actorList.name.keyword” ==》name默认是text,这个不能直接做分组字段,所以换成不分词的keyword新式
“order”: {
“avg_score”: “desc”
}
}, ==》分完组了按什么聚合
“aggs”: {
“avg_score”:{
“avg”: {
“field”: “doubanScore”
}
}
}
}
}
}


第 7 章 中文分词
elasticsearch 本身自带的中文分词,就是单纯把中文一个字一个字的分开,根本没有词汇的概念。
但是实际应用中,用户都是以词汇为条件,进行查询匹配的,如果能够把文章以词汇为单位切分开,那么与用户的查询条件能够更贴切的匹配上,查询速度也更加快速。


7.1 分词器
Elasticsearch自带的分词器

中文分词器


7.1 安装 IK 分词器
步骤 1: 下载中文分词器 ==》版本要和es匹配
使用 IK Analysis for Elasticsearch. 下载与 ElasticSearch 的版本匹配的分词器版本.
https://github.com/medcl/elasticsearch-analysis-ik/releases
步骤 2: 解压分词器
需要解压到 ES 的plugins目录下 ==》放到指定的目录,不能错 最后分发
unzip elasticsearch-analysis-ik-6.3.1.zip -d /opt/module/elasticsearch-6.3.1/plugins/ik ==》要有这个目录
步骤 3: 重启启动 ElasticSearch


7.2 测试使用
使用默认分词器
GET movie_index/_analyze
{
“text”: “我是中国人”
}
结果:

使用ik_smart分词器 ==》 最少分词 : 中文索引
GET movie_index/_analyze
{
“analyzer”: “ik_smart”,
“text”: “我是中国人”
}
结果:

使用 ik_max_word
GET movie_index/_analyze
{
“analyzer”: “ik_max_word”,
“text”: “我是中国人”
}


第 8 章 关于 Mapping
查看 Mapping ==》指定字段的类型: 自动推断
之前说 type 可以理解为table,那每个字段的数据类型是如何定义的呢
默认情况下, 是由插入的第一条数据的类型来自动推断来设定的!
可以通过 Mapping 来设置和查看每个字段的数据类型.
GET movie_index/movie/_mapping ==》mapping: 查看数据类型

==》字段类型的推断方式:
true/false → boolean
1020 → long
20.1 → double ==》或 float
“2018-02-01” → date
“hello world” → text +keyword
==》Nested: 嵌套
类型的作用?
分词和索引:

  1. 索引: 默认都建索引 ;
  2. 分词+索引 : text
  3. 既不分词也不索引(long类型)
    手动指定 mapping
    查询:
    搭建索引
    PUT movie_chn (==》index)
    ==》如果这里分隔开: 会自动推断类型;否则依据指定
    {
    “mappings”: {
    “movie”:{
    “properties”: {
    “id”:{
    “type”: “long”
    },
    “name”:{
    “type”: “text”
    , “analyzer”: “ik_smart” ==》指定为分词器
    },
    “doubanScore”:{
    “type”: “double”
    },
    “actorList”:{
    “properties”: {
    “id”:{
    “type”:“long”
    },
    “name”:{
    “type”:“keyword”
    }
    }
    }
    }
    }
    }
    }
    插入数据
    PUT /movie_chn/movie/1
    { “id”:1,
    “name”:“红海行动”,
    “doubanScore”:8.5,
    “actorList”:[
    {“id”:1,“name”:“张译”},
    {“id”:2,“name”:“海清”},
    {“id”:3,“name”:“张涵予”}
    ]
    }
    PUT /movie_chn/movie/2
    {
    “id”:2,
    “name”:“湄公河行动”,
    “doubanScore”:8.0,
    “actorList”:[
    {“id”:3,“name”:“张涵予”}
    ]
    }

PUT /movie_chn/movie/3
{
“id”:3,
“name”:“红海事件”,
“doubanScore”:5.0,
“actorList”:[
{“id”:4,“name”:“张晨”}
]
}
查询
GET /movie_chn/movie/_search
{
“query”: {
“match”: {
“name”: “红海”
}
}
}

GET /movie_chn/movie/_search
{
“query”: {
“term”: {
“actorList.name”: “张”
}
}
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值