【架构师面试-搜索-2】-ElasticSearch集群shard与replicas机制

1 为什么分片

在分布式系统中,单机无法存储规模巨大的数据,要依靠大规模集群处理和存储这些数据,一般通过增加机器数量来提高系统水平扩展能力。因此,需要将数据分成若干小块分配到各个机器上。然后通过某种路由策略找到某个数据块所在的位置。

【架构师面试-搜索-2】-ElasticSearch集群shard与replicas机制

2 为什么做副本

Redis主从复制,MySQL主从复制

1TB -> 2TB

除了将数据分片以提高水平扩展能力,分布式存储中还会把数据复制成多个副本,放置到不同的机器中,这样一来可以增加系统可用性,同时数据副本还可以使读操作并发执行,分担集群压力。

副本带来的弊病:数据的一致性问题!

但是多数据副本也带来了一致性的问题:部分副本写成功,部分副本写失败。

为了应对并发更新问题,ES将数据副本分为主从两部分,即主分片(primary shard)和副分片

(replica shard)。

主数据作为权威数据,写过程中先写主分片,成功后再写副分片,恢复阶段以主分片为准。

3 索引与分片的基本结构

【架构师面试-搜索-2】-ElasticSearch集群shard与replicas机制

分片(shard)是底层的基本读写单元。分片是数据容器,文档保存在分片内,不会跨分片存储分片的目的是分割巨大索引: 

让读写可以并行操作,由多台机器共同完成,读写请求最终落到某个分片上,分片独立执行读写操作ES利用分片将数据分散到集群内各处

当集群规模扩大或缩小时:ES 会自动在各节点中迁移分片,使数据仍然均匀分布在集群里

4 索引基本构成

【架构师面试-搜索-2】-ElasticSearch集群shard与replicas机制

一个ES的index包含很多分片,一个分片是一个Lucene的索引,它本身就是一个完整的搜索引擎,可以独立执行建立索引和搜索任务。

Lucene索引又由很多分段组成,每个分段都是一个倒排索引。

ES每次“refresh”都会生成一个新的分段,其中包含若干文档的数据。

在每个分段内部,文档的不同字段被单独建立索引。

每个字段的值由若干词(Term)组成,Term是原文本内容经过分词器处理和语言处理后的最终结果(例如,去除标点符号和转换为词根)。

Lucene分段文件组成详解:http://lucene.apache.org/core/7_3_0/core/org/apache/lucene/codecs/lucene70/package-summary.html#package.description。

5 分片应该怎么分

索引建立的时候就需要确定好主分片数。

单个分片大小不要超过30GB【上限】,分片数量最好不要太多。决定分片大小的更多是基于硬件和业务场景的预估数据量和增量情况。

5.x 版本之前:主分片数量不可以修改,副分片数可以随时修改。

5.x 版本之后:支持在一定条件的限制下,对某个索引的主分片进行拆分(Split)或缩小(Shrink)。主分片数量最好是提前估算好,后期调整容易出现严重后果。

分片数不够时,可以考虑新建索引:搜索1个有着50个分片的索引与搜索50个每个都有1个分片的索引完全等价也可以使用_split API来拆分索引(6.1版本开始支持)。

6 索引巨大怎么办

虽说单个分片可以达到30GB,但在实际应用中,我们不应该向单个索引持续写数据,直到它的分片巨大无比。

巨大的索引的问题:数据老化后难以删除以id 为单位删除文档不会立刻释放空间,删除的 doc 只在 Lucene分段合并时才会真正从磁盘中删除

即使手工触发分段合并,仍然会引起较高的 I/O 压力,并且可能因为分段巨大导致在合并过程中磁盘空间不足一个小小的建议:周期性地创建新索引。

例如,每天创建一个。假如有一个索引ITxiongge_shop,可以将它命名为ITxiongge_shop_20211031。

然后创建一个名为ITxiongge_shop的索引别名来关联这些索引。

这样,对于业务方来说,读取时使用的名称不变,当需要删除数据的时候,可以直接删除整个索引。

索引别名就像一个快捷方式或软链接,不同的是它可以指向一个或多个索引。可以用于实现索引分组,或者索引间的无缝切换。

7 分片数量过多怎么办

现在我们已经确定好了主分片数量,并且保证单个索引的数据量不会太大,周期性创建新索引带来的一个新问题是集群整体分片数量较多,集群管理的总分片数越多压力就越大。

在每天生成一个新索引的场景中,可能某天产生的数据量很小,实际上不需要这么多分片,甚至一个就够。这时,可以使用shrink index API来缩减主分片数量,降低集群负载。

如果您觉得文章好看,欢迎点赞收藏加关注,一连三击呀,感谢!!☺☻ 

上一篇:MongoDB 备份与还原 mongodump、mongorestore


下一篇:分布式数据层中间件详解:如何实现分库分表+动态数据源+读写分离