可伸缩与高可用设计

火烧云 2013-03-11

1 通过依靠升级硬件支撑访问量、数据量增长的方式成为垂直伸缩。他的优势是方便,无需改造软件;缺点是硬件升级很快会达到瓶颈、并且购买硬件的成本会指数级上升。

通过增加机器数量来支撑访问量、数据量增长的成为水平伸缩。缺点是对技术有较高的要求,并且对机房的空间占用、机房维护费用的增长。我们希望水平伸缩是线性的,即N台机器可以支持N倍的访问量、数据量。不过实际情况始终是会遇到瓶颈。

2 垂直伸缩

cpu增加后,需要考虑线程数调整,锁的竞争;增加内存需要考虑,cache大小的调整、jvm内存参数的调整。数据增加、单表数量增加后,再好的数据库也会成为瓶颈;当数据量变大的时候,就需要考虑分库分表的方案。优点是单表数据量减少,并发能力更强,缺点是开发难度增大(需要借助DAL,如tddl),无路由字段无法查询。

3 水平伸缩

水平伸缩的最优方案是采用无共享架构SNA,把共享的数据放入到集中式的存储,如数据库、缓存。否则,必须对机器间数据进行同步。如广播同步Jgroup。当数据量小的时候,是个不错的方法;但是当数据量大的时候,同步开销会很大,同步延迟也会很大。所以如果要做到水平伸缩,最好还是需要搭建一个分布式缓存和分布式文件系统,还有一些读写分离的策略。

4 单点避免

采用集群技术避免单点故障,集群由一组提供同样功能的计算机组成,对于外部访问而言就好像是访问单台机器一样。

集群技术需要克服,把请求均匀地分摊到每台机器,当有机器挂掉时,要保证用户不会访问到。

一般都会用到负载均衡器,有采用硬件负载均衡,也有采用软件负载均衡,他们都需要在集群前面配置一台负载均衡器。用户请求先到负载均衡器,然后再由负载均衡器选择某台业务机器发送请求。为了避免负载均衡器成为单点,一般也需要一主一备,一台提供服务,当挂掉的时候standby的那台自动接管。

负载均衡器需要知道所有业务机器的ip地址,一般是采用直接配置的方式。

负载均衡的方式有:

  • 随机,实现简单,如果请求消耗的资源相近,机器配置相近,那么随机是最优的
  • hash,针对url做hash,好处是如果使用缓冲的话会提高缓存命中率,缺点是对负载均衡器消耗较大,需要读取第七层信息,并做hash运算。
  • round-robin选择,按地址列表顺序选择。由于要保持顺序,所以需要同步操作,不过开销小,大部分的软件、硬件均衡器都支持,使用广泛,效果和随机差不多
  • 权重选择,按照机器配置分配权重;动态权重,按照机器的负载来,有消耗、有延迟,一般不用。
  • 按load、连接数选择,保持每台机器均衡

响应返回方式:

  • 通过负载均衡器返回,会造成均衡器负载过高。
  • 响应直接返回到请求方,可以采用ip隧道或者Direct routine,他们都需要特定的机器和环境的支持。

硬件负载均衡器,较为著名的有F5、netscalar,他们通过一主一备的方式来提供服务。直接通过硬件芯片来做计算,效率很高、且稳定。

软件负载均衡器,较为著名的有LVS、HaProxy

热备,使用多机房,需要解决机房间的状态同步问题。

5 应用自身的稳定性

  • 避免过度设计,过度设计会使系统变复杂,容易出bug
  • 快速失败,如果强依赖的服务有问题,应该直接启动失败,不能让应用以错误的状态提供服务,让开发人员及时发现问题。
  • 接口和设计对象的严谨性。
  • 对依赖服务保持悲观策略,做好容错处理,把损失降低到最小。
  • 限制内存使用,关注集合的容量、及时把引用置为null
  • 限制文件使用,并发写文件会竞争文件锁,会导致应用性能剧减
  • 限制网络使用,连接资源和操作系统的sendbuffer都是有限的
  • 限制线程使用,线程要消耗内存,并且产生上下文切换。如果要使用多线程,尽量用jcu提供的线程池,要注意过多的runnable放入阻塞队列冲爆内存,最好是直接使用new ThreadPoolExecutor传入合适的参数。
  • 及时发现故障,监控和报警机制。

相关推荐

gamezouni / 0评论 2013-07-28