ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
第一节 elasticSearch的使用场景
1、 为用户提供按关键字查询的全文搜索功能。
2、 实现企业海量数据的处理分析的解决方案。大数据领域的重要一份子,如著名的ELK框架(ElasticSearch,Logstash,Kibana)。
第二节 常用数据库存储对比
第三节 elasticsearch的特点
1.3.1 天然分片,天然集群
es 把数据分成多个shard,下图中的P0-P2,多个shard可以组成一份完整的数据,这些shard可以分布在集群中的各个机器节点中。随着数据的不断增加,集群可以增加多个分片,把多个分片放到多个机子上,已达到负载均衡,横向扩展。
在实际运算过程中,每个查询任务提交到某一个节点,该节点必须负责将数据进行整理汇聚,再返回给客户端,也就是一个简单的节点上进行Map计算,在一个固定的节点上进行Reduces得到最终结果向客户端返回。
这种集群分片的机制造就了elasticsearch强大的数据容量及运算扩展性。
1.3.2 天然索引
ES 所有数据都是默认进行索引的,这点和mysql正好相反,mysql是默认不加索引,要加索引必须特别说明,ES只有不加索引才需要说明。
而ES使用的是倒排索引和Mysql的B+Tree索引不同。
第四节 lucene与elasticsearch的关系
lucene只是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。
好比lucene是类似于发动机,而搜索引擎软件(ES,Solr)就是汽车。
目前市面上流行的搜索引擎软件,主流的就两款,elasticsearch和solr,这两款都是基于lucene的搭建的,可以独立部署启动的搜索引擎服务软件。由于内核相同,所以两者除了服务器安装、部署、管理、集群以外,对于数据的操作,修改、添加、保存、查询等等都十分类似。就好像都是支持sql语言的两种数据库软件。只要学会其中一个另一个很容易上手。
从实际企业使用情况来看,elasticSearch的市场份额逐步在取代solr,国内百度、京东、新浪都是基于elasticSearch实现的搜索功能。国外就更多了 像维基百科、GitHub、Stack Overflow等等也都是基于ES的。
2.1 下载地址
https://www.elastic.co/cn/downloads/past-releases#elasticsearch
https://www.elastic.co/cn/downloads/past-releases#kibana
【注意】:
- es和kibana版本下载需一致
- 目前生产环境大多采用大版本6.x.x;7.x.x版本相对较新,但部署流程都一样
2.2 机器规划
3台机器:
11.8.37.50 ops01
11.8.36.63 ops02
11.8.36.76 ops03
【注意】:如果在各节点的/etc/hosts中都配置了节点的ip解析,那后续在配置文件中,相关的ip配置都可以用解析名代替;
例如:network.host: 11.8.37.50 等同于 network.host: ops01
2.3 下载安装包
2.4 环境优化
2.4.1 优化1
系统允许 Elasticsearch 打开的最大文件数需要修改成65536
这个配置不优化启动服务会出现:
[error] max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536] elasticsearch
2.4.2 优化2
允许最大进程数配置修该成4096;不是4096则需要修改优化
这个配置不优化启动服务会出现:
[error]max number of threads [1024] for user [judy2] likely too low, increase to at least [4096]
2.4.3 优化3
设置一个进程可以拥有的虚拟内存区域的数量
这个配置不优化启动服务会出现:
[error]max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
2.5 解压安装
2.6 修改配置文件
配置项说明:
cluster.name: my-es # 集群名称;同一集群各节点名称必须相同
node.name: node-ops01 # 当前节点名称;可理解成在集群中各自用这个名称区别
bootstrap.memory_lock: false # bootstrap自检程序
network.host: 11.8.37.50 # 当前节点host主机
http.port: 9200 # es启动端口
discovery.zen.ping.unicast.hosts: [“11.8.37.50”, “11.8.36.63”, “11.8.36.76”] # 自发现配置:新节点向集群报到的主机名
【注意】: 这些是常规配置,其它例如data存储路径,log存储路径等等都可以自定义根据情况去配置
2.7 分发安装目录
2.8 修改其它节点配置文件
2.9 服务启动
【注意】:
- -d 为后台运行,不加-d只能前台运行,关了会话窗口服务也会同时终止
- 3台机器都需要启动elasticsearch
- 运行日志没有配置定义,默认在服务目录下:elasticsearch-6.6.0/logs/ ,有异常可以先查看日志
2.10 命令验证es
【注意】:正常运行的es集群,curl各个节点nodes状态都是可以返回结果
2.11 安装kibana
2.12 界面验证kibana
在哪个节点部署,则使用对应地址+5601端口访问
http://11.8.36.76:5601/
第一节:关键词解释
第二节:语法简单示例:
GET /_cat/nodes?v # 查询各个节点状态
GET /_cat/indices?v # 查询各个索引状态
GET /_cat/shards/xxxx # 查询某个索引的分片情况
第三节:elasticsearch 9200 9300端口区别
es正常启动会有9200和9300两个端口
1、9200作为Http协议,主要用于外部通讯;是 HTTP 协议的 RESTful 接口
2、9300作为Tcp协议,jar之间就是通过tcp协议通讯;集群间和 TCPClient 都走得它
DSL: 全称 Domain Specific language,即特定领域专用语言
第一节 es中保存的数据结构
一般在java代码中,两个对象如果放在关系型数据库保存,例如存储在MySQL中,则会被拆成2张表,Movie对应一张MySQL表,Actor对应另一张MySQL表;
但是elasticsearch是用一个json来表示一个document。
为便于理解,简单和MySQL作一个对比,关键词只是类似,并不是完全一个概念,功能差不多
第二节 对数据常用操作
4.2.1 查看es中有哪些索引
比较类似MySQL中的show tables;
【注意】:
- es 中会默认存在一个名为.kibana的索引
- GET /_cat/indices?v 等同于命令行中curl http://11.8.37.50:9200/_cat/indices?v
- 最后的?v可以不加,但是不建议,因为这样结果没有表头,查询的结果相对较乱,不便于查阅
查询索引表头各关键词释义
4.2.2 添加索引
比较类似MySQL中的create table;
【注意】:
#! Deprecation: the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template
意思大致是:提示在大版本7.0.0以后,默认分片数将从5更改变为1,以后如想使用默认的5,就必须新建带有索引模板的索引请求
再次查询索引信息:
4.2.3 删除索引
比较类似MySQL中的drop table;
4.2.4 新增文档
比较类似MySQL中某张表的insert into ;
语法:格式 PUT /index/type/id
如果上面示例的 movie_index索引删除了,重新建一下:PUT /movie_index
新增:
4.2.5 直接用id查找数据
比较类似MySQL中某张表的select where条件 ;
4.2.6 修改 - ( 修改整体替换数据 )
比较类似MySQL中某张表的alter table ;
【注意】: 和新增没有区别 要求:必须包括全部字段
4.2.7 修改 - ( 修改某个字段 )
某个字段的值内容修改
比较类似MySQL中某张表的alter table ;
某个字段关闭索引
4.2.8 删除一个document
比较类似MySQL中某张表的DELETE FROM <表名> [WHERE 子句]
4.2.9 搜索type全部数据
比较类似MySQL中某张表select * from;
4.2.10 按条件查询(全部)
【注意】:按条件查询时,条件中为空,则效果等同于查询type中全部数据GET movie_index/movie/_search
4.2.11 按分词查询
比较类似MySQL中某张表select * from like %xxx%;但是仅仅像原理不同
4.2.12 按分词子属性查询
4.2.13 match phrase [ 短语查询 ]
按短语查询,不再利用分词技术,直接用短语在原始数据中匹配
相当于operation red当成一个整体来查询,不会operation查完再查询red,并不做拆分一个个去匹配;name中单独有operation和red的词就不符合条件
4.2.14 fuzzy查询 [ 校正匹配 ]
fuzzy校正匹配分词,当一个单词都无法准确匹配,es通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
这个机制就相当于平时搜索百度内容时,输入的内容可能输错了,主页搜内容会提示:您是否要搜索是xxx,然后把搜索xxx的内容返回
4.2.15 过滤–查询后过滤(先查询后过滤)
post_filter过滤为满足条件的数据保留,不满足的剔除;并不是符合post_filter给剔除。
先查询满足name中有red的是
id=1 -> “name”: “operation red sea”,
id=3 -> “name”: “incident red sea”,
在过滤出id为3的结果返回
4.2.16 过滤–查询前过滤(先过滤后查询)
同样需求下,先过滤后查询优于先查询后过滤
4.2.17 过滤–按范围过滤
“name”: “operation red sea”,
“doubanScore”: 8.5,
“name”: “operation meigong river”,
“doubanScore”: 8,
“name”: “incident red sea”,
“doubanScore”: 5,
查出电影评分8分及以上的结果
结果返回id为1和2的数据
4.2.18 排序
先查出名称包含red sea关键词的数据,再根据查询数据结果进行排序;asc 从小到大 | desc从大到小
4.2.19 分页查询
from定义了目标数据的偏移值
size定义当前返回的事件数目。
如果不自定义数值则默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。
4.2.20 指定查询的字段
4.2.21 高亮显示
这里可以看到结果中包裹了一层em标签,就是高亮显示,加斜
可以创建个html后缀的文件,输入如下代码,保存html文件用浏览器打开,再进行观察比对
4.2.22 聚合查询
示例来说明1:取出每个演员共参演了多少部电影
示例来说明2:每个演员参演电影的平均分是多少,并按评分排序
keyword 是某个字符串字段,专门储存不分词格式的副本 ,在某些场景中只允许只用不分词的格式,比如过滤filter 比如 聚合aggs, 所以字段要加上.keyword的后缀
keyword功能:
- 不进行分词,直接索引
- 支持模糊、精确查询
- 支持聚合
第三节 中文分词
elasticsearch本身自带的中文分词,就是单纯把中文一个字一个字的分开,根本没有词汇的概念。但是实际应用中,用户都是以词汇为条件,进行查询匹配的,如果能够把文章以词汇为单位切分开,那么与用户的查询条件能够更贴切的匹配上,查询速度也更加快速。
通过示例可以明显看出,“wang ting niubi”,“今天给力”;英文分词根据空格分词相对合理,但中文一个个字拆开显然不合适(今天 、给力 两个词语没有被识别)
分词器下载网址:https://github.com/medcl/elasticsearch-analysis-ik
【注意】:建议找到和es版本一致的ik版本最佳;找到zip包下载
安装
【注意】:插件安装需重启es才生效,否则使用不到对应功能,如下图
重启es:
测试使用ik中文分词
常用的ik分词器功能有ik_smart和ik_max_word
ik_smart
逐个去匹配,每个字使用1次
ik_max_word
逐个去匹配,每个字前后能连成词都会展示,相当于尽可能多的形成关系词
【注意】:从上面示例可以看出,不同的分词器,分词有明显的区别,所以以后定义一个type不能再使用默认的mapping,要手工建立mapping来指定分词器, 因为要根据使用场景选择适用合理的分词器
自定义中文词库
生活中,经常会出现一些新的热门词语,比如近期我接触最多的就是yyds永远的神。。。如果始终用之前的词库,那像 永远的神 就可能分成:永远、的、神,不会是我们所想的永远的神作为一个整体。
那这种情况就需要维护一套用户自定义的中文词库。
在没有自定义中文词库之前,我们先查一个示例,把结果留下,一会安装完自定义词库后作为对比:
安装前:
安装部署自定义词库:
重启es后重新再测试:(已经可以成功识别出新定义的词语)
第四节 关于mapping
type可以类比成table,MySQL在create table时会定义每个字段的字段类型约束;那es每个字段的数据类型也是可以定义的;实际上每个type中的字段是什么数据类型,由es的mapping定义。
【注意】:如果没有设定mapping,则系统会自动根据一条数据的格式来推断出应该的数据格式
4.4.1 查看type的mapping
常见的类型:
true/false → boolean
1020 → long
20.1 → double
“2018-02-01” → date
“hello world” → text + keyword
【注意】:
-
默认type只有text类型会进行分词,keyword是不会分词的字符串。
-
mapping除了自动定义,还可以手动定义,但是只能对新加的、没有数据的字段进行定义。一旦有了数据就无法再做修改了。
-
虽然每个Field的数据放在不同的type下,但是同一个名字的Field在一个index下只能有一种mapping定义。
4.4.2 基于中文文辞搭建索引
创建mapping
name -> 定义成text类型 使用ik中文分词ik_smart
执行结果:
创建完成后
PUT插入数据:
name:红海行动、湄公河行动、红海事件
测试查询效果:
查询电影名为红海战役的结果:
查询演员有张译的结果:
第五节 索引别名 _aliases
索引别名就像一个快捷方式或软连接,可以指向一个或多个索引,也可以给任何一个需要索引名的API来使用。别名 带给我们极大的灵活性,允许我们做下面这些:
1.给多个索引分组 (例如, last_three_months -> 可以指向多个)
2.给索引的一个子集创建视图
3.在运行的集群中可以无缝的从一个索引切换到另一个索引
4.5.1 创建索引别名
定义别名:
“aliases”: {
“movie_chn_2020-query”: {}
}
已存在的索引增加别名
也可以通过加过滤条件缩小查询范围,建立一个子集视图
4.5.2 查询别名
4.5.3 删除某个索引别名
4.5.4 为别名切换
4.5.5 查询别名列表
第六节 索引模板
Index Template 索引模板,是创建索引的模具,其中可以定义一系列规则来帮助我们构建符合特定业务需求的索引的 mappings 和 settings,通过使用 Index Template 可以让我们的索引具备可预知的一致性。
索引模板可以更方便的建立索引,例如当还没有建好索引的时候,es获取到第一条数据进来需要保存时,如果数据里的索引前缀可以匹配到索引模板的index pattern,则es会根据模板直接生成该索引
4.6.1 分割索引
分割索引就是根据时间间隔把一个业务索引切分成多个索引。
举例:
把order_info变成order_info_0801,order_info_0802,order_info_0803,…
这样做的好处有两个:
- 结构变化的灵活性:因为elasticsearch不允许对数据结构进行修改。但是实际使用中索引的结构和配置难免变化,那么只要对下一个间隔的索引进行修改,原来的索引位置原状。这样就有了一定的灵活性。
- 查询范围优化: 因为一般情况并不会查询全部时间周期的数据,那么通过切分索引,物理上减少了扫描数据的范围,也是对性能的优化。
4.6.2 创建索引模板
其中 “index_patterns”: [“movie_test*”], 的含义就是凡是往movie_test开头的索引写入数据时,例如向movie_test_001索引写入数据,如果索引movie_test_001不存在,那么es会根据movie_test模板自动建立索引。
shard数量设置:
在 “aliases” 中用{index}表示,获得真正的创建的索引名。
4.6.3 查询已有模板列表
4.6.4 查看某个模板详情
第一条数据进来需要保存时,如果数据里的索引前缀可以匹配到索引模板的index pattern,则es会根据模板直接生成该索引
4.6.1 分割索引
分割索引就是根据时间间隔把一个业务索引切分成多个索引。
举例:
把order_info变成order_info_0801,order_info_0802,order_info_0803,…
这样做的好处有两个:
- 结构变化的灵活性:因为elasticsearch不允许对数据结构进行修改。但是实际使用中索引的结构和配置难免变化,那么只要对下一个间隔的索引进行修改,原来的索引位置原状。这样就有了一定的灵活性。
- 查询范围优化: 因为一般情况并不会查询全部时间周期的数据,那么通过切分索引,物理上减少了扫描数据的范围,也是对性能的优化。
4.6.2 创建索引模板
其中 “index_patterns”: [“movie_test*”], 的含义就是凡是往movie_test开头的索引写入数据时,例如向movie_test_001索引写入数据,如果索引movie_test_001不存在,那么es会根据movie_test模板自动建立索引。
shard数量设置:
在 “aliases” 中用{index}表示,获得真正的创建的索引名。