架构系列谈三:左移

对于大型或复杂系统来说,架构是项目成败的关键,本文尝试从架构设计的方法论的层面谈一下架构设计的常见思路。

软件是用来解决业务问题,一般分为三个阶段:

首先是对业务问题进行分析、解耦、抽象和合理组织;进而进行系统架构的设计;最后使用通用编程语言对系统架构进行实现。

下面我们从复杂度变化的角度谈一下架构设计的递进过程。

首先业务问题本事是有一个复杂度的,假设这个复杂度为100;

而我们的系统架构要能够hold这个问题,系统架构的复杂度需要>=100,假设为200;

而编程语言需要实现这个系统架构,它的复杂度又必须>=200,假设是300。

这时一个有趣的现象就出现了,越是往右,后一个节点为了全cover住前一个节点的复杂度,它的复杂度必须不低于前一个节点的复杂度,而且很大概率还会上升很多,甚至是急剧升高,体现在以下几个方面:

01

业务问题和系统架构之间的gap

业务模型和系统模型主体不能一一对应,每个业务逻辑都需要一个频繁的映射关系,这部分就带来了额外的复杂度。

02

过度设计

过度开发、过度设计无疑会带来额外的复杂度,而且会耦合到系统本质复杂度上,造成复杂度过高。

03

强耦合

强耦合导致复杂度之间产生黏连,从而导致系统的僵化和造成了铁板一块,特别是耦合越深的地方,越是难以理解和演进,额外复杂度增加的也越多。

小结,这里可以看出,复杂度在业务问题-》系统架构-》编程语言一路放大传播。

越是在业务领域内简化问题,复杂度放大的越小,实现的代价越低;越是往系统架构甚至编程语言方面应对问题,复杂度越高,实现的代价越大,即软件设计越是左移,实现的难度越小。

我们来看一个例子,RTB(real time bid)实时广告竞标系统。

其基于happy path的业务流程如下:

第一版的设计

在海量用户并发访问站点的场景下,会有海量的用户信息高并发投送到RTB,RTB再向厂商发起海量竞标请求,竞标过程中存在复杂的竞标策略、网络延时等情况。

为了保证每个用户竞标信息不丢不重,无论采用同步方式(线程池)还是异步方式,即使对竞标操作进行分布式设计,每个分布式节点中,都需要开辟巨量竞标信息缓存数据区,采用队列的方式,先到先处理,后到的缓存到数据区,由于处理速度赶不上用户上来的速度,数据区积压成为系统的瓶颈,后面上来的用户经常广告播放失败,造成整个RTB成功流量较低。

提升竞标并发率和竞标效率成为必须啃下的硬骨头,但是由于竞标的特点(多家厂商返回竞标结果后,才能开标,这是个同步过程),尽管扩充了分布式节点大并行度,并且在编程语言方面(c语言)下大力气整改:

1、工具层面

a、编译器把icc更换为gcc

b、链接参数更换为o2,部分换成o3

2、内存

a、防止内存漂移

b、减少内存拷贝

3、cpu

a、cache friendly

b、绑核

c、通过反汇编进行计算强度降解

d、使用表驱动和宏进行预先计算

e、ILP(指令并行)替换

f、改善cpu分支预测(通过消减分支)

g、循环展开

h、数据解依赖,加大并行

i、数据流并行,使用SIMD(单指令多数据流)

j、互斥锁改自旋锁

k、替换STL库

l、文本转二进制

。。。。。

18般武艺俱全,但性能提升效果其实并不理想,广告成功播放率没有显著提升。

第二版设计

结合业务场景对问题进行简化,考虑到RTB赢利的核心是成果播放广告的次数(按广告展示成功次数和广告展示方分成),而一个用户浏览一个网页平均停留时长不超过1s,折算到竞标过程的话,如果竞标过程超过30ms,即使竞标成功,用户也可能已经离开该网页了,竞标成功也没有意义了。

针对这个业务特征,对系统架构做调整,新上线的用户优先处理,老的没有处理完的用户直接丢弃。竞标数据区改成stack结构,后到先处理,stack底部数据超时部分全部丢弃。经过这一简易的改动后,广告播放成功率大幅提升。

所以,在业务域进行简化(后发先至),可以大幅降低问题复杂度,比系统架构、编程语言的优化大幅提升性价比。

又比如,数据库的应用要满足cap(一致性、可用性、分布式容忍性)的要求,如果在海量数据+高实时性的前提下,要能保持高可用性+数据一致性是非常困难的,系统可能会非常复杂,很难以理解(系统的可理解性非常重要,如果系统不能被理解,就很难实现正确)。

但是很多高可用性的场景下,数据的一致性的要求可以放松,比如可以接受最终一致性,即可以有个时间窗口能容忍数据不一致。这种在数据库中间键有很多应用。

另外在很多“写重读轻”的大数据场景中,即允许读写的内容在一段时间内不一致,就可以采用LSB(log-structure based Data System)系统,延后做日志分级索引的建立,并且所有记录的变更都采用追加写的方式,降低写的代价,这也是对放松数据一致性的应用。

综上,在业务问题-》系统架构-》编程语言这个顺序上,简化越是靠左,越是能够降低整体复杂度,就像发烧一样,在编程语言上进行优化,就像进行物理降温或吃退烧药,而在业务问题上进行简化,才真正找到了感染源,进行有的放矢的治疗,才能事半功倍。

左移!左移!左移!

重要的思路讲三遍!

(笔者wo在川知乐 简称老乐)

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181101G0ANQH00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券