关于java:ElasticSearch让人叹为观止的分布式系统架构设计

43次阅读

共计 5254 个字符,预计需要花费 14 分钟才能阅读完成。

分布式系统类型多,涉及面十分广,不同类型的零碎有不同的特点,批量计算和实时计算就差异十分大。这篇文章中,重点会探讨下分布式数据系统的设计,比方分布式存储系统,分布式搜寻零碎,分布式剖析零碎等。

咱们先来简略看下 Elasticsearch 的架构。

Elasticsearch 集群架构

Elasticsearch 是一个十分驰名的开源搜寻和剖析零碎,目前被广泛应用于互联网多种畛域中,尤其是以下三个畛域特地突出。一是搜寻畛域,绝对于 solr,真正的后起之秀,成为很多搜寻零碎的不二之选。二是 Json 文档数据库,绝对于 MongoDB,读写性能更佳,而且反对更丰盛的地理位置查问以及数字、文本的混合查问等。三是时序数据分析解决,目前是日志解决、监控数据的存储、剖析和可视化方面做得十分好,能够说是该畛域的引领者了。

Elasticsearch 的具体介绍能够到官网查看。咱们先来看一下 Elasticsearch 中几个要害概念:

  • 节点(Node):物理概念,一个运行的 Elasticearch 实例,个别是一台机器上的一个过程。
  • 索引(Index),逻辑概念,包含配置信息 mapping 和倒排正排数据文件,一个索引的数据文件可能会散布于一台机器,也有可能散布于多台机器。索引的另外一层意思是倒排索引文件。
  • 分片(Shard):为了反对更大量的数据,索引个别会按某个维度分成多个局部,每个局部就是一个分片,分片被节点 (Node) 治理。一个节点 (Node) 个别会治理多个分片,这些分片可能是属于同一份索引,也有可能属于不同索引,然而为了可靠性和可用性,同一个索引的分片尽量会散布在不同节点 (Node) 上。分片有两种,主分片和正本分片。
  • 正本(Replica):同一个分片 (Shard) 的备份数据,一个分片可能会有 0 个或多个正本,这些正本中的数据保障强统一或最终统一。

用图形示意进去可能是这样子的:

图片

  • Index 1:蓝色局部,有 3 个 shard,别离是 P1,P2,P3,位于 3 个不同的 Node 中,这里没有 Replica。
  • Index 2:绿色局部,有 2 个 shard,别离是 P1,P2,位于 2 个不同的 Node 中。并且每个 shard 有一个 replica,别离是 R1 和 R2。基于零碎可用性的思考,同一个 shard 的 primary 和 replica 不能位于同一个 Node 中。这里 Shard1 的 P1 和 R1 别离位于 Node3 和 Node2 中,如果某一刻 Node2 产生宕机,服务根本不会受影响,因为还有一个 P1 和 R2 都还是可用的。因为是主备架构,当主分片产生故障时,须要切换,这时候须要选举一个正本作为新主,这里除了会消耗一点点工夫外,也会有失落数据的危险。

Index 流程

建索引(Index)的时候,一个 Doc 先是通过路由规定定位到主 Shard,发送这个 doc 到主 Shard 上建索引,胜利后再发送这个 Doc 到这个 Shard 的正本上建索引,等正本上建索引胜利后才返回胜利。

在这种架构中,索引数据全副位于 Shard 中,主 Shard 和正本 Shard 各存储一份。当某个正本 Shard 或者主 Shard 失落(比方机器宕机,网络中断等)时,须要将失落的 Shard 在其余 Node 中复原回来,这时候就须要从其余正本(Replica)全量拷贝这个 Shard 的所有数据到新 Node 上结构新 Shard。这个拷贝过程须要一段时间,这段时间内只能由残余主副原本承载流量,在复原实现之前,整个零碎会处于一个比拟危险的状态,直到 failover 完结。

这里就体现了正本(Replica)存在的一个理由,防止数据失落,进步数据可靠性。正本(Replica)存在的另一个理由是读申请量很大的时候,一个 Node 无奈承载所有流量,这个时候就须要一个副原本分流查问压力,目标就是扩大查问能力。

角色部署形式

接下来再看看角色分工的两种不同形式:

图片

Elasticsearch 反对上述两种形式:

1. 混合部署(左图)

  • 默认形式。
  • 不思考 MasterNode 的状况下,还有两种 Node,Data Node 和 Transport Node,这种部署模式下,这两种不同类型 Node 角色都位于同一个 Node 中,相当于一个 Node 具备两种性能:Data 和 Transport。
  • 当有 index 或者 query 申请的时候,申请随机(自定义)发送给任何一个 Node,这台 Node 中会持有一个全局的路由表,通过路由表抉择适合的 Node,将申请发送给这些 Node,而后等所有申请都返回后,合并后果,而后返回给用户。一个 Node 分饰两种角色。
  • 益处就是应用极其简略,易上手,对推广零碎有很大价值。最简略的场景下只须要启动一个 Node,就能实现所有的性能。
  • 毛病就是多种类型的申请会相互影响,在大集群如果某一个 Data Node 呈现热点,那么就会影响途经这个 Data Node 的所有其余跨 Node 申请。如果产生故障,故障影响面会变大很多。
  • Elasticsearch 中每个 Node 都须要和其余的每一个 Node 都放弃 13 个连贯。这种状况下,– 每个 Node 都须要和其余所有 Node 放弃连贯,而一个零碎的连接数是有下限的,这样连接数就会限度集群规模。
  • 还有就是不能反对集群的热更新。

2. 分层部署(右图):

  • 通过配置能够隔离开 Node。
  • 设置局部 Node 为 Transport Node,专门用来做申请转发和后果合并。
  • 其余 Node 能够设置为 DataNode,专门用来解决数据。
  • 毛病是上手简单,须要提前设置好 Transport 的数量,且数量和 Data Node、流量等相干,否则要么资源闲置,要么机器被打爆。
  • 益处就是角色互相独立,不会相互影响,个别 Transport Node 的流量是平均分配的,很少呈现单台机器的 CPU 或流量被打满的状况,而 DataNode 因为解决数据,很容易呈现单机资源被占满,比方 CPU,网络,磁盘等。独立开后,DataNode 如果出了故障只是影响单节点的数据处理,不会影响其余节点的申请,影响限度在最小的范畴内。
  • 角色独立后,只须要 Transport Node 连贯所有的 DataNode,而 DataNode 则不须要和其余 DataNode 有连贯。一个集群中 DataNode 的数量远大于 Transport Node,这样集群的规模能够更大。另外,还能够通过分组,使 Transport Node 只连贯固定分组的 DataNode,这样 Elasticsearch 的连接数问题就彻底解决了。
  • 能够反对热更新:先一台一台的降级 DataNode,降级实现后再降级 Transport Node,整个过程中,能够做到让用户无感知。

下面介绍了 Elasticsearch 的部署层架构,不同的部署形式适宜不同场景,须要依据本人的需要抉择适宜的形式。

Elasticsearch 数据层架构

接下来咱们看看以后 Elasticsearch 的数据层架构。

数据存储

Elasticsearch 的 Index 和 meta,目前反对存储在本地文件系统中,同时反对 niofs,mmap,simplefs,smb 等不同加载形式,性能最好的是间接将索引 LOCK 进内存的 MMap 形式。默认,Elasticsearch 会主动抉择加载形式,另外能够本人在配置文件中配置。这里有几个细节,具体能够看官网文档。

索引和 meta 数据都存在本地,会带来一个问题:当某一台机器宕机或者磁盘损坏的时候,数据就失落了。为了解决这个问题,能够应用 Replica(正本)性能。

正本(Replica)

能够为每一个 Index 设置一个配置项:正本(Replicda)数,如果设置正本数为 2,那么就会有 3 个 Shard,其中一个是 PrimaryShard,其余两个是 ReplicaShard,这三个 Shard 会被 Mater 尽量调度到不同机器,甚至机架上,这三个 Shard 中的数据一样,提供同样的服务能力。

正本(Replica)的目标有三个:

  • 保障服务可用性:当设置了多个 Replica 的时候,如果某一个 Replica 不可用的时候,那么申请流量能够持续发往其余 Replica,服务能够很快复原开始服务。
  • 保证数据可靠性:如果只有一个 Primary,没有 Replica,那么当 Primary 的机器磁盘损坏的时候,那么这个 Node 中所有 Shard 的数据会失落,只能 reindex 了。
  • 提供更大的查问能力:当 Shard 提供的查问能力无奈满足业务需要的时候,能够持续加 N 个 Replica,这样查问能力就能进步 N 倍,轻松减少零碎的并发度。

问题

下面说了一些劣势,这种架构同样在一些场景下会有些问题。

Elasticsearch 采纳的是基于本地文件系统,应用 Replica 保证数据可靠性的技术架构,这种架构肯定水平上能够满足大部分需要和场景,然而也存在一些遗憾:

  • Replica 带来老本节约。为了保证数据可靠性,必须应用 Replica,然而当一个 Shard 就能满足解决能力的时候,另一个 Shard 的计算能力就会节约。
  • Replica 带来写性能和吞吐的降落。每次 Index 或者 update 的时候,须要先更新 Primary Shard,更新胜利后再并行去更新 Replica,再加上长尾,写入性能会有不少的降落。
  • 当呈现热点或者须要紧急扩容的时候动静减少 Replica 慢。新 Shard 的数据须要齐全从其余 Shard 拷贝,拷贝工夫较长。

下面介绍了 Elasticsearch 数据层的架构,以及正本策略带来的劣势和有余,上面简略介绍了几种不同模式的分布式数据系统架构。

分布式系统

第一种:基于本地文件系统的分布式系统

图片

上图中是一个基于本地磁盘存储数据的分布式系统。Index 一共有 3 个 Shard,每个 Shard 除了 Primary Shard 外,还有一个 Replica Shard。当 Node 3 机器宕机或磁盘损坏的时候,首先确认 P3 曾经不可用,从新选举 R3 位 Primary Shard,此 Shard 产生主备切换。而后从新找一台机器 Node 7,在 Node7 上重新启动 P3 的新 Replica。因为数据都会存在本地磁盘,此时须要将 Shard 3 的数据从 Node 6 上拷贝到 Node7 上。如果有 200G 数据,千兆网络,拷贝完须要 1600 秒。如果没有 replica,则这 1600 秒内这些 Shard 就不能服务。

为了保障可靠性,就须要冗余 Shard,会导致更多的物理资源耗费。

这种思维的另外一种表现形式是应用双集群,集群级别做备份。

在这种架构中,如果你的数据是在其余存储系统中生成的,比方 HDFS/HBase,那么你还须要一个数据传输零碎,将筹备好的数据散发到相应的机器上。

这种架构中为了保障可用性和可靠性,须要双集群或者 Replica 能力用于生产环境,劣势和副作用在下面介绍 Elasticsearch 的时候曾经介绍过了,这里就就不赘述了。

Elasticsearch 应用的就是这种架构形式。

第二种:基于分布式文件系统的分布式系统(共享存储)

图片

针对第一种架构中的问题,另一种思路是:存储和计算拆散。

第一种思路的问题本源是数据量大,拷贝数据耗时多,那么有没有方法能够不拷贝数据?为了实现这个目标,一种思路是底层存储层应用共享存储,每个 Shard 只须要连贯到一个分布式文件系统中的一个目录 / 文件即可,Shard 中不含有数据,只含有计算局部。相当于每个 Node 中只负责计算局部,存储局部放在底层的另一个分布式文件系统中,比方 HDFS。

上图中,Node 1 连贯到第一个文件;Node 2 连贯到第二个文件;Node3 连贯到第三个文件。当 Node 3 机器宕机后,只须要在 Node 4 机器上新建一个空的 Shard,而后结构一个新连贯,连贯到底层分布式文件系统的第三个文件即可,创立连贯的速度是很快的,总耗时会十分短。

这种是一种典型的存储和计算拆散的架构,劣势有以下几个方面:

  • 在这种架构下,资源能够更加弹性,当存储不够的时候只须要扩容存储系统的容量;当计算不够的时候,只须要扩容计算局部容量。
  • 存储和计算是独立治理的,资源管理粒度更小,治理更加精细化,节约更少,后果就是总体老本能够更低。
  • 负载更加突出,抗热点能力更强。个别热点问题根本都呈现在计算局部,对于存储和计算拆散零碎,计算局部因为没有绑定数据,能够实时的扩容、缩容和迁徙,当呈现热点的时候,能够第一工夫将计算调度到新节点上。

这种架构同时也有一个有余:拜访分布式文件系统的性能可能不迭拜访本地文件系统。在上一代分布式文件系统中,这是一个比拟显著的问题,然而目前应用了各种用户态协定栈后,这个差距曾经越来越小了。HBase 应用的就是这种架构形式。Solr 也反对这种模式的架构。

总结

上述两种架构,各有劣势和有余,对于某些架构中的有余或缺点,思路不同,解决的计划也天壤之别,然而思路跨度越大,收益个别也越大。

下面只是介绍了分布式数据(存储 / 搜寻 / 剖析等等)零碎在存储层的两种不同架构形式,心愿能对大家有用。然而分布式系统架构设计所波及的内容广,细节多,衡量点众,如果大家对某些畛域或者方面有趣味,也能够留言,前面再探讨。

正文完
 0