从 Elasticsearch 来看分布式系统架构设计

简介: 分布式系统类型多,涉及面非常广,不同类型的系统有不同的特点,批量计算和实时计算就差别非常大。这篇文章中,重点会讨论下分布式数据系统的设计,比如分布式存储系统,分布式搜索系统,分布式分析系统等。 分布式系统类型多,涉及面非常广,不同类型的系统有不同的特点,批量计算和实时计算就差别非常大。


Elasticsearch 集群架构

Elasticsearch 是一个非常著名的开源搜索和分析系统,目前被广泛应用于互联网多种领域中,尤其是以下三个领域特别突出。一是搜索领域,相对于 solr,真正的后起之秀,成为很多搜索系统的不二之选。二是 Json 文档数据库,相对于 MongoDB,读写性能更佳,而且支持更丰富的地理位置查询以及数字、文本的混合查询等。三是时序数据分析处理,目前是日志处理、监控数据的存储、分析和可视化方面做得非常好,可以说是该领域的引领者了。

Elasticsearch 的详细介绍可以到官网查看。我们先来看一下 Elasticsearch 中几个关键概念:

8481c8f592b7f349aa84a1de5c171db681516edf 节点(Node):物理概念,一个运行的 Elasticearch 实例,一般是一台机器上的一个进程。
8481c8f592b7f349aa84a1de5c171db681516edf 索引(Index),逻辑概念,包括配置信息 mapping 和倒排正排数据文件,一个索引的数据文件可能会分布于一台机器,也有可能分布于多台机器。索引的另外一层意思是倒排索引文件。
8481c8f592b7f349aa84a1de5c171db681516edf 分片(Shard):为了支持更大量的数据,索引一般会按某个维度分成多个部分,每个部分就是一个分片,分片被节点 (Node) 管理。一个节点 (Node) 一般会管理多个分片,这些分片可能是属于同一份索引,也有可能属于不同索引,但是为了可靠性和可用性,同一个索引的分片尽量会分布在不同节点 (Node) 上。分片有两种,主分片和副本分片。
8481c8f592b7f349aa84a1de5c171db681516edf 副本(Replica):同一个分片 (Shard) 的备份数据,一个分片可能会有0个或多个副本,这些副本中的数据保证强一致或最终一致。

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

de74c194cd84914ee6998a76d0d12f0f9df0b291

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 无法承载所有流量,这个时候就需要一个副本来分流查询压力,目的就是扩展查询能力。

角色部署方式

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

fa25bdd3601acdb04217c3d7d1e50932adfe8d9c

Elasticsearch 支持上述两种方式:

混合部署(左图):

8481c8f592b7f349aa84a1de5c171db681516edf 默认方式。
8481c8f592b7f349aa84a1de5c171db681516edf 不考虑 MasterNode 的情况下,还有两种 Node,Data Node 和 Transport Node,这种部署模式下,这两种不同类型 Node 角色都位于同一个 Node 中,相当于一个Node 具备两种功能:Data 和 Transport。
8481c8f592b7f349aa84a1de5c171db681516edf 当有 index 或者 query 请求的时候,请求随机(自定义)发送给任何一个 Node,这台 Node 中会持有一个全局的路由表,通过路由表选择合适的 Node,将请求发送给这些 Node,然后等所有请求都返回后,合并结果,然后返回给用户。一个 Node 分饰两种角色。
8481c8f592b7f349aa84a1de5c171db681516edf 好处就是使用极其简单,易上手,对推广系统有很大价值。最简单的场景下只需要启动一个 Node,就能完成所有的功能。
8481c8f592b7f349aa84a1de5c171db681516edf 缺点就是多种类型的请求会相互影响,在大集群如果某一个 Data Node 出现热点,那么就会影响途经这个 Data Node 的所有其他跨 Node 请求。如果发生故障,故障影响面会变大很多。
8481c8f592b7f349aa84a1de5c171db681516edf Elasticsearch 中每个 Node 都需要和其余的每一个 Node 都保持13个连接。这种情况下,每个 Node 都需要和其他所有 Node 保持连接,而一个系统的连接数是有上限的,这样连接数就会限制集群规模。
8481c8f592b7f349aa84a1de5c171db681516edf 还有就是不能支持集群的热更新。

分层部署(右图):

8481c8f592b7f349aa84a1de5c171db681516edf 通过配置可以隔离开 Node。

8481c8f592b7f349aa84a1de5c171db681516edf设置部分 Node 为 Transport Node,专门用来做请求转发和结果合并。

其他 Node 可以设置为 DataNode,专门用来处理数据。
8481c8f592b7f349aa84a1de5c171db681516edf 缺点是上手复杂,需要提前设置好 Transport 的数量,且数量和 Data Node、流量等相关,否则要么资源闲置,要么机器被打爆。
8481c8f592b7f349aa84a1de5c171db681516edf 好处就是角色相互独立,不会相互影响,一般 Transport Node 的流量是平均分配的,很少出现单台机器的 CPU 或流量被打满的情况,而 DataNode 由于处理数据,很容易出现单机资源被占满,比如 CPU,网络,磁盘等。独立开后,DataNode如果出了故障只是影响单节点的数据处理,不会影响其他节点的请求,影响限制在最小的范围内。
8481c8f592b7f349aa84a1de5c171db681516edf 角色独立后,只需要 Transport Node 连接所有的 DataNode,而 DataNode 则不需要和其他 DataNode 有连接。一个集群中DataNode的数量远大于 Transport Node,这样集群的规模可以更大。另外,还可以通过分组,使 Transport Node 只连接固定分组的 DataNode,这样 Elasticsearch 的连接数问题就彻底解决了。
8481c8f592b7f349aa84a1de5c171db681516edf 可以支持热更新:先一台一台的升级 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)的目的有三个:

8481c8f592b7f349aa84a1de5c171db681516edf 保证服务可用性:当设置了多个 Replica 的时候,如果某一个 Replica 不可用的时候,那么请求流量可以继续发往其他 Replica,服务可以很快恢复开始服务。
8481c8f592b7f349aa84a1de5c171db681516edf 保证数据可靠性:如果只有一个 Primary,没有 Replica,那么当 Primary 的机器磁盘损坏的时候,那么这个 Node 中所有 Shard 的数据会丢失,只能 reindex 了。

8481c8f592b7f349aa84a1de5c171db681516edf提供更大的查询能力:当 Shard 提供的查询能力无法满足业务需求的时候, 可以继续加N个 Replica,这样查询能力就能提高N倍,轻松增加系统的并发度。

问题

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

8481c8f592b7f349aa84a1de5c171db681516edf Elasticsearch 采用的是基于本地文件系统,使用 Replica 保证数据可靠性的技术架构,这种架构一定程度上可以满足大部分需求和场景,但是也存在一些遗憾:
8481c8f592b7f349aa84a1de5c171db681516edf Replica带来成本浪费。为了保证数据可靠性,必须使用 Replica,但是当一个 Shard 就能满足处理能力的时候,另一个 Shard 的计算能力就会浪费。
8481c8f592b7f349aa84a1de5c171db681516edf Replica 带来写性能和吞吐的下降。每次 Index 或者 update 的时候,需要先更新Primary Shard,更新成功后再并行去更新 Replica,再加上长尾,写入性能会有不少的下降。
8481c8f592b7f349aa84a1de5c171db681516edf 当出现热点或者需要紧急扩容的时候动态增加 Replica 慢。新 Shard 的数据需要完全从其他 Shard 拷贝,拷贝时间较长。

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

分布式系统

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

020acc6b8fc626158eede556ac8eb08dbf01f8f5

上图中是一个基于本地磁盘存储数据的分布式系统。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 使用的就是这种架构方式。

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

5b7726289c20be4f72b32924ca4456255bcc1ab7

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

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

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

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

8481c8f592b7f349aa84a1de5c171db681516edf 在这种架构下,资源可以更加弹性,当存储不够的时候只需要扩容存储系统的容量;当计算不够的时候,只需要扩容计算部分容量。
8481c8f592b7f349aa84a1de5c171db681516edf 存储和计算是独立管理的,资源管理粒度更小,管理更加精细化,浪费更少,结果就是总体成本可以更低。
8481c8f592b7f349aa84a1de5c171db681516edf 负载更加突出,抗热点能力更强。一般热点问题基本都出现在计算部分,对于存储和计算分离系统,计算部分由于没有绑定数据,可以实时的扩容、缩容和迁移,当出现热点的时候,可以第一时间将计算调度到新节点上。

这种架构同时也有一个不足:

访问分布式文件系统的性能可能不及访问本地文件系统。在上一代分布式文件系统中,这是一个比较明显的问题,但是目前使用了各种用户态协议栈后,这个差距已经越来越小了。

HBase 使用的就是这种架构方式。

Solr 也支持这种形式的架构。

总结

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

上面只是介绍了分布式数据(存储/搜索/分析等等)系统在存储层的两种不同架构方式,希望能对大家有用。但是分布式系统架构设计所涉及的内容广,细节多,权衡点众,如果大家对某些领域或者方面有兴趣,也可以留言,后面再探讨。


原文发布时间为:2018-03-29
本文来自云栖社区合作伙伴“ 数据和云”,了解相关信息可以关注“ 数据和云”微信公众号
相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
人工智能 Kubernetes 数据可视化
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
本文回顾了一次关键词监测任务在容器集群中失效的全过程,分析了中转IP复用、调度节奏和异常处理等隐性风险,并提出通过解耦架构、动态IP分发和行为模拟优化采集策略,最终实现稳定高效的数据抓取与分析。
298 2
Kubernetes下的分布式采集系统设计与实战:趋势监测失效引发的架构进化
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
1573 3
|
11月前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
监控 算法 关系型数据库
分布式事务难题终结:Seata+DRDS全局事务一致性架构设计
在分布式系统中,CAP定理限制了可用性、一致性与分区容错的三者兼得,尤其在网络分区时需做出取舍。为应对这一挑战,最终一致性方案成为常见选择。以电商订单系统为例,微服务化后,原本的本地事务演变为跨数据库的分布式事务,暴露出全局锁失效、事务边界模糊及协议差异等问题。本文深入探讨了基于 Seata 与 DRDS 的分布式事务解决方案,涵盖 AT 模式实践、分片策略优化、典型问题处理、性能调优及高级特性实现,结合实际业务场景提供可落地的技术路径与架构设计原则。通过压测验证,该方案在事务延迟、TPS 及失败率等方面均取得显著优化效果。
702 61
|
11月前
|
存储 NoSQL 前端开发
【赵渝强老师】MongoDB的分布式存储架构
MongoDB分片通过将数据分布到多台服务器,实现海量数据的高效存储与读写。其架构包含路由、配置服务器和分片服务器,支持水平扩展,结合复制集保障高可用性,适用于大规模生产环境。
699 1
|
12月前
|
消息中间件 缓存 监控
中间件架构设计与实践:构建高性能分布式系统的核心基石
摘要 本文系统探讨了中间件技术及其在分布式系统中的核心价值。作者首先定义了中间件作为连接系统组件的"神经网络",强调其在数据传输、系统稳定性和扩展性中的关键作用。随后详细分类了中间件体系,包括通信中间件(如RabbitMQ/Kafka)、数据中间件(如Redis/MyCAT)等类型。文章重点剖析了消息中间件的实现机制,通过Spring Boot代码示例展示了消息生产者的完整实现,涵盖消息ID生成、持久化、批量发送及重试机制等关键技术点。最后,作者指出中间件架构设计对系统性能的决定性影响,
|
监控 Linux 应用服务中间件
Linux多节点多硬盘部署MinIO:分布式MinIO集群部署指南搭建高可用架构实践
通过以上步骤,已成功基于已有的 MinIO 服务,扩展为一个 MinIO 集群。该集群具有高可用性和容错性,适合生产环境使用。如果有任何问题,请检查日志或参考MinIO 官方文档。作者联系方式vx:2743642415。
4325 57
|
11月前
|
存储 Linux iOS开发
Elasticsearch Enterprise 9.1.5 发布 - 分布式搜索和分析引擎
Elasticsearch Enterprise 9.1.5 (macOS, Linux, Windows) - 分布式搜索和分析引擎
704 0
|
12月前
|
JSON 监控 Java
Elasticsearch 分布式搜索与分析引擎技术详解与实践指南
本文档全面介绍 Elasticsearch 分布式搜索与分析引擎的核心概念、架构设计和实践应用。作为基于 Lucene 的分布式搜索引擎,Elasticsearch 提供了近实时的搜索能力、强大的数据分析功能和可扩展的分布式架构。本文将深入探讨其索引机制、查询 DSL、集群管理、性能优化以及与各种应用场景的集成,帮助开发者构建高性能的搜索和分析系统。
704 0
|
SQL 运维 数据挖掘
森马服饰从 Elasticsearch 到阿里云 SelectDB 的架构演进之路
森马引入阿里云 SelectDB 替换原 Elasticsearch + 业务库混合架构,统一分析 16+ 核心业务,打通 BI 组件,大幅简化数据同步链路和分析系统架构。实现复杂查询 QPS 提升 400%,响应时间缩短至秒级,亿级库存流水聚合查询缩短至 8 秒内的显著收益,有效驱动森马全渠道运营效率持续增长与业务创新。
454 0
森马服饰从 Elasticsearch 到阿里云 SelectDB 的架构演进之路

热门文章

最新文章