分布式系统如何设计?看elasticsearch是怎么做的-尊龙凯时ag旗舰厅

分布式系统如何设计?看elasticsearch是怎么做的
发布日期:2019-09-10

布式系统类型多,涉及面非常广,不同类型的系统有不同的特点,批量计算和实时计算就差别非常大。

这篇文章会重点讨论分布式数据系统的设计,比如分布式存储系统,分布式搜索系统,分布式分析系统等。我们先来简单看下 elasticsearch 的架构。

elasticsearch 集群架构

elasticsearch 是一个非常著名的开源搜索和分析系统,目前被广泛应用于互联网多种领域中。

尤其是以下三个领域特别突出:

elasticsearch 的详细介绍可以到人生就是博官网查看。我们先来看一下 elasticsearch 中几个关键概念:

如上图,用图形表示出来可能是这样子的:

index 流程

建索引(index)的时候,一个 doc 先是经过路由规则定位到主 shard,发送这个 doc 到主 shard 上建索引,成功后再发送这个 doc 到这个 shard 的副本上建索引,等副本上建索引成功后才返回成功。

在这种架构中,索引数据全部位于 shard 中,主 shard 和副本 shard 各存储一份。

当某个副本 shard 或者主 shard 丢失(比如机器宕机,网络中断等)时,需要将丢失的 shard 在其他 node 中恢复回来。

这时候就需要从其他副本(replica)全量拷贝这个 shard 的所有数据到新 node 上构造新 shard。

这个拷贝过程需要一段时间,这段时间内只能由剩余主副本来承载流量,在恢复完成之前,整个系统会处于一个比较危险的状态,直到 failover 结束。

这里就体现了副本(replica)存在的一个理由,避免数据丢失,提高数据可靠性。

副本(replica)存在的另一个理由是读请求量很大的时候,一个 node 无法承载所有流量,这个时候就需要一个副本来分流查询压力,目的就是扩展查询能力。

角色部署方式

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

elasticsearch 支持上述两种方式:

混合部署(如左图):

分层部署(如右图):

上面介绍了 elasticsearch 的部署层架构,不同的部署方式适合不同场景,需要根据自己的需求选择适合的方式。

elasticsearch 数据层架构

接下来我们看看当前 elasticsearch 的数据层架构。

数据存储

elasticsearch 的 index 和 meta,目前支持存储在本地文件系统中,同时支持 niofs,mmap,simplefs,smb 等不同加载方式,性能最好的是直接将索引 lock 进内存的 mmap 方式。

默认,elasticsearch 会自动选择加载方式,另外可以自己在配置文件中配置。这里有几个细节,具体可以看官方文档。

索引和 meta 数据都存在本地,会带来一个问题:当某一台机器宕机或者磁盘损坏的时候,数据就丢失了。为了解决这个问题,可以使用 replica(副本)功能。

副本(replica)

可以为每一个 index 设置一个配置项:副本(replicda)数,如果设置副本数为 2,那么就会有 3 个 shard,其中一个是 primary shard,其余两个是 replica shard。

这三个 shard 会被 mater 尽量调度到不同机器,甚至机架上,这三个 shard 中的数据一样,提供同样的服务能力。

副本(replica)的目的有三个:

问题

上面说了一些优势,这种架构同样在一些场景下会有些问题。elasticsearch 采用的是基于本地文件系统,使用 replica 保证数据可靠性的技术架构,这种架构一定程度上可以满足大部分需求和场景。

但是也存在一些遗憾:

上面介绍了 elasticsearch 数据层的架构,以及副本策略带来的优势和不足,下面简单介绍了几种不同形式的分布式数据系统架构。

分布式系统

基于本地文件系统的分布式系统

上图中是一个基于本地磁盘存储数据的分布式系统。index 一共有 3 个 shard,每个 shard 除了 primary shard 外,还有一个 replica shard。

当 node 3 机器宕机或磁盘损坏的时候,首先确认 p3 已经不可用,重新选举 r3 位 primary shard,此 shard 发生主备切换。然后重新找一台机器 node 7,在 node 7 上重新启动 p3 的新 replica。

由于数据都会存在本地磁盘,此时需要将 shard 3 的数据从 node 6 上拷贝到 node 7 上。

如果有 200g 数据,千兆网络,拷贝完需要 1600 秒。如果没有 replica,则这 1600 秒内这些 shard 就不能服务。

为了保证可靠性,就需要冗余 shard,会导致更多的物理资源消耗。这种思想的另外一种表现形式是使用双集群,集群级别做备份。

在这种架构中,如果你的数据是在其他存储系统中生成的,比如 hdfs/hbase,那么你还需要一个数据传输系统,将准备好的数据分发到相应的机器上。

这种架构中为了保证可用性和可靠性,需要双集群或者 replica 才能用于生产环境,优势和副作用在上面介绍 elasticsearch 的时候已经介绍过了,这里就不赘述了。elasticsearch 使用的就是这种架构方式。

基于分布式文件系统的分布式系统

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

第一种思路的问题根源是数据量大,拷贝数据耗时多,那么有没有办法可以不拷贝数据?

为了实现这个目的,一种思路是底层存储层使用共享存储,每个 shard 只需要连接到一个分布式文件系统中的一个目录/文件即可,shard 中不含有数据,只含有计算部分。

相当于每个 node 中只负责计算部分,存储部分放在底层的另一个分布式文件系统中,比如 hdfs。

上图中,node 1 连接到第一个文件;node 2连接到第二个文件;node 3 连接到第三个文件。

当 node 3 机器宕机后,只需要在 node 4 机器上新建一个空的 shard,然后构造一个新连接,连接到底层分布式文件系统的第三个文件即可,创建连接的速度是很快的,总耗时会非常短。

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

这种架构同时也有一个不足:访问分布式文件系统的性能可能不及访问本地文件系统。

在上一代分布式文件系统中,这是一个比较明显的问题,但是目前使用了各种用户态协议栈后,这个差距已经越来越小了。hbase 使用的就是这种架构方式,solr 也支持这种形式的架构。

总结

上述两种架构,各有优势和不足,对于某些架构中的不足或缺陷,思路不同,解决的方案也大相径庭,但是思路跨度越大,收益一般也越大。

上面只是介绍了分布式数据(存储/搜索/分析等等)系统在存储层的两种不同架构方式,希望能对大家有用。

但是分布式系统架构设计所涉及的内容广,细节多,权衡点众,如果大家对某些领域或者方面有兴趣,也可以留言,后面再探讨。

网站地图