采用分布式系统架构是由于业务需求决定的,若系统要求具备如下特性,便可考虑采用分布式架构来实现:

1.数据存储的分区容错,冗余

2.应用的大访问、高性能要求

3.应用的高可用要求,故障转移

分布式系统遵循几个基本原则

1.CAP原理

CAP Theorem,CAP原理中,有三个要素:
一致性(Consistency)
可用性(Availability)
分区容忍性(Partition tolerance)
CAP原理指的是,在分布式系统中这三个要素最多只能同时实现两点,不可能三者兼顾。因此在进行分布式架构设计时,必须做出取舍。而对于分布式数据系统,分区容忍性是基本要求,否则就失去了价值。因此设计分布式数据系统,就是在一致性和可用性之间取一个平衡。对于大多数web应用,其实并不需要强一致性,因此牺牲一致性而换取高可用性,是目前多数分布式数据库产品的方向。
从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
但web应用也有例外,比如支付宝系统,就要求数据(银行账户)的强一致性,而且面对大量淘宝用户,可用性要求很高,因此只能牺牲数据的分区冗余。这一点也曾在和支付宝工程师交流时,得到验证。
2.C10K问题
分布式系统另一个理论是C10K问题,即系统的并发用户增加1万(customer ten thousand,过去一台服务器承载假设为1万用户,现在平均3~5万),是否意味着增加一台机器就能解决问题?答案通常是否定
因为这涉及到系统的应用架构问题----串行系统和并行系统的架构和性能提升的关系:
串行系统一般设备越多,性能成一条向下弯曲的曲线,最差情况,可能性能不增反降;而并行分布式系统设备越多,性能是正比例线性增长的直线
3.串行系统和并行系统的可靠性问题
一个大系统一般都有超过 30 个环节(串行):如果每个环节都做到 99% 的准确率,最终系统的准确率是 74%; 如果每个环节都做到98%的准确率,最终系统的准确率 54%。一个 74% 的系统是可用的(有商业价值的),一个 54% 的系统仅比随机稍好一点,不可用。这就是做大系统的魅力和挑战!
而以上描述只是各模块串行系统所遇到的问题
如果是并行系统,准确率=1-(1-A)^B ,其中A是单个模块准确率,B是并行模块个数
如系统中每个模块的准确率是70%,那么3个模块并行,整体准确率=1-0.3^3=97.3%,如果是4个并行,准确率=1-0.3^4=99.19%,我在想这就是负载均衡靠谱的数学原理

5个9或6个9的QoS一定是指数思维的结果,线性思维等于送死
而对系统单一模块优化,准确性和可用性提升一个百分点,越接近100%,难度越大,投入成本越不可控(系统熵永不为零)
因此可靠性系统必然选择并行分布式作为架构的基本方法。
从数据的存储角度,多份冗余也是可靠性保障的一个方法。分布式存储的冗余备份常规是3份(aws就这么干的),古埃及的罗塞塔rosetta石碑用古埃及象形文字、埃及拼音和古希腊文三种文字记录一段历史,就算象形文字缺了一部分,没人能看懂,也能破译补全,这大概也是raid5的思想起源吧

分布式系统架构的实践

1.分布式存储架构

分布式存储架构现阶段有3种模式

 1.1一种是物理存储采用集中式,存储节点采用多实例的方式,如NFS挂载SAN、NAS等等



1.2第二种是带有中央控制器的分布式存储,如luster、moosefs、googlefs等等,一般特征是具备2个角色metadata server和storage node,将文件的元数据(描述数据的数据,如文件位置、大小等等)和数据块文件分开存储
其中metadata server除保存文件的元数据外,还维护存储节点的ip、状态等信息
luster的典型架构
MDS--meatadata server
MDT--metadata target
OSS--obj storage server
OST--obj starage target
其中MDT和OST是可以挂在NAS等中央存储上的;可见,luster借鉴了上面中央存储的模式,无论元数据服务还是节点服务都将服务实例和存储分离,但进化了一步,将元数据和数据块分离
luster系统很好解决了数据分布式存储,,在超级计算领域Lustre应用广泛,如美国LLNL国家实验室计算机系统、我国的天河超级计算机系统均采用Lustre搭建分布式存储系统。Lustre在全球排名前30个超级计算机系统中有15个在使用。
但有一个问题,就是metadata server的SPoF(single point of failure)问题,即单点故障;一旦metadata server挂了,整个集群也就挂了。实际应用中,是有解决方案的,如dell的官网有个pdf,就是采用heart beat和drbd网络raid的方式,启动2个实例,再如和keepalived一起组成故障转移的方案等等,可以自己试试
再来看moosefs架构
moosefs架构和luster很相似,但进化了一步,mater(也就是metadata server)可以有从机备份了,而且可以多个
而且服务实例和存储放在一起,没有像luster,自此服务和数据不离不弃了;其实luster也可以简化成不离不弃模式,moosefs也可以学他搞个后端存储,但随着云计算、追求低成本的趋势,采用SAN这样存储设备就太贵了
1.3第三种分布式存储是去中心化、全对称的架构(non-center or symmetric)
其设计思想是采用一致性哈希consistent hash算法(DHT的一种实现,关于一致性hash具体参考后面的链接)来定位文件在存储节点中的位置,从而取消了metadata server的角色
整个系统只有storage node一个角色,不区分元数据和数据块;
典型系统如sheepdog,但sheepdog是为满足kvm镜像和类EBS块存储而设计的,不是常规的分布式文件系统,架构如下

为了维护存储节点的信息,一般采用P2P技术的totem single ring算法(corosync是一种实现)来维护和更新node路由信息
对称架构有一个问题,采用totem single ring算法的存储节点数量有限,因为node数量超过1000,集群内的通信风暴就会产生(此处更正,应该是环太大,令牌传递效率下降,不会产生通信风暴),效率下降,sheepdog提出了一个解决方案,就是在一致性hash环上做嵌套处理,如图
1.4半对称结构
其实介于1.2metadata server中央控制和1.3全对称的架构之间还有一种,就是把metadata也做成对称结构,我们可以称半对称结构,典型应用如fastdfs,淘宝一大牛fishman写的,主要用作图片存储,可以实现排重存储
看图,tracker cluster就是metadata server的角色,实现了对称架构设计
国内几个大的网站都使用了fastdfs,在实际使用中,发现storage server之间同步数据较慢,一直没仔细研究

2.分布式数据库
分布式数据库一般都基于分布式文件系统实现数据的分片sharding,每中数据库都有自己的应用特性,就不做介绍,列出几个典型的应用,供参考
Google的big table,实现数据的追加存储append,顺序写入快速,不适合随机读的场景
hadoop的HBase
mongodb
hypertable 2010年以前,百度在用,今年infoq的中国qcon,百度的杨栋也讲了百度用hypertable的血泪史
3.分布式应用架构
分布式应用架构涉及具体应用场景,设计上除考虑上面的CAP和C10K等等经典分布式理论,还应根据业务进行权衡。
基本的思路是
3.1在做完需求和模块设计后,要对各模块进行解藕Decoupling
传统的企业应用设计一般是一条操作从头跑到尾(串行系统),拿视频网站的流程距离,传统应用设计是先上传是视频,然后存储,编码,最后发布一条龙
如下图
3.2在进行分布式设计时,先将各模块解藕,通过异步消息通知的方式将各模块链接,如下图
3.3最后,要考虑这个应用的压力承载点在哪,根据用户规模估算各模块的并行数量(如本例中的encode压力大,就增加encode模块的并行系统数量),如下图
以上是分布式系统构建的基本原则和实践步骤,在实际应用中,仍有很多细节要考虑。但有一点要再强调,就是要根据业务来选择各层、各模块的技术,做好业务适用、成本和难度之间的权衡
技术本无好坏,在于适当的使用和积累。

参考:
moosefs http://www.moosefs.org
luster http://wiki.whamcloud.com/display/PUB/Wiki+Front+Page
一致性hash http://baike.baidu.com/view/1588037.htm & http://stblog.baidu-tech.com/?p=42
fastdfs http://code.google.com/p/fastdfs/wiki/Overview

分布式系统架构的基本原则和实践相关推荐

  1. 《架构设计2.0大型分布式系统架构方法论与实践》三高笔记

    目录 前言 高并发 高并发读 动静分离与CDN加速 缓存 并发读与Pipeline 重写轻读 读写分离 批量 高并发写 数据分片 任务分片 异步化 批量 高可靠 七板斧 高可用 高可用架构几个核心问题 ...

  2. 左耳朵耗子:聊聊分布式系统架构

    点击关注 InfoQ,置顶公众号 程序员的 8 点技术早餐 作者|陈皓 编辑|杨爽 学习任何技术,善于提纲挈领总是事半功倍.学习分布式系统架构也是如此,只要找到这张网的纲,就能更有效率地做好架构和工程 ...

  3. 美团即时物流的分布式系统架构设计

    背景 美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验.最主要的收获包括两点: 即时物流业务对故障和高延迟的容忍度极低 ...

  4. 美团外卖分布式系统架构设计

    背景 美团外卖已经发展了五年,即时物流探索也经历了3年多的时间,业务从零孵化到初具规模,在整个过程中积累了一些分布式高并发系统的建设经验.最主要的收获包括两点: 即时物流业务对故障和高延迟的容忍度极低 ...

  5. 分布式系统架构与云原生—阿里云《云原生架构白皮书》导读

    -点击领取<云原生架构白皮书>- 导语: 有幸作为阿里云MVP提前获得了阿里云云原生团队编写的<云原生架构白皮书>,希望通过自己对于云原生的理解为开发者提供一篇观后感或者是能够 ...

  6. 大规模 Node.js 网关架构设计与工程实践

    作者:王伟嘉,腾讯云 CloudBase 前端负责人. 本文是王伟嘉在 GMTC 2021 全球大前端技术大会(深圳站)上的演讲内容:<十亿级 Node.js 网关的架构设计与工程实践>. ...

  7. 《大规模分布式系统架构与设计实战》

    <大规模分布式系统架构与设计实战> 基本信息 作者: 彭渊 丛书名: 大数据技术丛书 出版社:机械工业出版社 ISBN:9787111455035 上架时间:2014-2-21 出版日期: ...

  8. #分布式系统架构之# 事件驱动模式以及与之匹配的长时间处理过程讨论

    为什么80%的码农都做不了架构师?>>>    在分布式系统下,可以很多种架构从事设计,或者分布式系统对技术架构本身没有做严格的限制.但是结合自己的实践以及基于<领域驱动设计& ...

  9. 腾讯云十亿级 Node.js 网关的架构设计与工程实践

    作者|王伟嘉 编辑|孙瑞瑞 本文由 InfoQ 整理自腾讯云 CloudBase 前端负责人王伟嘉在 GMTC 全球大前端技术大会(深圳站)2021 上的演讲<十亿级 Node.js 网关的架构 ...

最新文章

  1. [分享] 数学学术资源站点
  2. RabbitMQ之惰性队列(Lazy Queue)
  3. spring boot 单元测试_spring-boot-plus1.2.0-RELEASE发布-快速打包-极速部署-在线演示
  4. Java基础笔记 – Annotation注解的介绍和使用 自定义注解
  5. .NET简谈组件程序设计之(渗入序列化过程)
  6. ubuntu 设置定时任务
  7. 数据结构第三章栈和队列(一)
  8. phpstorm配置ftp,自动更新代码
  9. nios IIcommand shell 烧录
  10. 如何在Word中画横线?
  11. Matlab syms 矩阵变量,matlab syms.m
  12. 自动化爬取网贷黑名单
  13. pgsql 日期转换
  14. 确定权重方法之一:主成分分析
  15. 图片文字转换为文本怎么做?图片转文本的简单方法介绍
  16. IDEA工具避坑指南(七):git@github.com: Permission denied|You must supply a key in OpenSSH public key format详解
  17. B. Dubious Cyrpto
  18. Element-Ui组件 Radio 单选框 修改点击激活时的文本颜色,填充色和边框色
  19. VB / VBA 自制二维码小工具
  20. Android的鼠标事件流向

热门文章

  1. Java 算法 传球游戏
  2. AC自动机(python)
  3. 250php货币,FreeHostia免费PHP空间中文面板250MB空间6GB流量
  4. 九 web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解...
  5. 关于 iOS 证书,你必须了解的知识
  6. MANIFEST.MF的用途(转载)
  7. codeblocks 调试
  8. Visio 2007中进行数据库建模时如何显示字段类型以及概念名称
  9. linux调整zram大小,ZRAM将在Linux5.1上看到更高的性能-它改变了默认的压缩器
  10. java 泛型 比较_java 泛型和object比较