文章目录
Elasticsearch简介
ES概述
- Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。
- Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。
- Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。
- 基于Lucene的分布式, 实时文档存储, 实时分析搜索引擎
ES架构
- Gateway
ES用来存储索引的文件系统,支持多种类型,包括Local FileSystem、Shared FileSystem等 - Distributed Lucene Directory
分布式的lucene框架 - ES的模块
- 索引模块(Index Module)
- 搜索模块(Search Module)
- 映射解析模块(Mapping)
- Discovery、Scripting和第三方插件
- Discovery是ES的节点发现模块,不同机器上的ES节点要组成集群需要进行消息通信,集群内部需要选举master节点,这些工作都是由Discovery模块完成。支持多种发现机制,如Zen、EC2、gce、Azure。
- Scripting用来支持在查询语句中插入javascript、python等脚本语言,scripting模块负责解析这些脚本,使用脚本语句性能稍低。ES也支持多种第三方插件。
- ES的传输模块和JMX
传输模块支持多种传输协议,如Thrift、memecached、http,默认使用http。JMX是Java的管理框架,用来管理ES应用 - RESTful API
ES提供给用户的接口,可以通过RESTful接口和ES集群进行交互
Elasticsearch安装(mac)
ES下载安装
ElasticSearch是使用java开发的,且本版本的es需要的jdk版本要是1.8以上,所以安装ElasticSearch 之 前保证JDK1.8+安装完毕,并正确的配置好JDK环境变量,否则启动ElasticSearch失败。
下载地址
解压压缩包进入bin文件里面启动 elasticsearch 直接启动即可 默认端口:9200
报错:exception during geoip databases updateorg.elasticsearch.ElasticsearchException: not all primary shards of [.geoip_databases] index are active
解决方式:修改config中elasticsearch.yml配置文件,添加如下三行配置
报错:received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/127.0.0.1:9200, remoteAddress=/127.0.0.1:59411}
解决方式:修改config中elasticsearch.yml配置文件,更改安全权限配置
启动成功后:访问http://127.0.0.1:9200 如下图 说明启动成功
kibana下载安装
Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索 引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理 解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch查 询动态。设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动 Elasticsearch索引监测。
下载地址
解压,进入config文件夹,修改配置文件
将es的地址,改为自己本机IP地址就ok,如果是服务器的话,改为服务器地址就好了。
进入bin目录,启动kibana;
打开网页,输入
http://localhost:5601
汉化
只需要在配置文件 kibana.yml 中加入
i18n.locale:"zh-CN"
Elasticsearch基础
集群Cluster
ElasticSearch 是一个分布式的搜索引擎,所以一般由多台物理机组成。而在这些机器上通过配置一个相同的cluster name,让其互相发现从而把自己组织成一个集群。
集群的健康状态,ES集群存在三种健康状态,单节点ES也可以算是一个集群。
- green(绿色):代表所有索引的主分片和副本均已分配且可用,集群是100%可用
- yellow(黄色):主分片已分配且全部主分片可用,但所有的副本不全部可用,可能是缺失,也有可能是某个索引的副本未被分配,可以通过move cancel allocate 命令所属的API进行分配或移动分片到指定节点,使用这里要注意主分片和其副本绝不能在同一节点。此时系统容错性和集群高可用被弱化。
- red(红色):所有的主分片不全部可用,这代表很有可能存在丢失数据的风险。如果只有一个单节点Elasticsearch那么属于一种yellow状态,因为没有副本。
节点Node
ElasticSearch 是以集群的方式运行的,而节点是组成ES集群的基本单位,所以每个 ElasticSearch 实例就是一个节点,每个物理机器上可以有多个节点,使用不同的端口和节点名称。
节点按主要功能可以分为三种:主节点(Master Node),协调节点(Coordianting Node)和数据节点(Data Node)。下面简单介绍下:
主节点:处理创建,删除索引等请求,维护集群状态信息。可以设置一个节点不承担主节点角色
协调节点:负责处理请求。默认情况下,每个节点都可以是协调节点。
数据节点:用来保存数据。可以设置一个节点不承担数据节点角色
索引
为了将数据添加到 Elasticsearch中,我们需要索引(index)——一个存储关联数据的地方,而实际上索引只是一个用来指向一个或多个分片(shards)的== 逻辑命名空间 (logical namespace)==。在ES中所有数据都存储于索引(index) 之上,但实际索引只是维护了与多个分片之间的联系,数据则是被路由到多个分片。例如一个索引有5个分片,则该索引将会有0,1,2,3,4,这五个分片 ,起指定每个文档数据存储在哪个分片是根据路由运算公式 ==has(_routing)%number_of_primary_shards ==指定,使数据均匀分布在集群当中。
物理设计 :节点和分片 如何工作
一个集群至少有一个节点,而一个节点就是一个elasricsearch进程,节点可以有多个索引默认的,如果 你创建索引,那么索引将会有个5个分片 ( primary shard ,又称主分片 ) 构成的,每一个主分片会有一个 副本 ( replica shard ,又称复制分片 )
类型
类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义称为映射,比如name映射为字符串类型。
文档
ElasticSearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,ElasticSearch,文档有几个重要属性:
- 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value
- 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
- 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在ElasticSearch中,对于字段是非常灵活的,有时候,我们可以忽略改字段,或者动态的添加一个新的字段
尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整型,因为ElasticSearch会保存字段和类型之间的映射及其他的设置,这种映射具体到每个映射的每种类型,这也是为什么在ElasticSearch中,类型有时候也称为映射类型。
分片和副本
分片分为:主分片(Primary shard)和副本分片(Replica shard):
- 主分片Primary shard:用于解决数据水平扩展的问题,通过主分片,可以将数据分布到集群内的所有节点之上,将一份索引数据划分为多小份的能力,允许水平分割和扩展容量。多个分片可以响应请求,提高性能和吞吐量。一个节点(Node)一般会管理多个分片,分片有两种,主分片和副本分片。
- 副本分片Replica shard:副本分片只是一个主分片的拷贝。 副本分片作为硬件故障时保护数据不丢失的冗余备份,从而提高整个集群的容错性,并为搜索和返回文档等读操作提供服务,且需要注意的是副本分片不能与主分片在同一个节点。。一般来说,Elasticsearch 会尽量把一个索引的不同分片存储在不同的主机上,分片的副本也尽可能存在不同的主机上,这样可以提高容错率,从而提高高可用性。
- 一个Index数据在物理上被分布在多个主分片中,每个主分片只存放部分数据,每个主分片可以有多个副本。
- 主分片的作用是对索引的扩容,使一个索引的容量可以突破单机的限制。
- 副本分片是对数据的保护,每个主分片对应一个或多个副本分片,当主分片所在节点宕机时,副本分片会被提升为对应的主分片使用。
- 一个主分片和它的副本分片,不会分配到同一个节点上。
- 一个分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。应用程序不会和它直接通信。
- 当索引创建完成的时候,主分片的数量就固定了,如果要修改需要重建索引,代价很高,如果要修改则需Reindex,但是复制分片的数量可以随时调整。
对比
elasticSearch是面向文档,关系型数据库 和 ElasticSearch 客观的对比!
Relational DB | ElasticSearch |
---|---|
数据库(database) | 索引(indices) |
表(tables) | types |
行(rows) | documents |
字段(columns) | fields |
elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)
物理设计:
elasticsearch 在后台把每个索引划分成多个分片,每分分片可以在集群中的不同服务器间迁移
逻辑设计:
一个索引类型中,包含多个文档,比如说文档1,文档2。
当我们索引一篇文档时,可以通过这样的一各 顺序找到 它: 索引 ▷ 类型 ▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。
注意:ID不必是整 数,实际上它是个字 符串。
倒排索引
倒排索引是实现“单词-文档矩阵”的一种具体存储形式,通过倒排索引,可以根据单词快速获取包含这个单词的文档列表
- 单词词典
单词词典是由文档集合中出现过的所有单词构成的字符串集合,单词词典内每条索引项记载单词本身的一些信息以及指向“倒排列表”的指针 - 倒排列表
- 倒排列表记载了出现过某个单词的所有文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项。根据倒排列表,即可获知哪些文档包含某个单词
- 文档频率信息(有多少个文档包含这个单词)
- 文档编号(哪个文档包含这个单词)
- 单词频率信息(这个单词在文档中的出现次数)
- 单词在文档出现的位置信息
- 倒排文件
倒排文件是存储倒排索引的物理文件
Elasticsearch基础操作
IK分词器
分词:即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词。
IK提供了两个分词算法:ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细 粒度划分!
- 下载ik分词器的包,Github地址 (注意版本对应)
- 下载后解压,并将目录拷贝到ElasticSearch根目录下的 plugins 目录中。
plugins目录下新建ik文件夹,将zip解压到ik文件夹下。
- 重新启动 ElasticSearch 服务,在启动过程中,你可以看到正在加载"analysis-ik"插件的提示信息。
- 在 kibana 中测试 ik 分词器,并就相关分词结果和 icu 分词器进行对比。 ik_max_word : 细粒度分词,会穷尽一个语句中所有分词可能,测试!
如果我们想让系统识别“哈尔滨工程大学”是一个词,需要编辑自定义词库。
步骤:- 进入elasticsearch/plugins/ik/config目录
- 新建一个my.dic文件,编辑内容:
哈尔滨工程大学
- 修改IKAnalyzer.cfg.xml(在ik/config目录下)
修改完配置重新启动elasticsearch,再次测试!<properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict">my.dic</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords"></entry> <!--用户可以在这里配置远程扩展字典 --> <!-- <entry key="remote_ext_dict">words_location</entry> --> <!--用户可以在这里配置远程扩展停止词字典--> <!-- <entry key="remote_ext_stopwords">words_location</entry> --> </properties>
基础测试
1、首先我们浏览器 http://localhost:5601/ 进入 kibana里的Console
2、首先让我们在 Console 中输入 :
// PUT 创建命令 test1 索引 _doc 类型 1 id
PUT /test1/_doc/1
{
"name":"ahtoh",
"age":18
}
返回结果 (是以REST ful 风格返回的 ):
{
"_index": "test1", // 索引
"_id": "1", // id
"_version": 2, // 版本
"result": "updated", // 操作类型
"_shards": { // 分片信息
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
3、name 字段指定类型!
- 字符串类型
text 、 keyword - 数值类型
long, integer, short, byte, double, float, half_float, scaled_float - 日期类型
date - 布尔值类型
boolean - 二进制类型
binary - 等等…
4、指定字段类型
PUT /test2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "long"
},
"birthday":{
"type": "date"
}
}
}
}
输出
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "test2"
}
5、查看索引字段
GET test2
输出
{
"test2": {
"aliases": {},
"mappings": {
"properties": {
"age": {
"type": "long"
},
"birthday": {
"type": "date"
},
"name": {
"type": "text"
}
}
},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"number_of_shards": "1",
"provided_name": "test2",
"creation_date": "1680940252599",
"number_of_replicas": "1",
"uuid": "_RDw3a3WRnK3je2FLVjuqQ",
"version": {
"created": "8050099"
}
}
}
}
}
没有给字段指定类型那么es就会默认给我配置字段类型!
6、查看elasticsearch 中的索引的情况
GET _cat/indices?v
查看输出
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open test2 _RDw3a3WRnK3je2FLVjuqQ 1 1 0 0 225b 225b
yellow open test1 tbLPjrz1QR-Fdj_e0ZVVIA 1 1 1 0 4.9kb 4.9kb
7、删除索引(库)
DELETE /test1
{
"acknowledged": true
}
增删改查
- 创建数据PUT
PUT /ahtoh/_doc/1
{
"name":"ahtoh",
"age":18,
"desc":"哈尔滨工程大学",
"tags":["直男","技术宅","温暖"]
}
{
"_index": "ahtoh",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
- 查询数据
通过 GET 命令查询
GET /ahtoh/_doc/1
{
"_index": "ahtoh",
"_id": "1",
"_version": 1,
"_seq_no": 0,
"_primary_term": 1,
"found": true,
"_source": {
"name": "ahtoh",
"age": 18,
"desc": "哈尔滨工程大学",
"tags": [
"直男",
"技术宅",
"温暖"
]
}
}
- 更新数据 POST
POST /ahtoh/_update/1
{
"doc":{
"name":"ahtoh",
"desc":"ahtoh每天都要加油呀"
}
}
{
"_index": "ahtoh",
"_id": "1",
"_version": 2,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
- 条件查询_search?q=
GET /ahtoh/_search?q=name:ahtoh
{
"took": 283,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "ahtoh",
"_id": "1",
"_score": 0.2876821,
"_source": {
"name": "ahtoh",
"age": 18,
"desc": "ahtoh每天都要加油呀",
"tags": [
"直男",
"技术宅",
"温暖"
]
}
}
]
}
}