# 文档

es 是面向文档的,文档是 es 中可搜索的最小单位, es 的文档由一个或多个字段组成,类似于关系型数据库中的一行记录,但 es 的文档是以 JSON 进行序列化并保存的,每个 JSON 对象由一个或多个字段组成,字段类型可以是布尔,数值,字符串、二进制、日期等数据类型。
es 每个文档都有唯一的 id , 这个 id 可以由我们自己指定,也可以由 es 自动生成。

es 每一个文档,除了保存我们写入进行的文档原始数据外,也有文档自己的元数据,这些元数据,用于标识文档的相关信息。

1
2
3
4
5
6
7
8
9
10
11
12
{
"_index" : "fxb_test",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"username" : "fxb"
}
}

从上面的文档中,我们可以看文档的元数据字段如下:

_index :文档所在索引名称
_source :原始 json 数据
_type :文档所属类型, es7.0 以后只有为 _doc
_version :文档版本,如果对文档进行修改,则该字段会增加
_score :相关性打分
id :文档唯一 id

# 索引

es 索引,是 es 组织文档的方式,是拥有相结构文档的集合,可以把 es 的索引类比为关系型数据库的一张数据表。
索引是 ES 中非常重要的一种数据结构。后面我们会着重的学习其原理。

比如,我们想创建一个索引,可以在 kibana 使用下面的命令:

1
2
# 创建索引
PUT /fxb_test

右侧就会输出:

1
2
3
4
5
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "fxb_test"
}

如图:

# Mapping

Mapping 是对 索引的定义。 类似的 MySQL 中表结构定义, ES 中支持手动定义 Mapping , 动态映射这两种方式。

比如,我们上面创建的 fxb_test 索引,就可以使用动态映射方式生成的 Mapping。

1
2
3
4
5
6
7
# 添加一个文档到 fxb_test 索引中
POST /fxb_test/_create/1
{
"username":"黄岛主",
"age":57,
"sex": "男"
}

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"_index" : "fxb_test",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}

然后,我们看下自动映射出来的 Mapping

1
2
# 查看索引的Mapping
GET /fxb_test

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"fxb_test" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"sex" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"username" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}

这里就先简单了解一下,相关的命令。 至于上面每个字段的含义以及作用,我们后面详细介绍。

# 集群

ES 的集群搭建很简单,不需要依赖第三方协调管理组件,自身内部就实现了集群的管理功能。 ES 集群由一个或多个 Elasticsearch 节点组成,每个节点配置相同的 cluster.name 即可加入集群,默认值为 “ elasticsearch ”。确保不同的环境中使用不同的集群名称,否则最终会导致节点加入错误的集群。

一个 Elasticsearch 服务启动实例就是一个节点( Node )。节点通过 node.name 来设置节点名称,如果不设置则在启动时给节点分配一个随机通用唯一标识符作为名称。

# 分片

ES 支持 PB 级全文搜索,当索引上的数据量太大的时候, ES 通过水平拆分的方式将一个索引上的数据拆分出来分配到不同的数据块上,拆分出来的数据库块称之为一个分片。

这类似于 MySQL 的分库分表,只不过 MySQL 分库分表需要借助第三方组件而 ES 内部自身实现了此功能。

在一个多分片的索引中写入数据时,通过路由来确定具体写入哪一个分片中,所以在创建索引的时候需要指定分片的数量,并且分片的数量一旦确定就不能修改。

分片的数量和下面介绍的副本数量都是可以通过创建索引时的 settings 来配置, ES 默认为一个索引创建 1 个主分片 ( ES 7.x ), 并分别为每个分片创建一个副本。

ES 通过分片的功能使得索引在规模上和性能上都得到提升,每个分片都是 Lucene 中的一个索引文件,每个分片必须有一个主分片和零到多个副本。

1
2
3
4
5
6
7
8
# 创建2个副本,5个分片的索引
PUT /fxb_test2
{
"settings": {
"number_of_replicas": 2,
"number_of_shards": 5
}
}

返回结果:

1
2
3
4
5
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "fxb_test2"
}

# 副本

副本就是对分片的 Copy ,每个主分片都有一个或多个副本分片,当主分片异常时,副本可以提供数据的查询等操作。主分片和对应的副本分片是不会在同一个节点上的,所以副本分片数的最大值是 n-1 (其中 n 为节点数)。

对文档的新建、索引和删除请求都是写操作,必须在主分片上面完成之后才能被复制到相关的副本分片, ES 为了提高写入的能力这个过程是并发写的,同时为了解决并发写的过程中数据冲突的问题, ES 通过乐观锁的方式控制,每个文档都有一个 _version (版本)号,当文档被修改时版本号递增。一旦所有的副本分片都报告写成功才会向协调节点报告成功,协调节点向客户端报告成功。

关于, ES 的基本概念,就介绍到这里。
下一篇: 《 ES 索引管理》

# 最后

期望与你一起遇见更好的自己

期望与你一起遇见更好的自己

更新于 阅读次数

请我喝[咖啡]~( ̄▽ ̄)~*

方小白 微信支付

微信支付

方小白 支付宝

支付宝

方小白 numberpay

numberpay