• 七牛李道兵谈“架构坏味道”


    转自:http://blog.qiniu.com/archives/3962

    七牛李道兵谈“架构坏味道”

    软 件架构在成功的软件交付中扮演着重要角色,好的架构可以兼容不同类型的业务和算法,并且相安无事,而架构设计不当就需要不断地进行整体的更替,以适应业务 的变化和新算法的需求,甚至影响最后架构整体的稳定性、容量等。事实上,架构的很多方向性问题是可以在设计初期就避免的。因此,七牛首席架构师李道兵结合 多年的实践经验,在本文中详细总结出了以下七类具有明显“坏味道”的架构影响因素。

    架构对容量数据不敏感

    设计架构时对于常规的一些基础架构元素容量不清晰,比如前端的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, 虽然架构上会复杂一些,但是性能和容量提升也都很可观。

    以上是架构设计时常出现的一些问题,关于“架构坏味道”还有更多细节的点和总结值得探讨,希望此文能给开发者们带来一定的帮助,也望以后能与大家做更充分的交流。

  • 相关阅读:
    关于findViewById返回空指针的错误
    android客户端向服务器发送图片和文字,类似于发微博。能用json格式发送吗?
    nodejs 学习资料大全
    篇章三:[AngularJS] 使用AngularCSS動態載入CSS
    篇章二:[AngularJS] 使用AngularAMD動態載入Service
    篇章一:[AngularJS] 使用AngularAMD動態載入Controller
    Angular 资料大集合
    js-音乐播放器,播放|暂停|滑块的功能
    JS-以鼠标位置为中心的滑轮放大功能demo1
    使用 Electron 构建桌面应用(拖动控制篇)
  • 原文地址:https://www.cnblogs.com/leoncfor/p/4704039.html
Copyright © 2020-2023  润新知