1.1 解析ES的分布架构
1.1.1 分布式架构的透明隐藏特性(Elasticsearch 集群分配多少分片合理)
ElasticSearch是一个分布式架构,隐藏了复杂的处理机制
分片机制(shard):我们不用关心数据是按照什么机制分片的,最后放入哪个分片中
分片的副本(replica):任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器
集群发现机制(cluster discovery):当前启动了一个es进程,当启动了第二个es进程时,这个进程作为一个node自动就发现了集群,并加入进去
shard负载均衡:比如现在有10shard,集群中有3个节点,es会均衡的进行分配,以保持每个节点均衡的负载请求
请求路由:!!es路由原理 在es中,一个index会被分片,一个index中存在很多document,这个document存放在不同的shard ,而一个document只能存在于一个primary shard中,这样,当客户端创建一个document并存入es时,es内部就需要决定这个document存于那一个primary shard,这就是es中的document 路由分发
1.1.2 扩容机制
垂直扩容:购置新的机器,替换已有的机器
水平扩容:直接增加机器
rebalance:增加或减少节点时会自动均衡
master节点:主节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关的节点。稳定的主节点对集群的健康是非常重要的。
节点对等:每个节点都能接受请求,每个节点接受请求后都能把该请求的路由到有关数据的其他节点上,接收原始请求的节点负责采集数据并返回给客户端
1.2 分片和副本机制
- index包含有多个shard
- 每个shard都是一个最小工作单元,承载部门数据;每个shard都是一个lucene实例,有完整的建立索引和处理请求的能力
- 增减节点时,shard会自动在nodes中负载均衡
- primary shard和replica shard,每个document肯定只存在某一个primary shard以及其对应的replica shard中,不可能存在多个primary shard
- replica shard是primary shard的副本,负责容错,以及承担读请求负载
- primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改(因为在保存文档的时候是根据路由Id进行hash算法确定这个文档保存在哪个主分片下,若主分片数量修改,那么同样的路由Id进行读取此文档,经过hash算法之后确定了此文档所在分片的位置,但此时分片的位置显然不是原档存入的位置,所以会造成数据缺失,查找不到数据)
- (创建索引时若不指定)primary shard的默认数量是5,replica是1,即默认有10个shard,5个primary shard,5个replica shard
- primary shard不能和自己的replica shard放在一个同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上
1.3 单节点环境下创建索引分析
# 创建myindex索引 指定主节点3个 副本节点一个(每个主节点下均有一个副本节点)
PUT myindex
{
"settings": {"number_of_shards": 3, "number_of_replicas": 1}
}
按上面设置进行创建索引时,只会将3个primary shard分配到仅有一个的node上,另外三个replica shard是无法分配的(一个shard的副本replica是不能在同一个节点的)。集群可以正常工作,但一旦出现节点宕机,数据全部丢失,而且集群不可用,无法接受任何请求
# 查看集群健康 显示为yellow(因为无法安置设置的副本节点) 但还是能进行正常的存储和读取
GET _cat/health
1.4 两个节点环境下创建索引分析
将3个primary shard分配到一个node上,另外三个replica shard分配到另一个节点上
primary shard和replica shard保持同步
primary shard和replica shard都可以处理客户端的请求
1.5 水平扩容的过程
- 扩容后primary shard和replica shard会自动的负载均衡
- 扩容后每个节点上的shard会减少,那么分配给每个shard的cpu、内存、IO资源会更多,性能提高
- 扩容的极限,如果有6个shard,扩容的极限就是6个节点,每个节点上一个shard,如果想超出扩容的极限,比如说扩容到9个节点,那么可以增加replica shard的个数
- 6个shard,3个节点,最多能承受几个节点所在的服务器宕机?(容错性) 3个节点,6个shard,最多能接受1台服务器宕机
提高容错性?接受的宕机的台数越多,容错性越好
提高容错性:增加shard的个数(增加shard的个数可以让每个节点下有更多的shard,增加到足够多的数量可以满足一个节点包含所有的数据,那么只要有一个节点在,服务就能正常进行,一般来说,shard总数量 = 节点个数 * 主shard个数) 比如现在有3个primary shard,3个node,为了达到最大容错率,需要增加6个replica shard,这样就能容忍最多两台服务器宕机
总结:扩容是为了提高系统的吞吐量,同时也要考虑容错性,也就是让尽可能多的服务器宕机还能保证数据不丢失
1.6 ES的容错机制
以9个shard,3个节点为例:
如果master node宕机,此时不是所有的primary shard都是Active status,所以此时的集群状态是red。
- 容错处理的第一步:选举一台服务器作为master
- 容错处理的第二部:新选举出的master会把挂掉的primary shard的某个replica shard提升为primary shard,此时集群的状态为yellow,因为少了一个replica shard,并不是所有的replica shard都是Active status
- 容错处理的第三步:重启故障机,新master会把所有的副本都复制一份到该节点上,(同步一下宕机后发生的修改),此时集群的状态为green,因为所有的primary shard和replica shard都是Active status
1.7 文档的核心元数据
- _index: 说明了一个文档存储在哪个索引中,同一个索引下存放的是相似的文档(文档的field多数是相同的)索引名必须是小写,不能以下划线开头,不能包括逗号
- _type: 表示文档属于索引中的哪个类型,一个索引下只能有一个type,类型名可以是大写也可以是小写,不能以下划线开头,不能包括逗号
- _id: 文档的唯一标识,和索引,类型在一起唯一标识了一个文档,可以手动指定值,也可以由es来生成这个值
1.8 文档id生成方式
- 手动指定 通常是把其他系统的已有数据导入到es时
- es生成id值 es生成的长度为20个字符,使用的是base64编码,URL安全;使用的是GUID算法,分布式下并发生成Id值不会冲突
1.9 改变文档内容原理解析
- POST:根据用户传递过来的数据查询出doc,然后使用用户提交过来的数据进行更新到doc中,再将已有的doc标记为deleted,根据此doc创建一个新的doc
- PUT:先从es中查询出doc返回给用户,用户再将修改后的doc传递给es,es将原来的doc标记为deleted,再将用户传递过来的doc创建为一个新的doc
- 总结:①post方式比put方式网络数据传输的次数要少(不需要查询返回给用户),从而提高了性能 ②post方式从查询文档到修改文档再到创建新的文档都是在es内部实现的 ③post方式发生并发冲突的可能性降低
1.10 文档数据路由原理解析
- 数据路由:一个索引有多个分片组成,当添加(查看、修改、删除)一个文档时,es就需要决定这个文档存储在哪个分片上,这个过程就叫做数据路由(routing)
- 路由算法:
shard = hash(routing) % number_of_primary_shards
示例:一个索引,三个primary shard
① 每次增删改查时都有一个routing值,默认是文档的_id的值
② 对这个routing值使用哈希函数进行计算
③ 计算出的值再和主分片个数取余数
余数肯定在0----(number_of_primary_shards-1)之间,文档就在对应的shard上
routing默认值是文档的_id的值,也可以手动指定一个值,手动指定对于负载均衡以及提高批量读取的性能都有帮助
- primary shard个数一旦确定就不能修改了