ElasticSearch学习记录(二)——核心篇

ElasticSearch学习记录(二)——核心篇

对应课程

【尚硅谷】ElasticSearch教程入门到精通

概念与术语

索引(Index):指拥有相似特征文档的集合。一个索引由一个名字来标识,比如:客户数据索引,订单数据索引,产品目录索引等。它对应于MySQL数据库的Table

文档(Doc):是一个可被索引的基础信息单元,也就是一条数据。如一个客户的数据索引包含许多的客户文档,而一个客户的信息对应一个客户文档。类似的,一个特定的产品对应一个产品文档,一个订单对应一个订单文档等。文档以JSON格式来表示,而JSON是一个到处存在的互联网数据交互格式。它对应于MySQL数据库的Row

字段(Field):就是JSON中的字段,对应于MySQL的Column,它对文档数据根据不同属性进行的分类标识。

映射(Mapping):是对处理数据的方式和规则做出的约束,对应于MySQL的表结构Schema。它指明了某个字段的数据类型、默认值、分析器、是否被索引等等。

节点(Node):一个运行中的es实例称作一个节点。

集群(Cluster):包含一个或多个启动的es实例的机器群。通常一台机器起一个es实例。同一网络下,集群名(cluster.name)一样的多个es实例自动组成集群,自动均衡分片等行为。

分片(Shards):一个索引可以存储超出单个节点硬件限制的大量数据。当一个索引所包含的文档数据过大时,需要将里面的数据分为多个shard,分布式地存储在各个服务器上面。另外,每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。

分片的意义:可以扩展内容的容量;可以在分片上进行分布式、并行地操作,提高了吞吐量。

副本(Replicas):作为分片的一份或多份拷贝,用于应对节点故障。副本可以应对失败情况,提供高可用性;另外,它也可以扩展吞吐量,因为搜索可以在所有的副本上并行运行。

分配(Allocation):将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。这个过程是由master节点完成的。

分布式架构

部署集群

1、创建一个文件夹"es-cluster"表示集群,复制三个elasticsearch服务。

结构

2、清空各个节点data文件夹下的数据,和log文件夹下的日志。

3、在config/elasticsearch.yml中,配置各个节点的参数,如下所示。

#节点 1 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-cluster
#节点名称,集群内要唯一
node.name: node-1001
#是不是有资格主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 3
#访问的IP地址
network.host: localhost
#http 端口
http.port: 1001
#tcp 监听端口
transport.tcp.port: 9301
#能够查询到的结点
#discovery.seed_hosts: ["localhost:9301", "localhost:9302", "localhost:9303"]
#discovery.zen.fd.ping_timeout: 1 m
#discovery.zen.fd.ping_retries: 5
#初始化一个新的集群时需要此配置来选举master
#cluster.initial_master_nodes: ["node-1001","node-1002","node-1003"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"


xpack.ml.enabled: false
#节点 2 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-cluster
#节点名称,集群内要唯一
node.name: node-1002
#是不是有资格主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 3
#访问的IP地址
network.host: localhost
#http 端口
http.port: 1002
#tcp 内部节点之间沟通端口
transport.tcp.port: 9302
#能够查询到的结点
discovery.seed_hosts: ["localhost:9301"]
discovery.zen.fd.ping_timeout: 1 m
discovery.zen.fd.ping_retries: 5
#初始化一个新的集群时需要此配置来选举master
#cluster.initial_master_nodes: ["node-1001","node-1002","node-1003"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

xpack.ml.enabled: false
#节点 3 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-cluster
#节点名称,集群内要唯一
node.name: node-1003
#是不是有资格主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 3
#访问的IP地址
network.host: localhost
#http 端口
http.port: 1003
#tcp 内部节点之间沟通端口
transport.tcp.port: 9303
#能够查询到的结点
discovery.seed_hosts: ["localhost:9301", "localhost:9302"]
discovery.zen.fd.ping_timeout: 1 m
discovery.zen.fd.ping_retries: 5
#初始化一个新的集群时需要此配置来选举master
#cluster.initial_master_nodes: ["node-1001","node-1002","node-1003"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

xpack.ml.enabled: false

4、分别双击bin/elasticsearch.bat,启动节点服务器,三个节点会根据配置加入集群。

5、创造一个索引users,并配置它的分片数为3,每个分片各有2个副本。

http://localhost:1001/users
{
	"settings":{
        "number_of_shards":3,
        "number_of_replicas":2
    }
}

单节点集群

仅仅启动node-1001一个es实例,构成一个单节点集群。通过elasticsearch-head插件查看集群的情况。

单节点

三个主分片都位于node-1001上,且是正常运行的,而这是存在丢失数据的风险的。从右上角集群健康值为黄色,说明副本分片没有处于正常状态,是失效的。注:还有一个索引".geoip_databases"拥有一个分片。

集群健康状态

绿色:代表所有的主分片和副本分片都可用;

黄色:所有的主分片可用,但是部分副本分片不可用;

红色:部分主分片不可用。

故障处理

当增加成3个节点的时候,集群就变成了健康的状态

集群

若此时,node-1001宕机了,则:

故障

由于,副本的存在,故而保障了索引"users"中数据的完整性。此时"node-1003"接替1001,成为了新的主机。删除"data"后,重新配置"node-1001",使它能够和另外两个节点通信,重新找到集群。

为它的配置文件添加:

#启动时能够查询到的结点
discovery.seed_hosts: ["localhost:9302", "localhost:9303"]
discovery.zen.fd.ping_timeout: 1 m
discovery.zen.fd.ping_retries: 5

重新启动"node-1001",然后刷新elasticsearch-head,得到:

恢复

与之前相比,数据没有丢失,且消除了故障,集群恢复了正常。

路由计算

当索引一个文档的时候,文档会被存储到一个主分片中。Elasticsearch需要通过一种方式,得知文档应该放在哪一个分片之中。它由以下规则决定:
shard = hash ( routing ) % number-of-shards \text{shard} = \text{hash}(\text{routing}) \% \text{number-of-shards} shard=hash(routing)%number-of-shards
其中,routing默认情况下是文档的_id。

分片控制与原理

一般情况下,相同的分片或副本不会放置在相同的结点下。任意一个结点都有能力处理任意的请求,且知道请求的文档所在的分片是哪个,所以可以直接将请求转发到需要的节点上。担任转发任务的节点,称作协调节点。当发送请求的时候, 为了扩展负载,更好的做法是轮询集群中所有的节点。

读写过程

ES数据写过程:

  1. 客户端请求集群中的任意节点;
  2. 协调节点将请求转发至指定节点,找到主分片;
  3. 主分片保存数据;
  4. 主分片将数据发送给副本;
  5. 副本保存后进行反馈;
  6. 主分片反馈给客户端。

ES数据读过程:

  1. 客户端发送请求至协调节点;
  2. 协调节点计算数据所在分片及其副本位置;
  3. 为了能够负载均衡,可以轮询所有节点;
  4. 将请求转发给具体的节点;
  5. 节点返回查询结果,将结果反馈给客户端。

倒排索引

Elasticsearch使用了一种称作倒排索引的结构,适用于快速全文搜索。

例如,有两个文档:

  • The quick brown fox jumped over the lazy dog
  • Quick brown foxes leap over lazy dogs in summer

需要对两个文档进行分词标准化处理,所谓标准化处理,包括大写转小写,词干提取,同义词转换等。

然后,创建索引:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CbpJbiYD-1658729920566)(.\img\倒排索引.jpg)]

相比于正向索引(文档id为key,内容为value),倒排索引能够实时返回包含“搜索关键字”的doc的id,更适合全文检索。

动态更新索引

早期的全文检索会为整个文档集合建立一个很大的倒排索引并将其写入到磁盘。你不能修改它。如果需要让一个新的文档可被搜索,需要重建整个索引。这要么对一个索引所能包含的数据量造成了很大的限制,要么对索引可被更新的频率造成了很大的限制。

为了在保证文档大部分不变的前提下,实现倒排索引的更新,需要使用更多的索引。通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引。每一个倒排索引都会被轮流查询到,从最早的开始查询完后再对结果进行合并。Elasticsearch基于 Lucene, 这个 java 库引入了按段搜索的概念。 每一段本身都是一个倒排索引,但索引在 Lucene 中除表示所有段的集合外,还增加了提交点的概念,即一个列出了所有已知段的文件。

按段搜索的执行流程如下:

  1. 新文档被收集到内存索引的缓存中;
按段搜索1
  1. 不时地,缓存被提交,包括:一个新的段(追加的倒排索引)和一个包含新段名字的提交点被写入磁盘;

  2. 新的段被开启,让它包含的文档可见以被搜索;

  3. 内存缓存被清空,等待接收新的文档。

按段搜索1

当一个查询被触发,所有已知的段按顺序被查询。词项统计会对所有段的结果进行聚合,以保证每个词和每个文档的关联都被准确计算。 这种方式可以用相对较低的成本将新文档添加到索引。

另外,段是不可改变的,段是不可改变的,所以既不能从把文档从旧的段中移除,也不能修改旧的段来进行反映文档的更新。取而代之的是,每个提交点会包含一个 .del 文件,文件中会列出这些被删除文档的段信息,这被称为“逻辑删除”。一个逻辑删除的文档仍然可以被查询匹配到,但它会在最终结果被返回前从结果集中移除。文档更新则是新的版本被索引到一个新的段中,而旧版本的文档则逻辑删除了。

ES与MySQL的对比

1、从事务上讲,MySQL能够处理事务,确保数据的ACID,而ES没有事务的概念。因此,处理订单和支付等带有事务要求的操作,需要选择MySQL数据库。

2、MySQL属于关系型数据库的范畴,适合于结构化的数据存储(数据之间存在强的关系型),而ES是非关系型数据库,能够实现搜索的秒级响应,适用于全文检索。

3、ES属于分布式架构,很容易实现横向扩容,因而更适合海量数据检索;

4、ES的检索可以覆盖全字段,即查询者只需提供关键字,而无需知道具体的字段;

5、ES会对输入的文本进行分词和标准化处理,这有助于提升检索的效率。而MySQL一旦分词,进行模糊查询,就会使索引失效,进而全表检索,这是低效的。
此,处理订单和支付等带有事务要求的操作,需要选择MySQL数据库。

2、MySQL属于关系型数据库的范畴,适合于结构化的数据存储(数据之间存在强的关系型),而ES是非关系型数据库,能够实现搜索的秒级响应,适用于全文检索。

3、ES属于分布式架构,很容易实现横向扩容,因而更适合海量数据检索;

4、ES的检索可以覆盖全字段,即查询者只需提供关键字,而无需知道具体的字段;

5、ES会对输入的文本进行分词和标准化处理,这有助于提升检索的效率。而MySQL一旦分词,进行模糊查询,就会使索引失效,进而全表检索,这是低效的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大灰煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值