以资源为中心的计算机和现实分析

计算机的哲学都与现实相通,但是大数据+AI让一切有了新的可能。

  1. y=f(x). 一切的任务都能抽象为对输入进行处理,然后输出。对输入的任务使用一定的资源进行处理,然后输出;可以类比工作中对工作任务的分工和资源协调。

  2. Resource. 资源。计算机中的资源,包括单机中计算(CPU)、存储(内存,硬盘)、网络,分布式计算、存储、网络等,而存储一般可以视为数据;现实中如时间、人力、资金;

  3. Worker. 工作者。按照业务角度,计算机处理的都是一个个任务的集合,任务在计算机中的抽象模型可以分为进程/线程/协程,进程又可以分为本实例内的进程和跨实例的不同进程;现实中对应任务的粒度:任务拆分,子任务等等;

  4. ResourceType. 资源依赖的类型包括:不共享的,一人一份,没有冲突,谁也别抢,共产主义;共享的(只读,不会冲突;读写:会有冲突,需要保证互斥);现实中对应:比如一个团队并行做两个项目。

  5. Manager. 由谁来协调和分配资源?单机上是操作系统,分布式的话有类似NamingServer的统一调度角色,或者像peer2peer每个节点都是对等节点,协调分配的工作由节点自己来承担;现实:管理层如项目经理等;

  6. LoadBalance. 负载均衡。分配资源的规则/算法?负载均衡无所不在,操作系统层,网络层,分布式层,数据sharding层;可以定义为choose1fromN,即从N个元素中选出一个;抽象模型为:

    1. Metadata:元数据,包含所有的N(node或数据)的集合;

    2. Proxy:代理,接口人,处理负载均衡的对象,可能在client里,也可能是一个单独的节点;上文的Manager就是一种。

    3. Workers:处理目标任务的物理实例集合N;

    4. Rule:负载均衡算法,如何choose1fromN;

    • 平均分配,轮询,或者哈希,为保证扩展时迁移数据量尽可能小,一般用一致性哈希,缺点是无法范围;

    • Range,按照数据属性和区间进行分配;

    • 按能力,根据不同节点的工作量和忙闲程度动态监测,然后分配(活多的少分配,比如dubbo的最少活跃数)

    • 加权,分优先级,比如高工VS初级程序员。

    1. Trigger:负载均衡的动作何时触发或者配置,比如消息队列数据的rebalance在consumer和队列变动时触发,另外也有定时任务触发,一般网络访问是请求到达时触发;
  7. Fair vs Unfair. 分配是否公平?现实:任务分配是否合理,存在闲的闲死,忙的忙死的情况,影响整体效率。

  8. Lock. 资源冲突。如果资源是互斥的,一方占用了资源,没拿到资源的怎么办?

    • FailFast。报错,异常,现实:没资源,处理不了了,向上反馈;还有其他的FailXXX等策略;
    • Block。阻塞了,任务执行不了了,死等;
    • Queue。排队,按照先来后到排队,是否公平==允不允许插队(不同任务的优先级不同);
    • CAS。这次不行,下次再来试试,自旋;
    • 死锁,你等我,我等你,然后卡住;
    • 活锁。你让我,我让你,然后卡住。
  9. Concurrency. 并发。如果有多个任务一块并发到来,如何应对?架构,软件工程也是工程,工程的本质遵循经济学,即对稀缺资源进行高效率的分配,降本增效。联想生活中,假如一家餐厅有大量顾客涌入怎么处理?一般情况,进行排队,开分店,或者提前打包好套餐直接卖,对应到软件中,策略为:

    • 异步,使用MQ排队下单,下单后给顾客单号,订单号了异步通知用户;

    • 分片,sharding,一个实例处理不了,就加其他实例,然后对用户进行分流;

    • Cache。局部性原理,即提前准备好套餐,用户来之后不用再制作,直接就是现成的。

    高可用。另外,高并发/高性能的前提是高可用,不能存在单点故障,因此对于所有节点不能存在单点故障,需要有冗余备份,即至少每个员工,至少关键员工需要有backup。

    如果关键节点故障,实在处理不了呢,只能采取兜底策略,进行限流,按照能消化的流量处理

    如果还是不行,只能降级,有些订单做不了,如果还不行,只能熔断,打烊关门了;

  10. Cache. 缓存。缓存无处不在。单机中:CPU中的L1/L2/L3,内存中的PageCache;分布式中的分布式存储。抽象模型就是高一层的组件中冗余低一层组件中的数据,原理是局部性原理,即2/8法则,这次访问的数据下次还可能访问到(当然还有其他算法),因此需要处理:哪些数据是2,把他们放到高一层的组件;什么时候删除数据?高一层数据和低一层的数据不是同一个组件,数据变化时如何保证一致性?

  11. Transaction. 事务。从业务角度上讲,是把低维度的原子操作从逻辑上绑定集合到一起形成的更高维的原子操作。AllorNothing,要么全做,要么全不做。全做就是commit,全不做就是rollcack。从逻辑上是原子,但是从物理上可能不是。在分布式场景下,有各种的中间件,多个服务是跨进程的不同实例,为了保证从逻辑上是原子操作,需要底层基础设施做底层的处理来保证分布式事务,要使不同的进程能够协调,需要引入第三个协调节点(TC,MQ等),因为当前层次产生的问题不能由当前层解决,只能由更高一级来解决。

    举个生活中的例子,结婚就是一个分布式事务,男女双方是两个不同的进程,如果要保证一致性,需要协调节点,即神父。

    • XX先生,你愿意XXXX吗?Yes,Ido。>Phase1 prepare;
    • XX女士,你愿意XXXX吗?Yes,Ido。>Phase1 prepare;
    • 现在我宣布,XX和XX结为夫妻。>Phase2 commit。
    • If不愿意,rollback,回滚;离婚>回滚。

    以上就是原始版本的两阶段提交(2PC)实现分布式事务。

    另外,在达成共识前,还要双方亲朋好友使用Paxos或Raft算法(leader家长同意才是硬道理)达成共识,并通过婚礼进行消息广播。

  12. Leaderless vs StrongLeader. 民主VS集权。以第9条最后为例,需要分布式系统达成共识(这俩人到底能不能在一起),有两种方式,

    • Leaderless.即人人平等,一条消息要同步给所有人,没有人是领导,绝对的公平民主,但是相对地低效。比如redis使用的gossip协议。

    • StrongLeader.强leader:选出leader节点,leader节点说了算,然后把消息同步给其他人。那么问题来了?谁是leader?谁当皇上?leader挂了怎么办(选谁当太子?),这个问题在两个人结婚找父母商量的场景可以抽象为:你看你岳父和岳母谁说话好使?这个例子不是很合适(其实也合适,两个人私底下应该都商量好了或者默许了谁当家~,没意见就是默许,合理的逻辑),因为家庭的行为不够普世。

      Election.普世的例子是领导选举,选举的模型一般都基于Quorum模型,即大多数人同意的节点才是领导,领导拥有话语权,Quorum=N/2+1,即人大代表投票,超过50%的人支持就算选举成功。算法包括:Paxos或Raft算法,zookeeper的zab。这些算法扩展起来话题就大了,收!

      对于强leader系统,主要的核心工作有三种:选举,广播,恢复。即:选皇上,登基昭告天下,选太子。

      解决的问题都是共识问题,我们说的最多的是一致性(consistency),这也是一个大课题,后续再说。

  13. Index. 逐渐增长的资源(数据)需要进行检索,那么问题来了,怎样检索才能更高效?

    哲学是通过对原始数据进行关键信息的抽取和压缩(信息降维),形成更高效的衍生数据,先检索衍生数据,再检索原始数据。因为需要创建另外一份数据,因此写有一定损耗,需要权衡利弊进行折衷考虑(Trade-Off)。

    从低层次来说,就是数据结构和算法的时空复杂度,从高层次来说,不同的数据结构可以在单机中,也可以成为独立的中间件,成为一类数据结构的中间件(数据结构对中间件多对1),来解决不同类型数据的增删查改需求。

    增删查改需求进一步分析,分为读操作,即查,检索;写操作,增加,删除,更改,但这类操作第一步需要定位到目标数据,即也需要先进行检索,因此检索性能的快慢就决定了整个资源的访问速度。

    再极端一点说,分析不同中间件的数据模型使用的何种索引,可以从数据角度了解到核心的访问逻辑。

    比如,关系数据库中的B+树索引,主要场景为范围查询,读多写少,支持排序;

    Hash索引,关系数据库有,但是我们一般不用,用的最多的是redis,redis本身就是KV数据库,因此用的最多的是hash结构索引,场景自然是键值对查询,但对于排序的结构,用了跳表,跳表和关系数据库的B+树有类似之处。

    LSMTree。大部分NoSQL数据库或者列式存储底层的结构都是基于LSM(Log-StructuredMerged-Tree),主要思想是追加写(SSTable排序字符串),以及数据分层压缩合并。场景是大数据量的高效率写入,而针对读不命中,使用BloomFilter进行处理。

  14. Software Match Hardare. 软件匹配硬件。按照12中所讲,数据结构决定了效率,在同一种介质中的速度差距是由算法的数学证明决定的,但是在计算机中,很多情况是由于硬件结构决定的,一切的根源在于冯诺依曼体系。比如中间件的很多底层日志是基于状态机复制,WAL,WAL是基于追加写日志,对于硬盘而言,磁头的顺序写与随机写速度有几个数量级的差距,因此使用追加写是提高硬盘写效率的有效策略,同样CPU->总线->Memory->Disk的不同访问速度差距也是由于物理学的限制。

    因此提高性能的一条策略就是:软件匹配硬件(softwarematchhardware)。

  15. Struct Limit.结构限制。 结构限制决定系统上限。这就是数据结构的底层本质,即不同的结构能处理的数据量的上限或者速度上限是一定的。系统由各种元素组成,不同元素由不同的结构组成,具有不同的属性与限制和优缺点,需要根据实际场景进行选择和取舍。

    最熟悉的,就是javahashmap处理hash冲突,初始使用链表,达到一定数据量转为红黑树。

    在现实中就是,管理10个人,100个人,1000个人,10000个人乃至国家级别亿级的结构是组织结构是不一样的。

    说俗气一点,认知决定一个人的高度。而要想突破上限,必须有认知上的突围和升维,才能降维打击。

  16. Gene. 基因。一切都是系统,计算机系统,生物系统也是系统,一个人是一个系统,而系统所有的组件的最小单位-->细胞中的基因包含了一个人所有的信息,或者说元信息。说明白点就是一个系统的原理方面的信息体现在一个系统的每个元素中。

    对于计算机而言,就是分布式系统的哲学在单机的操作系统中有同样的体现。分布式系统=操作系统list+网络。

    比如操作系统的并发模型的进程,分布式中是跨进程通信,互斥,锁的原理类似;操作系统的缓存与分布式缓存的一致性;操作系统的多线程处理与分布式的无状态微服务横向扩展都是基于分治和并行的思想;

    冗余,缓存,异步,批量的思想都是相通的。

    如果更往底层抽象,不管是分布式系统=操作系统list+网络=数据结构list+算法list。

    从一个HashMap的初始化,扩容缩容,解决hash冲突,能体会到分布式数据分片的sharding(分库分表,消息队列rebalance)同样的原理。了解了相同,再思考不同,对其掌握会更深刻。

    见微知著,大道相通。

    关键看你怎么想。怎么行。

  17. Business vs Tech. 业务 vs 技术。回到起点思考,资源(数据)从0到1,从1到N,从N到海量,整个过程采取的措施和问题的解决可以作为分析软件架构发展的脉络,这是一条主线;

    而另外一条主线就是现实生活如何挂靠到技术架构上,即业务如何转化为数据,业务+数据如何转化为价值,DomainArchitecture->TechArchitecture->ValueArchitecture。

    思考->业务设计,技术设计,组织设计->得到资源-->处理资源-->挖掘价值。

  18. Trade Off. 取舍。计算机中(不止计算机)解决问题都是解决一个问题,带来一个问题,然后摁下葫芦浮起瓢。最后都是折衷。

    比如,单机为了提高效率,引入多线程,导致上下文切换和原子问题;为了提高效率,引入缓存,导致缓存一致性问题。到了分布式中:为了保证分布式集群的可用性,做了多副本冗余,影响了一致性。为了保证一致性,影响了高性能。同步写能保证不丢数据,但是性能低;异步写性能高,但是有可能丢数据。

    诸如 CAP 的原理都是“鱼,我所欲也,熊掌亦我所欲也;二者不可得兼,舍鱼而取熊掌者也。 ”

  19. Human vs Machine. 人 vs 机器。根据14所述,系统=元素的集合,元素有不同的属性,由人来根据场景组合元素,构成系统。数据增长时,升级或切换元素,而元素如果想自己突破结构限制,成为更高维度的结构突破上限,目前来看是不可能的。比如,MySQL的B+树不会因为数据写入量大了就会自己切换到LSMTree。HashMap的链表转换为红黑树,但是代码也是人编写的。Node就是Node,Manager就是Manager,Manager能链接更多的节点,因此具有更大的价值,但是Node无能为力。大数据+AI能做到智能升级吗?

    但是一个人,一开始可以是小兵,后来也可以升为Manager(管理层),甚至成为Leader,人能突破系统的结构限制,自我进化。

    怎么突破结构限制。原则是提升认知。方法是至少有一次突破底层结构的限制。比如高考,比如就业。

    接下来呢?

你可能感兴趣的:(以资源为中心的计算机和现实分析)