日暮途远

日暮途远,涸辙难行;东隅已逝,桑榆非晚

Java开源世界里面的分布式(一)

前言

随着互联网的高速发展,大型网站的访问量也开发爆发性的增长,各种高并发访问、海量数据处理等场景越来越多,传统的集中式系统架构已经越来越难以应付新的业务发展。如何实现网站的高可用、易伸缩、可扩展、安全等目标就显得越来越重要,为了解决这样一系列问题,大型网站的架构也在不断发展。
在初期,传统方式中增加集中式产品的容量,提高服务器性能与配置,以高昂的硬件成本来为高增长买单尚可接受,但当增长到一定的量级后,这种方式不管是在成本控制,还是扩展的瓶颈上都已经难堪大任,必须找到一种新的解决方案来替换。而在发展的过程中,从集中式变迁到分布式应用将不可避免,也是一个非常合理的变迁。
伴随着互联网的高速发展所带来的传统构架的困扰,开源软件近年来已变为构建一些大型网站的基础组件,并且随着开源的成长,围绕着它们架构的最佳实践和指导准则已经显露。

我常常在想,如果公司没有成熟的方案,而是软件构架方面一片空白,要在开源的基础上从头到尾重新设计一套分布式应用,该如果下手?业界有哪些优秀的实践?各个开源产品该如何选型?各个产品之间能否很好的融合?

本文将从一个传统架构向分布式应用转变的角度来探讨Java开源世界里面对于分布式应用的各个方面的一些优秀的开源软件,以及相对应的最佳实践及准则。(当然,分布式是一个很广的概念,涉及到系统的方方面面,而每一方面都有很多不同的解决方案,这里也只是跟大家一起讨论一下我所了解到的、或者从其它地方学习到的一些知识与观点,与大家共同研讨与学习,多多挖掘Java开源世界里的宝藏)
最后,将会列出一张完整的由开源产品组成的架构设计图,当然,也仅仅是列出个可以整合在一起的整体架构图。就好比:根据宴席的档次,采用最少的原料,列出一份合理的,可以互相辉映、融合的菜单。而具体的各个菜式详细制作(开发)方式,以及摆放(运维)的位置则需要后续不断的学习与探讨(还是那句话,分布式水很深,每一步都不容易)。

分布式概览

在《分布式系统概念与设计》一书中,对分布式系统做了如下定义:

分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统

简单来说就是一群独立计算机集合共同对外提供服务,但是对于系统的用户来说,就像是一台计算机在提供服务一样。从分布式系统的概念中我们知道,各个主机之间通信和协调主要通过网络进行,所以,分布式系统中的计算机在空间上几乎没有任何限制,这些计算机可能被放在不同的机柜上,也可能被部署在不同的机房中,还可能在不同的城市中,对于大型的网站甚至可能分布在不同的国家和地区。
但是,无论空间上如何分布,一个标准的分布式系统应该具有以下几个主要特征:

  1. 分布性

分布式系统中的多台计算机之间在空间位置上可以随意分布,系统中的多台计算机之间没有主、从之分,即没有控制整个系统的主机,也没有受控的从机。

  1. 透明性

系统资源被所有计算机共享。每台计算机的用户不仅可以使用本机的资源,还可以使用本分布式系统中其他计算机的资源(包括CPU、文件、打印机等)。

  1. 同一性

系统中的若干台计算机可以互相协作来完成一个共同的任务,或者说一个程序可以分布在几台计算机上并行地运行。

  1. 通信性

系统中任意两台计算机都可以通过通信来交换信息。

从以上几个方面可以总结出,跟传统的集中式构架设计相比,有2点认识在今后的分布式构架设计过程中非常非常的重要:

网络是不透明的
在传统的构架设计过程中,我们所有的应用都运行在单一的环境中,不具有“通信性”,我们认为网络是透明的,不会因为与其它机器的通信而导致错误。
但是在分布式应用中,网络的不透明性确是至关重要,则是非常繁琐难以处理的,如果你简单的翻看一下JDK中的关于网络的异常就可见一斑,仅仅这个 RemoteException 的自带子类就有20多个。

java.rmi.RemoteException

局部性错误
RMI的真正问题在于这些调用可能会出现局部性失败的情况。比如,调用可能会在对其他层的请求操作执行前失败,又或者请求成功了,但之后的返回值又不正确。引起这类局部性失败的原因非常多。其实,这些故障模式正是分布式系统特性的明确定义:

“分布式系统就是某一台你根本意识不到其存在的计算机,它的故障会造成你的计算机无法正常使用。”  ——  Leslie Lamport

还好,Java是一个开源的世界,在这个开源的世界里面,有许许多多优秀的开源 产品,已经很好的帮我们解决了这些底层繁琐,复杂的设计问题,让我们可以站在这些巨人的肩膀上完善我们的产品,架构我们的系统。

Web分布式系统设计准则

摘自:http://aosabook.org/en/distsys.html
构建和运行一个可伸缩的网站或应用来说究竟意味着什么?从一个基本的层面来看,就是将用户和远程资源通过互联网连接起来——将其变得可伸缩的部分,是指这些资源或者访问这些资源是分布式的、贯穿于多个服务器。像很多生活中的事情一样,在构建一个web服务时花费时间提前做好计划将会帮助服务能够长久运行;理解一些大型网站背后的考量和权衡会在创建小型网站时帮助做出更明智的决定。下面是一些会影响到设计大型可伸缩性Web系统的关键准则:

可用性
一个网站的正常运行时间,对于很多公司的信誉和功能来说都是至关重要的。对于一些大型在线零售网站,甚至是几分钟的不可用都会导致数以千万计美元的收入损失,所以将他们的系统设计成不间断可用和能够弹性恢复既是一项基础业务也是一个技术需求。分布式系统的高可用性需要仔细考虑关键组件冗余,快速恢复部分有问题的系统,并且当出现问题时能够做到优雅降级。

性能
性能已成为大多数网站一个很重要的考量指标。一个网站的速度会影响到使用和用户满意度,同样也会影响到搜索引擎排名,将直接关系到网站收入和用户保持力(黏性)。因此,关键之处就在于创建一个为快速响应、低延迟的系统。
可靠性
一个系统需要做到可靠,这样才能使得对于(固定)数据的请求始终会返回同样的数据。如果数据发生变化或者更新,那相同的请求应该返回新的数据。用户需要知道,一旦一些数据被写入、存储到系统中,那么系统就会持久化(这些数据)并且能够让人信赖随时能够检索。

可伸缩性
对于任何大型分布式系统,系统规模只是可伸缩性需要考虑的一个方面。同样重要的是,增加容量能够处理更大量的负载所需的工作,通常在系统可伸缩性方面被提及到。可伸缩性会涉及到系统的很多不同的因素:系统额外还能够处理多少流量,是否能够轻易增加存储容量,还能多处理多少事务。

可管理性
设计一个易于运维的系统是另一个重要考量点。系统的可管理型等同于操作的可伸缩性:维护和变更。可管理性需要考虑的有:当问题发生时能够便于诊断和理解,便于进行变更和修改,并且系统易于操作。(比如系统是否能够进行例行操作而不带来失败或者异常?)

 成本 
成本是一个重要因素。这明显会包括硬件和软件成本,但同样还要考虑到一些其他方面来部署、运维系统,比如构建系统所需的开发时间,运行系统所需的运维工作量,甚至所需的培训都要被考虑在内。
这些准则中的每一条都提供了在设计一个分布式web系统架构时作决定的基本原则。但是,他们也可能互相矛盾,比如达到某一目标是以牺牲另一个为代价的。一个典型的例子:专注于系统容量时,选择通过简单增加更多机器(可伸缩性)的代价是(增加了)可管理性(你需要运维更多的服务器)和成本(更多服务器价格)。当设计任何web应用时,这些关键准则都是需要考量的,即使不得不承认,一个设计可能会牺牲它们中的一个或更多。

相关的开源产品

_
我们将按照前文所述的分布式设计原则,以及上图中的相关技术,从一个 Web 网站从前到后,来一一探讨这些开源产品,以及其所在业界中的地位,最佳实践。
图中所列的并不各个领域唯一(或者)全部的开源产品,而我所了解到的,或者目前业界(Java)广泛使用的产品。从前到后依次如下:

  1. 负载均衡
  2. CDN
  3. 分布式 session
  4. 调度协调
  5. 分布式缓存
  6. 远程调用RMI
  7. 分布式数据层
  8. 分布式存储
  9. 分布式搜索
  10. 任务调度
  11. 异步通信
  12. 分布式事务
  13. 监控
  14. 备份/容灾

待续……

点赞
  1. 明朝第一号大公公说道:

    后面的文章呢,咋找不到?太监了? :redface:

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">