Elasticsearch基础

并发问题
比如秒杀
为控制并发问题,通常采用锁机制,分为悲观锁和乐观锁
悲观锁:很悲观,所有情况都上锁。此时只有一个线程可以操作数据。具体例子为数据库中的行级锁、表级锁、读锁、写锁等。
特点:优点是方便,直接加锁,对程序透明。缺点是效率低。

乐观锁:很乐观,对数据本身不加锁。提交数据时,通过一种机制验证是否存在冲突,如es中通过版本号验证。
特点:优点是并发能力高。缺点是操作繁琐,在提交数据时,可能反复重试多次。

es对复杂分布式机制的透明隐藏特性
分布式机制:分布式数据存储及共享
分片机制:数据存储到哪个分片,副本数据写入
集群发现机制:cluster discovery。新启动es实例,自动加入集群
shard负载均衡:大量数据写入及查询,es会将数据平均分配
shard副本:新增副本数,分片重分配

Elasticsearch的垂直扩容与水平扩容
垂直扩容:使用更加强大的服务器替代老服务器,但单机存储及运算能力有上线。且成本直线上升
水平扩容:采购更多服务器,加入集群

增减或减少节点时的数据rebalance
新增或减少es实例时,es集群会将数据重新分配

master节点
创建删除节点
创建删除索引

节点对等的分布式架构
节点对等,每个节点都能接受到所有的请求
自动请求路由
响应收集
master节点挂掉,es会选出一台新的节点为master节点,不会出现

分片shard&副本replica机制
1.每个index包含一个或多个shard
2.每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处理请求的能力
3.增减节点时,shard会自动在nodes中负载均衡
4.primary shard(主分片)和replica shard(副本分片),每个document肯定只存在于某一个primary shard以及其对应的replica shard中,不可能存在于多个primary shard
5.replica shard是primary shard的副本,负责容错,以及承担读请求负载
6.primary shard的数量在创建索引的时候就固定了(这是因为 Elasticsearch 在创建索引时,会根据分片的数量把数据分布到不同的节点上,如果在创建索引后改变分片的数量,那么数据的分布就会出问题),replica shard的数量可以随时修改
7.primary shard的默认数量是1,replica默认是1,默认共有2个shard,1个primary shard,1个replica shard
8.primary shard不能和自己的replica shard放在同一个节点上(否则节点岩机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上

单node环境下创建index
单node环境下,创建一个index, 设置有3个主分片3个副本分片,eg:

PUT /test_index1
{
  "settings": {
    "number_of_replicas": 3,
    "number_of_shards": 3
  }
}

查看集群状态时得到

集群状态时yellow; 只会将3个primary shard分配到仅有的一个node上去,另外3个replica shard是无法分配的;
集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法承接任何请求

横向扩容
分片自动负载均衡,分片向空闲机器转移
每个节点存储更少分片,系统资源给与每个分片的资源更多,整体集群性能提高。
扩容极限:节点数大于整体分片数,则必有空闲机器
超出扩容极限时,可以增加副本数,如设置副本数为2,总共3*3=9个分片。9台机器同时运行,存储和搜索性能更强。容错性更好
容错性:只要一个索引的所有主分片在,集群就就可以运行

容错机制
以3个分片2个副本 3个节点为例

情景:
node1宕机,P0 shard 没有了,所有主分片不是active,集群状态red
容错步骤
1.重新选举master节点,承担master功能
2.新的master将丢失的主分片的某个副本提升为主分片,集群状态为yellow,现在缺少副本分片

3. 故障机器重启后,新master会感知到新节点加入,将缺失的副本分片copy一份到新的机器上(copy为增量数据),此时集群的状态为green

文档存储机制
数据路由
一个文档最终会落在主分片的一个分片上,至于落到哪个分片上需要路由

  1. 路由算法
shard = hash(routing) % number_of_primary_shards

哈希值对主分片数取模
eg:
对一个文档经行crud时,都会带一个路由值 routing number。默认为文档_id(可能是手动指定,也可能是自动生成),
存储1号文档,经过哈希计算,哈希值为2,此索引有3个主分片,那么计算2%3=2,就算出此文档在P2分片上。

决定一个document在哪个shard上,最重要的一个值就是routing值,默认是_id,也可以手动指定,相同的routing值,每次过来,从hash函数中,产出的hash值一定是相同的无论hash值是几,无论是什么数字,对number_of_primary_shards求余数,结果一定是在0-number_of_primary_shards-1之间这个范围内的.
2. 手动指定routing key

PUT /test_index1/_doc/1?routing=tom
{
  "user_name": "tom"
}

场景:在程序中,架构师可以手动指定已有数据的一个属性为路由值,好处是可以定制一类文档数据存储到一个分片中。缺点是设计不好,会造成数据倾斜。所以,不同文档尽量放到不同的索引中。剩下的事情交给es集群自己处理。
3. 主分片数量不可变:
原因:涉及到以往的数据查询搜索,一旦建立索引,可能会导致查询失败

文档的增删改机制
增删改可以看做update,都是对数据的改动。一个改动请求发送到es集群,经历以下4步骤

  1. 客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)
  2. coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)
  3. 实际的node上的primary shard处理请求,然后将数据同步到replica node。
  4. coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

文档的查询内部机制
1.客户端发送请求到任意一个node,成为coordinating node(协调节点)
2. coordinating node对document进行路由,将请求转发到对应的node,此时会使用 round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡
3. 接收请求的node返回document给coordinating node
4. coordinating node返回document给客户端
5. 特殊情况:document如果还在建立索引过程中,可能只有primary shard有,任何一个replica shard都没有,此时可能会导致无法读取到document,但是document完成索引建立之后,primary shard和replica shard就都有了

posted @ 2024-03-19 09:54  py卡卡  阅读(1)  评论(0编辑  收藏  举报