刚看了阿里技术大牛毕玄《分布式领域架构师要掌握的技术》,里面讲到,架构师在设计分布式系统须要重点考虑如下四方面:算法
一、通讯网络
首先要掌握一些基础知识,例如网络通讯协议(诸如TCP/UDP等等)、网络IO(Blocking-IO,NonBlocking-IO、Asyn-IO)、网卡(多队列等);更偏应用的层面,须要了解例如链接复用、序列化/反序列化、RPC、负载均衡等。架构
学了这些基本知识后,基本上能够写一个简单的分布式系统里的通讯模块,但这其实远远不够,既然进入了分布式领域,对规模其实就已经有了不低的要求,一般也就意味着须要的是能支持大量链接、高并发、低资源消耗的通讯程序。并发
大量的链接一般会有两种方式:负载均衡
1. 大量client连一个server分布式
在现现在NonBlocking-IO这么成熟的状况下,一个支持大量client的server已经不那么难写了,但在大规模,而且一般长链接的状况下,有一个点要特别注意,就是当server挂掉的时候,不能出现全部client都在一个时间点发起重连,那样基本就是灾难,在没有经验的状况下我看过好几起相似的case,到client规模上去后,server一重启基本就直接被冲进来的大量建连冲垮了(固然,server的backlog队列首先应该稍微设置大一些),一般能够采用的方法是client重连前都作随机时间的sleep,另外就是重连的间隔采起避让算法。高并发
2. 一个client连大量的server工具
有些场景也会出现须要连大量server的现象,在这种状况下,一样要注意的也是不要并发同时去建全部的链接,而是在能力范围内分批去建。线程
除了建链接外,另外还要注意的地方是并发发送请求也一样,必定要作好限流,不然很容易会由于一些点慢致使内存爆掉。设计
这些问题在技术风险上得考虑进去,并在设计和代码实现上体现,不然一旦随着规模上去了,问题一时半会还真不太好解。
高并发这个点须要掌握CAS、常见的lock-free算法、读写锁、线程相关知识(例如线程交互、线程池)等,通讯层面的高并发在NonBlocking-IO的状况下,最重要的是要注意在总体设计和代码实现上尽可能减小对io线程池的时间占用。
二、伸缩性
伸缩性的问题围绕着如下两种场景在解决:
1. 无状态场景
对于无状态场景,要实现随量增加而加机器支撑会比较简单,这种状况下只用解决节点发现的问题,一般只要基于负载均衡就能够搞定,硬件或软件方式都有;
无状态场景一般会把不少状态放在db,当量到必定阶段后会须要引入服务化,去缓解对db链接数太多的状况。
2. 有状态场景
所谓状态其实就是数据,一般采用Sharding来实现伸缩性,Sharding有多种的实现方式,常见的有这么一些:
2.1 规则Sharding
基于必定规则把状态数据进行Sharding,例如分库分表不少时候采用的就是这样的,这种方式支持了伸缩性,但一般也带来了很复杂的管理、状态数据搬迁,甚至业务功能很难实现的问题,例如全局join,跨表事务等。
2.2 一致性Hash
一致性Hash方案会使得加机器代价更低一些,另外就是压力能够更为均衡,例如分布式cache常常采用,和规则Sharding带来的问题基本同样。
2.3 Auto Sharding
Auto Sharding的好处是基本上不用管数据搬迁,并且随着量上涨加机器就OK,但一般Auto Sharding的状况下对如何使用会有比较高的要求,而这个一般也就会形成一些限制,这种方案例如HBase。
2.4 Copy
Copy这种常见于读远多于写的状况,实现起来又会有最终一致的方案和全局一致的方案,最终一致的多数可经过消息机制等,全局一致的例如zookeeper/etcd之类的,既要全局一致又要作到很高的写支撑能力就很难实现了。
即便发展到今天,Sharding方式下的伸缩性问题仍然是很大的挑战,很是很差作。
三、稳定性
做为分布式系统,必需要考虑清楚整个系统中任何一个点挂掉应该怎么处理(到了必定机器规模,天天挂掉一些机器很正常),一样主要仍是分红了无状态和有状态:
1. 无状态场景
对于无状态场景,一般好办,只用节点发现的机制上具有心跳等检测机制就OK,经验上来讲无非就是纯粹靠4层的检测对业务不太够,一般得作成7层的,固然,作成7层的就得处理好规模大了后的问题。
2. 有状态场景
对于有状态场景,就比较麻烦了,对数据一致性要求不高的还OK,主备类型的方案基本也能够用,固然,主备方案要作的很好也很是不容易,有各类各样的方案,对于主备方案又以为不太爽的状况下,例如HBase这样的,就意味着挂掉一台,另一台接管的话是须要必定时间的,这个对可用性仍是有必定影响的;
全局一致类型的场景中,若是一台挂了,就一般意味着得有选举机制来决定其余机器哪台成为主,常见的例如基于paxos的实现。
四、可维护性
维护性是很容易被遗漏的部分,但对分布式系统来讲实际上是很重要的部分,例如整个系统环境应该怎么搭建,部署,配套的维护工具、监控点、报警点、问题定位、问题处理策略等等。