ElasticSearch 7 学习记录(一) ----安装es与kibana及基础概念简介
文章目录
1. 安装
1. 安装步骤
基于docker进行构建,但相关docker指令也不是很熟悉,参阅相关博客进行实践,在此做记录。
1. 镜像下载
docker pull elasticsearch:7.3.2
docker pull kibana:7.3.2
2. es单节点启动
docker run --name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
elasticsearch:7.3.2
3. kibana启动
docker run -p 5601:5601 --name kibana --link elasticsearch:elasticsearch docker.io/kibana:7.3.2
4. es启动验证
1. es启动验证
curl -XGET localhost:9200/_cat
2. kibana启动验证
5. 分词器安装
1. ik分词器未安装之前:
对于文本使用默认分词器 :
GET /_analyze?
{
"text":"你听过一个关于小熊的故事吗",
"analyzer":"standard"
}
{
"tokens" : [
{
"token" : "你",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "听",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "过",
"start_offset" : 2,
"end_offset" : 3,
"type" : "<IDEOGRAPHIC>",
"position" : 2
},
{
"token" : "一",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 3
},
{
"token" : "个",
"start_offset" : 4,
"end_offset" : 5,
"type" : "<IDEOGRAPHIC>",
"position" : 4
},
{
"token" : "关",
"start_offset" : 5,
"end_offset" : 6,
"type" : "<IDEOGRAPHIC>",
"position" : 5
},
{
"token" : "于",
"start_offset" : 6,
"end_offset" : 7,
"type" : "<IDEOGRAPHIC>",
"position" : 6
},
{
"token" : "小",
"start_offset" : 7,
"end_offset" : 8,
"type" : "<IDEOGRAPHIC>",
"position" : 7
},
{
"token" : "熊",
"start_offset" : 8,
"end_offset" : 9,
"type" : "<IDEOGRAPHIC>",
"position" : 8
},
{
"token" : "的",
"start_offset" : 9,
"end_offset" : 10,
"type" : "<IDEOGRAPHIC>",
"position" : 9
},
{
"token" : "故",
"start_offset" : 10,
"end_offset" : 11,
"type" : "<IDEOGRAPHIC>",
"position" : 10
},
{
"token" : "事",
"start_offset" : 11,
"end_offset" : 12,
"type" : "<IDEOGRAPHIC>",
"position" : 11
},
{
"token" : "吗",
"start_offset" : 12,
"end_offset" : 13,
"type" : "<IDEOGRAPHIC>",
"position" : 12
}
]
}
可以看到使用默认的分词器,无法分词至逻辑词条。
2. 安装IK分词器:
docker exec -it elasticsearch /bin/bash
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.3.2/elasticsearch-analysis-ik-7.3.2.zip
3.拼音分词与上面步骤相同 : ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v7.3.2/elasticsearch-analysis-pinyin-7.3.2.zip
安装完成之后,需要对es进行重启
- docker restart elasticsearch
- docker start elasticsearch
验证IK分词器安装:
GET /_analyze?
{
"text":"你听过一个关于小熊的故事吗",
"analyzer":"ik_smart"
}
{
"tokens" : [
{
"token" : "你",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "听过",
"start_offset" : 1,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "一个",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "关于",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "小熊",
"start_offset" : 7,
"end_offset" : 9,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "的",
"start_offset" : 9,
"end_offset" : 10,
"type" : "CN_CHAR",
"position" : 5
},
{
"token" : "故事",
"start_offset" : 10,
"end_offset" : 12,
"type" : "CN_WORD",
"position" : 6
},
{
"token" : "吗",
"start_offset" : 12,
"end_offset" : 13,
"type" : "CN_CHAR",
"position" : 7
}
]
}
可以看到已经具备中文语义上的分词了。
2. ElasticeSearch 基本概念介绍
引言
数据分类:
从我的工作经验而讲,在日常工作中,数据大多存储在mysql这样的关系型数据库中。
使用二维表结构来维护数据关系,并且会严格的告知它数据格式与长度。再基于关联做多数据的关系维护,这样的数据我们称之为结构化数据
。
除此之外,对不不定长、无固定格式,不适合用二维表表现的数据我们称之为非结构化数据,如XML、HTML、word文档,邮件,各类报表、图片和咅频、视频信息。它还有个称呼,叫做 全文数据
。
搜索方式:
根据两种数据分类,搜索也相应的分为两种:结构化数据搜索
和非结构化数据搜索
。
对于
结构化数据
,因为它们具有特定的结构,所以我们一般都是可以通过关系型数据库(mysql,oracle等)的 二维表(table)的方式存储和搜索,也可以建立索引。
对于
非结构化数据
,也即对全文数据的搜索主要有两种方法:顺序扫描法
,全文检索
。
顺序扫描
:通过文字名称也可了解到它的大概搜索方式,即按照顺序扫描的方式查询特定的关键字。例如给你一张报纸,让你找到该报纸中“平安”的文字在哪些地方出现过。你肯定需要从头到尾把报纸阅读扫描一遍然后标记出关键字在哪些版块出现过以及它的出现位置。
这种方式无疑是最耗时的最低效的,如果报纸排版字体小,而且版块较多甚至有多份报纸,等你扫描完你的眼睛也差不多了。
全文搜索
:对非结构化数据顺序扫描很慢,我们是否可以进行优化?把我们的非结构化数据想办法弄得有一定结构不就行了吗?将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。
这种方式就构成了全文检索的基本思路。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引
。这种方式的主要工作量在前期索引的创建,但是对于后期搜索却是快速高效的。
Lucene
Lucene 能实现全文搜索主要是因为它实现了倒排索引
的查询结构,es以此为基础能力。
呢么什么是``倒排索引``呢?
假如现有三份数据文档,文档的内容如下分别是:
doc1: Java is the best programming language.
doc2: PHP is the best programming language.
doc3: Javascript is the best programming language.
为了创建倒排索引,我们通过分词器将每个文档的内容域拆分成单独的词(我们称它为词条
或 Term
),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。结果如下所示:
Term | DOC_1 | DOC_2 | DOC_3 |
---|---|---|---|
JAVA | X | ||
is | X | X | X |
the | X | X | X |
best | X | X | X |
programming | x | X | x |
language | X | X | X |
PHP | X | ||
Javascript | X |
这种结构由文档中所有不重复词的列表构成,对于其中每个词都有一个文档列表与之关联。这种由属性值来确定记录的位置的结构就是倒排索引
。带有倒排索引的文件我们称为倒排文件
。
相关名词解释
索引(index)
一个索引就是一个拥有几分相似特征的文档的集合。
比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。
一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。
索引类似于关系型数据库中Database 的概念。
类型(type)
在一个索引中,你可以定义一种或多种类型。
一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。
通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。
在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。
类型类似于关系型数据库中Table的概念。
NOTE: 在5.x版本以前可以在一个索引中定义多个类型,6.x之后版本也可以使用,但是不推荐,在7~8.x版本中彻底移除一个索引中创建多个类型,我们目前使用的是7.X的版本
映射(Mapping)
Mapping是ES中的一个很重要的内容,它类似于传统关系型数据中table的schema,用于定义一个索引(index)中的类型(type)的数据的结构。
在ES中,我们可以手动创建type(相当于table)和mapping(相关与schema),也可以采用默认创建方式。
在默认配置下,ES可以根据插入的数据自动地创建type及其mapping。
mapping中主要包括字段名、字段数据类型和字段索引类型
对字段类型根据数据格式自动识别的映射称之为动态映射(Dynamic mapping),我们创建索引时具体定义字段类型的映射称之为静态映射或显示映射(Explicit mapping)。
常见的数据类型有如下几种:
l类别 | 数据类型 |
---|---|
核心类型 | text, keywords, long, integer, short, double, data, boolean等等 |
复杂类型 | Object, Nested |
地理类型 | geo_point, geo_shape |
特殊类型 | ip, completion, token_count, join等等 |
… |
text
用于索引全文值的字段,例如电子邮件正文或产品说明。这些字段是被分词的,它们通过分词器传递 ,以在被索引之前将字符串转换为单个术语的列表。分析过程允许Elasticsearch搜索单个单词中每个完整的文本字段。文本字段不用于排序,很少用于聚合。
keyword
用于索引结构化内容的字段,例如电子邮件地址,主机名,状态代码,邮政编码或标签。它们通常用于过滤,排序,和聚合。keyword字段只能按其确切值进行搜索。
通过对字段类型的了解我们知道有些字段需要明确定义的,例如某个字段是text类型还是keword类型差别是很大的,时间字段也许我们需要指定它的时间格式,还有一些字段我们需要指定特定的分词器等等。如果采用动态映射是不能精确做到这些的,自动识别常常会与我们期望的有些差异。
文档(document)
一个文档是一个可被索引的基础信息单元,类似于表中的一条记录。
比如,你可以拥有某一个员工的文档,也可以拥有某个商品的一个文档。
文档以采用了轻量级的数据交换格式JSON(Javascript Object Notation)来表示。
- 文档可以自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key::value
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的。
- 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在es中,我们可以做动态新增。
ES是什么
一些基础知识的铺垫之后我们正式进入今天的主角Elasticsearch的介绍, ES是使用Java编写的一种开源搜索引擎,它在内部使用Lucene做索引与搜索,通过对Lucene的封装,隐藏了Lucene的复杂性,取而代之的提供一套简单一致的 RESTful API。
然而,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确的形容:
- 一个分布式的实时文档存储,每个字段可以被索引与搜索。
- 一个分布式实时分析搜索引擎。
- 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
官网对Elasticsearch的介绍是Elasticsearch 是一个分布式
、可扩展
、近实时
的搜索与数据分析引擎。
近实时
:从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒内) ,这是由于ES写数据的机制决定的。
为了提升写的性能,ES并没有每新增一条数据就增加一个段到磁盘上,而是
采用延迟写
的策略。
每当有新增的数据时,就将其先写入到内存中,在内存和磁盘之间是文件系统缓存,当达到默认的时间(1秒钟)或者内存的数据达到一定量时,会触发一次刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件缓存系统 上,稍后再被刷新到磁盘中并生成提交点。
es中的集群、集群发现机制、节点角色、脑裂、分片、段等概念,我们在熟悉过一轮API后逐步进行整理。