软件架构在成功的软件交付中扮演着重要角色,好的架构可以兼容不同类型的业务和算法,并且相安无事,而架构设计不当就需要不断地进行整体的更替,以适应业务的变化和新算法的需求,甚至影响最后架构整体的稳定性、容量等。事实上,架构的很多方向性问题是可以在设计初期就避免的。因此,七牛首席架构师李道兵结合多年的实践经验,在本文中详细总结出了以下七类具有明显“坏味道”的架构影响因素。
架构对容量数据不敏感
设计架构时对于常规的一些基础架构元素容量不清晰,比如前端的Nginx、后端标准的业务服务器、数据库及缓存的容量等方面。Nginx整体容量比较大,一般不需要担心。如果是下载类型的需求,那么需要注意机器的网卡。到业务逻辑这一段,每种语言、每个并发连接都有内存消耗,会导致单台服务器能支撑的并发数目是有限的。在数据库领域,系统容量跟磁盘的IOPS相关,因此最好知道普通的SATA盘和SSD盘的IOPS是多少?做RAID10或者是RAID5对IOPS的影响究竟是怎样的(因为IOPS对数据库的性能影响很大)。还有缓存层,但缓存层更重要的是容量的设计(即内存总量),因此,要对各个架构元素容量的数据有一定了解,才能保证构造出的架构在容量上不会出问题。
未考虑高可用
如果架构设计的时侯只想着怎样实现业务逻辑,完全没有考虑主机宕机了怎么解决,那么迟早会遇到事故。因此,架构需要从入口层、业务层、缓存层和数据库层构建高可用和可伸缩系统。例如,在入口层使用Keepalived;业务层不要有状态,将状态存储到缓存层或数据库;缓存层考虑挡住绝大部分服务请求以提升系统整体容量,但同时也要考虑高可用的问题;数据库层做一个主从模式 《七牛李道兵:高可用可伸缩架构实用经验谈》 一文有详细讲述。架构设计重要的是有考虑高可用的意识,有意识以后再考虑如何实现就会比较容易。
用Hash来避免机器宕机时影响到所有用户
这个问题主要由于想做高可用,但却用了错误的方法。比如有很多用户,根据用户的Hash把它们分到不同的服务器,这样单台服务器宕掉的时侯就不会影响到所有的业务。但这种方法并不够好,因为即使小部分用户的体验受到了影响,也已经构成事故。另外,如果服务分很多层,这层做高可用漏掉一部分客户,另一层漏掉另外一部分客户,那么整体的可用性会变得很差,出故障的概率就是各层出故障概率之和。目前有很多更简单的方式来做高可用,所以没有必要使用Hash这种方式。另外,用Hash来分散请求比较容易导致压力不均,反而降低了整个系统的容量。
缓存节点数太少
很多人认为缓存是一个可选的环节,在设计上就比较随意,但这会带来一定的问题。比如一个缓存节点宕掉,将导致这个缓存节点的压力压到数据库上面。如果系统的容量原本就是靠缓存支撑,缓存又只分布在两台机器上,那么宕掉一台对后面的数据库的压力很大,数据库响应变差,那么宕掉缓存节点也就意味着服务真的宕机。因此,建议将缓存尽量分开,比如和业务服务器混合部署,当业务服务器在增长时,缓存也在增长,这时保证缓存节点多一点,单台缓存机死机了压力到了数据库也不会导致数据库宕机。当然,Codis这类自带高可用的缓存系统也是一个很好的选择。
有容灾无容错
首先,应分清容灾和容错的差别。容灾指,出了事故(如单磁盘故障、单数据故障、机柜故障或者机房故障)时的保障措施。容错则指,操作失误(如运维的错误操作),这种错误操作导致了数据丢失,或者别人通过SQL注入的方法删除了数据库。身边有一个真实的例子,一家公司用MongoDB数据库,由于MongoDB的ReplicaSet机制,所以觉得不用做备份了,就未做备份。但这里他们没有考虑到,如果有人失手删除了数据库该怎么办,这时所有数据都丢掉了,是一件非常恐怖的事情。
架构失配的问题
MongoDB支持文件存储,但它并不擅长,容量会受到很大的限制,一旦上传量增大就可能会引发事故。因此,最好在各个环节找一些最恰当的方式。例如,Redis擅长的是缓存而不是数据库,那么用Redis做数据库就必然会出现架构失配的问题;而MongoDB擅长的是OLTP,用MongoDB去支撑数据仓库就不太合适;像MySQL这类事务型数据库也可以去做一些离线计算,但如果要做很多离线计算的工作,就需要用最好的工具去做(如Hadoop、Hive、Spark等),在每一个架构环节都要有最合适的架构组件,避免出现一些架构失配的问题。
数据流太长
这种情况常出现于存储领域。数据流太长就很难保证响应,如果一份数据中转了10次,与中转3次相比,内网的带宽需求相差好几倍,整个系统的容量明显下降,更容易出现内网阻塞。在这种情况下,将数据流缩短,就可以得到比较显著的性能提升。缩减数据流长度的方式非常有效,值得考虑。此外,还可以利用一些数据流优化方法。例如,一份数据需要写三份,一种做法是由发起机器并发地发三份数据到三台对应的机器上,但是这种方法对发起机器来讲,流量压力比较大。反之,如果要将数据发到A、B、C三台机器,先发给A,然后由A转发给B,再由B转发给C,虽然架构上会复杂一些,但是性能和容量提升也都很可观。
以上是架构设计时常出现的一些问题,关于“架构坏味道”还有更多细节的点和总结值得探讨,希望此文能给开发者们带来一定的帮助,也望以后能与大家做更充分的交流。
共同学习,写下你的评论
评论加载中...
作者其他优质文章