分布式系统如何设计?看Elasticsearch是怎么做的

技术教程 2025-05-05 20:38:54 浏览
分布式系统如何设计

分布式系统如何设计?看ElasticSearch是怎么做的

2019-09-10 09:25:27 服务 分布式系统类型多,涉及面非常广,不同类型的系统有不同的特点,批量计算和实时计算就差别非常大。

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

图片来自 Pexels

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

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

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

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

一个节点(Node)一般会管理多个分片,这些分片可能是属于同一份索引,也有可能属于不同索引,但是为了可靠性和可用性,同一个索引的分片尽量会分布在不同节点(Node)上。分片有两种,主分片和副本分片。

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

基于系统可用性的考虑,同一个 Shard 的 Primary 和 Replica 不能位于同一个 Node 中。

这里 Shard1 的 P1 和 R1 分别位于 Node3 和 Node2 中,如果某一刻 Node2 发生宕机,服务基本不会受影响,因为还有一个 P1 和 R2 都还是可用的。

因为是主备架构,当主分片发生故障时,需要切换,这时候需要选举一个副本作为新主,这里除了会耗费一点点时间外,也会有丢失数据的风险。

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

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

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

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

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

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

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

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

Elasticsearch 支持上述两种方式:

混合部署(如左图):

这种部署模式下,这两种不同类型 Node 角色都位于同一个 Node 中,相当于一个 Node 具备两种功能:Data 和 Transport。

这台 Node 中会持有一个全局的路由表,通过路由表选择合适的 Node,将请求发送给这些 Node,然后等所有请求都返回后,合并结果,然后返回给用户。一个 Node 分饰两种角色。

这种情况下,每个 Node 都需要和其他所有 Node 保持连接,而一个系统的连接数是有上限的,这样连接数就会限制集群规模。

分层部署(如右图):

而>一个集群中>另外,还可以通过分组,使 Transport Node 只连接固定分组的>Elasticsearch 数据层架构

看Elasticsearch是怎么做的

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

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

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

索引和 Meta 数据都存在本地,会带来一个问题:当某一台机器宕机或者磁盘损坏的时候,数据就丢失了。为了解决这个问题,可以使用 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 也支持这种形式的架构。

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

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

看Elasticsearch是怎么做的

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


详细讲解下JAVA

Java语言是一个支持网络计算的面向对象程序设计语言。 Java语言吸收了Smalltalk语言和C++语言的优点,并增加了其它特性,如支持并发程序设计、网络通信、和多媒体数据控制等。 主要特性如下: 1、Java语言是简单的。 Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用Java。 另一方面,Java丢弃了C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。 特别地,Java语言不使用指针,并提供了自动的废料收集,使得程序员不必为内存管理而担忧。 2、Java语言是一个面向对象的。 Java语言提供类、接口和继承等原语,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为implements)。 Java语言全面支持动态绑定,而C++ 语言只对虚函数使用动态绑定。 总之,Java语言是一个纯的面向对象程序设计语言。 3、Java语言是分布式的。 Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、 ServerSocket等。 Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。 4、Java语言是健壮的。 Java的强类型机制、异常处理、废料的自动收集等是Java程序健壮性的重要保证。 对指针的丢弃是Java的明智选择。 Java的安全检查机制使得Java更具健壮性。 5、Java语言是安全的。 Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。 除了Java语言具有的许多安全特性以外,Java对通过网络下载的类具有一个安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类SecurityManager)让Java应用设置安全哨兵。 6、Java语言是体系结构中立的。 Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件), 然后可以在实现这个Java平台的任何系统中运行。 这种途径适合于异构的网络环境和软件的分发。 7、Java语言是可移植的。 这种可移植性来源于体系结构中立性,另外,Java还严格规定了各个基本数据类型的长度。 Java系统本身也具有很强的可移植性,Java编译器是用Java实现的,Java的运行环境是用ANSI C实现的。 8、Java语言是解释型的。 如前所述,Java程序在Java平台上被编译为字节码格式, 然后可以在实现这个Java平台的任何系统中运行。 在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。 9、Java是高性能的。 与那些解释型的高级脚本语言相比,Java的确是高性能的。 事实上,Java的运行速度随着JIT(Just-In-Time)编译器技术的发展越来越接近于C++。 10、Java语言是多线程的。 在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。 通常有两种方法来创建线程:其一,使用型构为Thread(Runnable) 的构造子将一个实现了Runnable接口的对象包装成一个线程,其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。 值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。 线程的活动由一组方法来控制。 Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。 11、Java语言是动态的。 Java语言的设计目标之一是适应于动态变化的环境。 Java程序需要的类能动态地被载入到运行环境,也可以通过网络来载入所需要的类。 这也有利于软件的升级。 另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。 Java语言的优良特性使得Java应用具有无比的健壮性和可靠性,这也减少了应用系统的维护费用。 Java对对象技术的全面支持和Java平台内嵌的API能缩短应用系统的开发时间并降低成本。 Java的编译一次,到处可运行的特性使得它能够提供一个随处可用的开放结构和在多平台之间传递信息的低成本方式。 特别是Java企业应用编程接口(Java Enterprise APIs)为企业计算及电子商务应用系统提供了有关技术和丰富的类库。

如何对memcache的数据进行遍历操作

下面贴上一段php实现的遍历memcache数据的代码,其他语言可以参考代码自己实现。 1. 转载

请帮忙解释电脑中Web指的是什么?

WEB标准不是某一个标准,而是一系列标准的集合。 网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为(Behavior)。 对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如W3C DOM)、ECMAScript等。 这些标准大部分由W3C起草和发布,也有一些是其他标准组织制订的标准,比如ECMA(European computer Manufacturers Association)的ECMAScript标准。 我们来简单了解一下这些标准: 1.结构标准语言 (1)XML XML是The Extensible Markup Language(可扩展标识语言)的简写。 目前推荐遵循的是W3C于2000年10月6日发布的XML1.0,参考(/TR/2000/REC-XML-)。 和HTML一样,XML同样来源于SGML,但XML是一种能定义其他语言的语。 XML最初设计的目的是弥补HTML的不足,以强大的扩展性满足网络信息发布的需要,后来逐渐用于网络数据的转换和描述。 关于XML的好处和技术规范细节这里就不多说了,网上有很多资料,也有很多书籍可以参考。 (2)XHTML XHTML是The Extensible HyperText Markup Language可扩展标识语言的缩写。 目前推荐遵循的是W3C于2000年1月26日推荐XML1.0(参考)。 XML虽然数据转换能力强大,完全可以替代HTML,但面对成千上万已有的站点,直接采用XML还为时过早。 因此,我们在HTML4.0的基础上,用XML的规则对其进行扩展,得到了XHTML。 简单的说,建立XHTML的目的就是实现HTML向XML的过渡。 2. 表现标准语言 CSS是Cascading Style Sheets层叠样式表的缩写。 目前推荐遵循的是W3C于1998年5月12日推荐CSS2(参考)。 W3C创建CSS标准的目的是以CSS取代HTML表格式布局、帧和其他表现的语言。 纯CSS布局与结构式XHTML相结合能帮助设计师分离外观与结构,使站点的访问及维护更加容易。 3.行为标准 (1)DOM DOM是Document Object Model文档对象模型的缩写。 根据W3C DOM规范(),DOM是一种与浏览器,平台,语言的接口,使得你可以访问页面其他的标准组件。 简单理解,DOM解决了Netscaped的Javascript和Microsoft的Jscript之间的冲突,给予web设计师和开发者一个标准的方法,让他们来访问他们站点中的数据、脚本和表现层对像。 (2) ECMAScript ECMAScript是ECMA(European Computer Manufacturers Association)制定的标准脚本语言(JAVAScript)。 目前推荐遵循的是ECMAScript 262()。 参考资料:

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐