菜鸟架构笔记:上部

从零开始学架构

照着做,你也能成为架构师

李运华|著

技术成就梦想,坚持就能成功

程序设计与架构设计

程序设计的关键思维是逻辑实现
架构设计的关键思维是判断取舍

架构即人性!切勿好大喜功。

三大原则:

  1. 合适原则——合适优于业界领先。
  2. 简单原则——简单优于复杂。
    《UNIX编程艺术》Kiss:KeepItSimple,Stupid!
  3. 演化原则——演化优于一步到位。

系统是其内部的诸多有关联的个体按照相应的规则
运行出的具备新的能力的东西。

组件与模块

从逻辑的角度来拆分系统得到的单元是模块
从物理的角度来拆分系统得到的单元是组件

划分模块的主要目的是职责划分
划分组件的主要目的是单元复用

component组件,零件,属于物理范畴。

框架Framework和架构Architecture

不同角度理解问题,所抽象出的概念是不同的。

高**的误区

不能一味的追求高性能、高可用和高扩展!
Done is better than perfect!

以史为鉴

探索一个事务的目的,最好的方式就是去追寻这个事物出现的
历史背景推动因素
屁股决定脑袋,位置决定想法。
事物的量级达到一定程度后,问题也会***变质***。
模块、对象再到组件,差别是随着软件的复杂度不断增加,拆分
的粒度越来越粗,拆分的角度越来越高。

架构设计的主要目的

是为了解决复杂度带来的问题。
低成本是架构设计的附加约束。

高屋建瓴,有的放矢,而非贪大求全

不同架构应该针对不同的复杂点。

任务分配器与业务服务器

任务分配随着量级的增加,性能损耗越来越高,整体收益会大打折扣。
任务分解,拆大为小,进而更容易找到关键性能点进行突破,且不会
牵一发而动全身,方便调优。
拆分后的子系统之间交流也有成本,所以拆分的粒度要适度。

系统的高可用

通过冗余实现无中断。相当于功能备份。
存储高可用的难点不在于如何备份数据,而在于如何减少或规避数据不一致
对业务造成的影响。

数据+逻辑=业务

即便是毫秒级别的传输延时,也会照成数据的不一致,进而导致业务出现问题。

CAP定理

consistency
available
partitionTolerance
存储高可用不可能同时满足一致性可用性分区容错性,最多满足
其中两个,在做架构设计时要结合业务进行取舍。由于网络延时等不可避免,
所以通常在一致性可用性之间进行取舍。

高可用状态决策

独裁式:一个决策者与多个上报者
协商式:主从通信问题
民主式:投票选举,脑裂混乱问题

可扩展性

设计模式
正确预测变化,完美封装变化。
唯一不变的是变化
变与不变,稳定层与变化层的确立。

创新

小公司引入新技术,大公司创造新技术。

安全

功能上的安全,在攻与防的矛盾中逐步完善。
架构上的安全
防火墙一般不适用海量用户访问与高并发。
运营商或云服务商具备强大的带宽和流量清洗能力。

规模

规模的线性增加带来的是复杂度的指数增加。
数据越来越多,系统复杂度也会由量变带来质变。
大数据的三架马车。
传统mysql推荐单表5000万行左右。

名词解释

CDN:Content Delivery Network
GSLB:Global Server Load Balance

规范

凭借个人经验与感觉设计架构。
积累自己的储备库。
大公司具备的平台、资源和积累是架构衍生的关键。
环境逼迫创新。
情境激活灵感。

建筑

对于建筑来说,永恒是主题。
对于软件来说,变化是主题。
条条大路通罗马,要综合选择。

备选方案

3-5个
几乎没有无暇的方案
如果你有一把锤子,那么所有的问题在你看来都是钉子。
不要被既有经验局限。
备选阶段关注技术选型,而不是技术细节。
360度环评:最简派、最牛派、最熟派、领导派
极端情况的出现毕竟是小概率事件,留有较多余力的时候再去考虑。
举例:
1.横向扩展
2.系统拆分
不同的方案,面对不同的公司情况,考虑问题的侧重点应该不同。
权值的设定应该依具体情况而定。
按优先级选择。
详细方案的设计阶段可能显露出备选方案中遗漏的关键点,进而导致
备选方案全局否定。架构师应该在早期看的更深入。
海纳百川,博采众长。

关系数据库

高性能数据库集群:

  • 读写分离:将访问压力分散到多个节点。主机读写,从机读操作。
    主从复制延迟问题:
    1.写操作后的读操作指定发给主机。
    2.从机读取失败后再读一次主机,二次读取会增加主机压力。
    3.关键业务全部指向主机,非关键业务由从机完成。
  • 分库分表:既分散访问压力,又分散存储压力。
    join操作问题:无法使用join
    事务问题:分布式事务解决方案性能不高。
    成本问题:业务分库一般后期进行。前期业务规模小且不稳定。
  • 单表数据拆分的两种方式:
    垂直拆分:不常用的字段剥离出去。
    水平拆分:如果单表行数超过5000万,相对来说可以考虑拆分。
    范围路由:单表水平分段建议100万到2000万之间。
    最后一张表可能导致分布不均。
    Hash路由:所有表分布均匀,但后期扩充要重分布。
    配置路由:记录拆分信息,利于扩充,但多一次查询。
    拆分难点:粒度选取。
    举例:count()
    拆分后的多个表求总记录数,需要把每张表的count(
    )
    累加求和,性能会受到影响。引入记录数表记录当前表
    的行数,又会导致同步更新的问题,复杂度增加。
    order by操作无法进行,需要单表排序后引入中间件汇总排序。
  • 读写分离实现:
    程序代码封装:实现简单,但每个语言都需要自己实现一次,无法通用。
    如:TDDL(Taobao Distributed Data Layer)头都大了!
    中间件封装:数据库中间件对业务服务器提供的是标准SQL接口。
    实现复杂,主从切换服务器无感知。
    如:mysql-proxy、mysql-router、奇虎360的Atlas。
  • NoSQL
    关系数据库的缺点:
    1.无法存储数据结构,存储的是行记录。
    2.schema扩展不方便。扩充列导致表长时间锁定。
    3.大数据场景下IO较高。即使是对某一列进行统计,
    关系数据库也会将整行进行读取。
    4.且全文搜索能力比较弱。
    NoSQL!= no sql 而是 NoSQL = Not only sql
    针对上述缺点常见的NoSql方案:
    1.k-v存储:Redis
    2.文档数据库:MongoDB
    3.列式数据库:HBase
    4.全文搜索引擎:Elasticsearch
    1.Redis事务只支持I(是单进程单线程的工作模式)和C,不支持
    A(不支持回滚)和D.
    2.no-schema的文档数据库,如JSON数据是自描述的,无需在使用前
    定义字段,读取一个JSON中的不存在的字段也不会导致SQL的语法错误。
    JSON比起先要执行DDL的关系数据库要方便更多。但某些对事务要求严格
    的业务场景是不能使用文档数据库的。通常可以sql+noSql组合使用。
    3.行式存储可以同时高效读取多个列,也可以同时在一行中对多个列进行
    写操作。但在海量数据进行统计的场景中并不适用。普通行式数据库一般
    压缩率在3:1到5:1左右,而列式数据库压缩率一般在8:1到30:1左右。
    4.全局搜索引擎技术原理:倒排索引。
    正排索引:根据文档名称来查询文档内容。
    倒排索引:根据关键词来查询文档内容。
    全文搜索引擎的索引对象是单词和文档,而关系数据库的索引对象是键和行。
    全文搜索引擎在支持关系型数据全文搜索时需要JSON(不唯一)与表对应转换。
    Elasticsearch是分布式的文档存储数据库。它能存储和检索复杂的数据结构
    ————序列化称为JSON文档————以实时的方式。在Elasticsearch中,每个字
    段的所有数据都是默认被索引的。即每个字段都有为了快速索引设置的专用倒
    排索引。而且,不像其他多数的数据库,它能在相同的查询中使用所有的倒排
    索引,并以惊人的速度返回结果。
  • 缓存
    将可能重用的数据放到内存中,一次生成,多次使用,避免每次使用都去访问
    存储系统。
    缓存穿透:故意访问不存在的数据,空值替代。
    生成缓存耗费时间和资源,当竞争对手故意爬取所有分页时(通常
    缓存前10页比如),会拖慢整体。
    缓存雪崩:缓存失效后引起系统性能极具下降。
    解决方法:1.更新锁机制:加锁保证只有一个线程进行缓存更新。
    2.后台更新机制:后台线程更新缓存而不是由业务线程更新缓存。
    缓存本身的有效期设置为永久,后台线程定时更新缓存。
    定时读取:频繁查看被踢的数据,及时更新空值。
    消息队列通知:业务线程发现缓存丢失主动发消息
    通知后台线程更新缓存。相对简单,且可以用于系统
    预热。
    缓存热点:某明星大咖的消息复制多份缓存,缓解服务器压力。
    PPC:Process per Connection,每次有new connection,then fork a new process.
  • some problems:
  1. Fork is expensive.
  2. IPC:Interprocess Communication is expensive.
  3. The increasing number of processes are not good for
    performance.
  • solvable method:
    1.prefork,which needs system solve “惊群” phenomenon.
    2.TPC:Thread per Connection.
    3.进程池:
    read操作改为非阻塞,然后进程不断地轮询多个连接,
    但这并不优雅,且连接达到几千上万的时候,效率低下。
    4.I/O多路复用结合线程池:Reactor 即:反应堆(事件反应)非阻塞
    同步网络模型
    当多个连接共用一个阻塞对象后,进程只需要在一个阻塞对
    象上等待,而无需再轮询所有的连接。
    当某条连接有新的数据可以处理时,操作系统会通知进程,
    进程从阻塞状态返回,开始进行业务处理。
    Reactor模式也称为Dispatcher模式,即:I/O多路复用
    统一监听事件,收到事件后分配给某个进程。
    实用类型:单Reactor单进程/单线程。
    单Reactor多线程。
    多Reactor多进程/线程。
    上述具体线程还是进程依具体编程环境及平台有
    关。java一般使用多线程。
    5.Proactor 前摄器 类比proactive主动的,主动器
    Reactor:来了事件我通知你,你来处理。
    Proactor:来了事件我来处理,处理完了我通知你。
    解释:”我“是操作系统,”事件“是新的连接、有数据可读、数据可写。
    流程:
    1.Proactor Initiator负责创建Proactor和Handler,并
    将Proactor和Handler都通过Asynchronous Operation
    Processor注册到内核。
    2.Asynchronous Operation Processor负责处理注册请
    求,并完成I/O操作后通知Proactor。
    3.Asynchronous Operation Processor完成I/O操作后
    通知Proactor。
    4.Proactor根据不同的事件类型回调不同的Handler进行
    业务处理。
    5.Handler完成业务处理,Handler也可以注册新的
    Handler到内核进程。
    目前windows下采用IOCP,而linux采用Reactor模式为主
    因为linux下的AIO并不完善。
    集群高性能:负载均衡不只是为了计算单元的负载达到均衡状态,而是一种综合的考虑。
  • DNS负载均衡
    地域级别的均衡。就近原则。
  • 硬件负载均衡
    集群级别负载均衡。昂贵,扩展能力大。
  • 软件负载均衡
    机器级别负载均衡。通过软件实现负载均衡功能。
  • 负载均衡算法
    任务平分类:轮询
    负载均衡类:权重轮询
    性能最优类:按服务器性能分配,适当概率判断服务器性能
    Hash类:同IP或者同session id归属到同一服务器

CAP

  • What is Partition Tolerance?

System continues to work despite message loss or partial failure.
The System will continue to function when network partitons occur.

  • What is CP?当发生分区时,返回错误。
  • What is AP?当发生分区时,返回错误值。
CAP理论的实践
  • 需要将系统内的数据按照不同的应用场景和要求进行分类,每类数据选择不同的的策略。
  • 比如:用户信息数据选择AP,而用户账号数据选择CP。
  • AP相当于是放宽了一致性的要求,可用就好。CP由于追求强一致性而导致不可用情况发生。
  • CAP是忽略网络延迟的。有时强一致性的要求导致只能单点写入,其他节点备份,无法做到分布式情况下多点写入。但并不意味着系统无法应用分布式架构,可以两个节点各自负责一半业务,同时备份另一半。这样即便其中一个节点发生故障,也只是影响一半的用户。

正常情况下,不存在CP和AP的选择(即:当P可以舍弃时),可以同时满足CA。

  • 此情况我们需要考虑分区发生情况下的CP与AP的选择,同时也要考虑P没有发生情况下的CA的实现。
  • 不同的数据CA实现方式可能不一样,比如:用户账号数据可以采用消息队列,因为可以比较好的控制实时性。而用户信息数据可以采用数据库同步的方式来实现,因为实现简单。

分区期间(一年可能5分钟(4个9)、50分钟(5个9))

  • 分区发生,则记录相关日志。
  • 分区故障解决后,系统根据日志进行数据恢复。
  • CAP关注的粒度是数据,而不是整个系统。

BASE

  • Basically Available 登录比注册重要。
  • Soft State 允许数据存在中间状态(CAP理论中的数据不一致),但不影响系统整体可用性。
  • Eventual Consistency 系统中的所有副本经过一定时间后,最终能够达到一致性的状态。是对AP方案的一个补充。

FMFA(Failure mode and effects analysis)故障模式与影响分析

  • 是一套分析和思考的方法,应用于各个领域。
  • 登录注册才是功能点。
  • 故障模式关注现象和对应影响,即便原因不同。尽量使用量化描述,而非泛化。
  • 对于故障现象,殊途同归,殊因同果,应不同对待。

存储高可用

主备倒换(主读写,备备份)与主从倒换(主读写,从读)
  • 问题关键点:状态判断倒换决策数据冲突修复
  • 互连式与中介式(MongoDB(A)),还有模拟式(将备机模拟为客户端进而判别主机状态)。
  • 主主倒换需要双向复制。
开源的数据集中集群
  • ZooKeeper,ZAB协议,开源
数据分散集群
  • 均衡性
  • 容错性
  • 可伸缩性
  • Hadoop,Namenode是一个中心服务器,负责数据分区的分配。HDFS,master/slave.

分布式事务算法

  • 2PC(Two-phase commit protocol)
  • 提交请求阶段,看看是否有No存在,都yes则提交执行阶段。
  • 强一致性算法,简单,但不好用。
  • 3PC(Three-phase commit protocol)
  • 在2PC中间插入一个准备阶段。
分布式一致性算法
  • Paxos,state machine replication(active replication)各个节点间复制操作
  • Raft,state machine replication(active replication)
  • ZAB,primary backup(passive replication)Leader节点执行操作,将执行结果复制给其他节点。

数据分区

  • 地理级别重大灾害规避风险。每个区域负责一部分数据。
  • 国家洲际间分区仅作为备份,而城市之间由于延迟低、业务相似,分区同时适合对外提供服务。
复制规则
  • 集中式 所有分区将数据备份到备份中心。
  • 互备式 形成闭合链,但如何加入新的一环。
  • 独立式 一对一,不同区域。

计算高可用

主备

冷备(未启动)与 温备(已启动)

主从

从机也干活,主机有故障,从机升级主机(一般升级配置),新增从机。

对称集群与非对称集群

业务高可用

  • 异地多活,把鸡蛋放到多个篮子里。
  • 优先实现核心业务的异地多活架构!
  • 物理(地理等)因素导致无法很快。所以取舍:核心数据最终一致性。采用多种手段,保证绝大部分用户的核心业务异地多活!
  • 保证最终一致性,不保证实时一致性。

异地多活设计步骤

  • 1.业务分级,根据不同标准不同情境(核心、访问量、盈利)区分业务。
  • 2.数据分类,根据(数据量、唯一性、实时性、可丢失性、可恢复性)
3.数据同步
  • 存储系统同步(延迟高)
  • 消息队列同步(无事务性和无时序性业务)
  • 重复生成(如:cookie、session)
4.异常处理
  • 多通道同步
  • 同步和访问结合:本地没有去其他接口找。
  • 日志记录
  • 用户补偿

没有更多推荐了,返回首页