ElasticSearch 设计的理念是分布式搜索引擎,底层其实是基于 lucene 的。核心思想是在多台机器上启动多个 ES 进程实例,组成了一个 ES 集群。
ES 中存储数据的基本单位是索引,例如在 ES 中存储一些订单数据,在 ES 中创建一个索引 order_idx
,所有的订单数据写到这个索引里面,一个索引相当于 mysql 里的一张表。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n11" mdtype="fences" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none; box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-size: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); border: 1px solid rgb(231, 234, 237); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; position: relative !important;">index -> type -> mapping -> document -> field。</pre>
在这里做个类比。但是切记,不要划等号,类比只是为了便于理解。
index 相当于 mysql 里的一张表。
type 没法跟 mysql 里去对比,一个 index 里可以有多个 type,每个 type 的字段都是差不多的,有一些略微的差别。
假设有一个 订单 index,里面专门是放订单数据的。
在 mysql 中建表,有些订单是实物商品的订单,一件衣服、一双鞋子;有些订单是虚拟商品的订单,游戏点卡,话费充值。两种订单大部分字段是一样的,少部分字段可能有略微的一些差别。
所以就会在订单 index 里,建两个 type,一个是实物商品订单 type,一个是虚拟商品订单 type,这两个 type 大部分字段是一样的,少部分字段是不一样的。
很多情况下,一个 index 一个 type,如果一个 index 里有多个 type 的情况(注意, mapping types
这个概念在 ElasticSearch 7. X 已被完全移除,详细说明可以参考官方文档),可以认为 index 是一个类别的表,具体的每个 type 代表了 mysql 中的一个表。每个 type 有一个 mapping,如果认为一个 type 是具体的一个表,index 就代表多个 type 同属于的一个类型,而 mapping 就是这个 type 的表结构定义,在 mysql 中创建一个表,定义表结构,里面有哪些字段,每个字段是什么类型。 index 里的一个 type 里面写的一条数据,叫做一条 document,一条 document 就代表了 mysql 中某个表里的一行,每个 document 有多个 field,每个 field 就代表了这个 document 中的一个字段的值。
[图片上传失败...(image-60962f-1620436742522)]
一个索引可以拆分成多个 shard
,每个 shard 存储部分数据。拆分多个 shard 是有好处的,一是支持横向扩展,例如数据量是 3T,3 个 shard,每个 shard 就 1T 的数据,现在数据量增加到 4T,建一个有 4 个 shard 的索引,将数据导进去;二是提高性能,数据分布在多个 shard,即多台服务器上,所有的操作会在多台机器上并行分布式执行,提高了吞吐量和性能。
这个 shard 的数据实际是有多个备份,每个 shard 都有一个 primary shard
,负责写入数据,有几个 replica shard
。 primary shard
写入数据之后,会将数据同步到其他几个 replica shard
上。
[图片上传失败...(image-7d5383-1620436742521)]
通过这个 replica 的方案,每个 shard 的数据有多个备份,如果某个机器宕机了,有数据副本在其他机器上。
ES 集群多个节点,会自动选举一个节点为 master 节点,这个 master 节点做一些管理的工作的,例如维护索引元数据、负责切换 primary shard 和 replica shard 身份等。如果 master 节点宕机了,会重新选举一个节点为 master 节点。
如果是非 master 节点宕机了,那么会由 master 节点,让宕机节点上的 primary shard 的身份转移到其他机器上的 replica shard。如果修复了宕机机器,重启了之后,master 节点会将缺失的 replica shard 分配过去,同步后续修改的数据之类的,让集群恢复正常。
如果某个非 master 节点宕机了。那么此节点上的 primary shard 挂了。master 会让 primary shard 对应的 replica shard(在其他机器上)切换为 primary shard。如果宕机的机器修复了,修复后的节点也不再是 primary shard,而是 replica shard。
网友评论