1.解析es的分布式架构
1.1分布式架构的透明隐藏特性
ElasticSearch是一个分布式系统,隐藏了复杂的处理机制
分片机制:我们不用关心数据是按照什么机制分片的、最后放入到哪个分片中
分片的副本:
集群发现机制(cluster discovery):比如当前我们启动了一个es进程,当启动第二个es进程时,这个进程作为一个node自动就发现了集群,并且加入了进去
shard负载均衡:比如现在有10shard,集群中有3个节点,es会进行均衡的进行分配,以保证每个节点均衡的负载请求
请求路由
1.2.扩容机制
垂直扩容:购置新的机器,替换已有的机器
水平扩容:直接增加机器
1.3.rebalance
增加或减少节点时会自动均衡
1.4.master节点
主节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点.稳定的主节点对集群的健康是非常重要的.
1.5.节点对等
每个节点都能接收请求,每个节点接收到请求后都能把该请求路由到有相关数据的其它节点上接收原始请求的节点负责采集数据并返回给客户端
2.分片和副本机制
1.index包含多个shard
2.每个shard都是一个最小工作单元,承载部分数据;每个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的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
7.primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shard
8.primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失了,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上
3.单节点情况下创建索引分析
PUT /myindex
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
这个时候,只会将3个primary shard分配到仅有的一个node上去,另外3个replica shard是无法分配的(一个shard的副本replica,他们两个是不能在同一个节点的),集群可以正常工作,但是一旦出现节点宕机,数据全部丢失,而且集群不可用,无法接收任何请求
4.两个节点环境下创建索引分析
将3个primary shard分配到一个node上去,另外3个replica shard分配到另一个节点上
primary shard 和 replica shard 保持同步
primary shard 和 replica shard 都可以处理客户端的读请求
5. 水平扩容的过程
1.扩容后primary shard和replica shard会自动的负载均衡
2.扩容后每个节点上的shard会减少,那么分配get每个shard的CPU,内存,IO资源会更多,性能提高
3.扩容的极限,如果有6个shard,扩容的极限就是6个节点,每个节点上一个shard,如果想超出扩容的极限,比如扩容到9个节点,那么可以增加replica shard的个数
4.6个shard,3个节点,最多能承受几个节点所在的服务器宕机?(容错性)任何一台服务器宕机都会丢失部分数据,为了提高容错性,增加shard的个数:9个shard(3个primary shard,6个replica shard),这样就能容忍最多两台服务器宕机了
总结:扩容是为了提高系统的吞吐量,同时也要考虑容错性,也就是让尽可能多的服务器宕机还能保证数据不丢失
6.ElasticSearch的容错机制
以9个shard,3个节点为例:
如果master node宕机,此时不是所有的primary shard都是Active status,所以此时的集群状态是red.
容错处理的第一步:是选举一台服务器作为master
容错处理的第二步:新选举出的master会把挂掉的primary shard的某个replica shard提升为primary shard,此时集群的状态为yellow,因为少了一个replica shard,并不是所有的replica shard都是actice status
容错处理的第三步:重启故障机,新master会把所有的副本都复制一份到该节点上,(同步一下宕机后发生的修改),此时集群的状态为green,因为所有的primary shard和replica shard都是Active status
7.文档的核心元数据
1._index:说明一个文档储存在哪个索引中,同一个索引下存放的是相似的文档(文档的field多数是相同的)索引名是小写的,不能以下划线开头,不能包括逗号
2._type:表示文档属于索引中的哪个类型,一个索引下只能有一个type,类型名可以是大写也可以是小写,不能以下划线开头,不能包括逗号
3._id:文档的唯一标识,和索引,类型组合在一起标识了一个文档,可以手动指定值,也可以由es来生产这个值
8.文档id生成方式
1.手动指定
put /index/type/66
通常是把其他系统的已有的数据导入到es时
2.由es生成id值
put /index/type
es生成的id长度为20个字符,使用的是base64编码,URL安全,使用的是GUID算法,分布式下并发生成id值时不会冲突
9._source元数据分析
其实就是我们在添加文档时request body中的内容
指定返回的结果中含有哪些字段:
get /index/type/1?_source=name
10.改变文档内容原理解析
替换方式:
PUT /lib/user/4
{ "first_name" : "Jane",
"last_name" : "Lucy",
"age" : 24,
"about" : "I like to collect rock albums",
"interests": [ "music" ]
}
修改方式(partial update):
查询出document然后使用用户提交过来的数据更新到document中,已有的document被标记为deleted,创建一个新的document
POST /lib/user/2/_update
{
"doc":{
"age":26
}
}
总结:
1.post方式比put方式网络数据传输的次数要少,从而提高了性能,post方式从查询文档到修改文档再到创建新的文档都是在es内部实现的;
2.post方式发生并发冲突的可能性降低,put方式发生并发冲突的可能性比较大
删除文档:标记为deleted,随着数据量的增加,es会选择合适的时间删除掉
11.基于groovy脚本执行partial update
es有内置的脚本支持,可以基于groovy脚本实现复杂的操作
1.修改年龄
GET /lib/user/4/_update
{
"script":"ctx._source.age+=1"
}
2.修改名字
GET /lib/user/4/_update
{
"script":"ctx._source.last_name+='hehe'"
}
3.添加爱好
GET /lib/user/4/_update
{
"script":{
"source":"ctx._source.interests.add(params.tag)",
"params": {
"tag":"football"
}
}
}
4.删除爱好
GET /lib/user/4/_update
{
"script":{
"source":"ctx._source.interests.remove(ctx._source.interests.indexOf(params.tag))",
"params": {
"tag":"football"
}
}
}
5.删除文档
GET /lib/user/4/_update
{
"script":{
"source":"ctx.op=ctx._source.age==params.count?'delete':'none'",
"params": {
"count":27
}
}
}
6.upsert
upsert操作:如果该文档不存在会进行初始化,如果存在执行"script":"ctx._source.age+=1"
GET /lib/user/4/_update
{
"script":"ctx._source.age+=1",
"upsert":{
"first_name": "Jane",
"last_name": "Smith",
"age": 23,
"about": "I like to collect rock albums",
"interests": [
"music"
]
}
}