架构基础学习

从0开始学架构 0. 开篇 架构设计的相关特性: 架构设计思维和程序设计思维差异较大。架构设计的关键思维是判断和取舍,程序设计的关键思维是逻辑和底层实现。 缺少体系化的培训和训练机制 程序员对架构设计理解存在很多误区 内容: 架构基础 高性能架构模式 高可用架构模式 可扩展架构模式 目标: 清楚地理解架构设计相关的概念、本质、目的,避免架构师在实践过程中把握不住重点、分不清主次,眉毛胡子一把抓,导致架构设计变形或者“四不像” 。 掌握通用的架构设计原则,无论是何种业务或技术,架构师在判断和选择的时候有一套方法论可以参考,避免架构设计举棋不定,或者拍脑袋式设计。 掌握标准的架构设计流程,即使是刚开始做架构设计的新手,也能够按照步骤一步一步设计出合适的架构,避免某些步骤缺失导致错误的架构设计。 深入理解已有的架构模式,做到能够根据架构特点快速挑选合适的模式完成架构设计,或者在已有的模式上进行创新,或者将已有的模式组合出新的架构。 掌握架构演进和开源系统使用的一些技巧。 1. 架构到底是什么 1.1 三组概念 三组概念: 系统与子系统。具有关联的个体按照一定规则组织起来完成个体所不能完成的工作,成为系统。子系统是更大系统中的一部分。 模块(Module)与组件(component)。从业务逻辑拆分,得到的有程序和数据结构组成的软件组织成为模块。模块的接口表达了其功能。从屋里部署的角度拆分,得到的就是组件。划分模块的主要目的是职责分离,划分组件的目的是单元服用。模块与组件都是系统的组成部分,只是拆分角度不同。 框架(Framework)与架构(Architecture)。框架是组件规范,提供基础功能的产品。架构是指软件系统的基础结构,创造这些基础结构的准则和描述。也就是说框架关注的是规范,架构关注的是结构。 一个系统的架构只包含顶层这一层的架构,不包含下属子系统的架构。一个系统的架构从业务逻辑、物理部署不同角度看,有着不同的结构。 1.2 4R架构 软件架构指软件系统的顶层(Rank)结构,它定义了系统由哪些角色(Rule)组成,角色之间的关系(Relation)和运作规则(Rule)。通常Rank,Relation,Rule可以通过系统架构图展示,Rule可以通过系统序列图展示。 1.3 架构设计的历史背景 随着软件系统规模的增加,计算相关的算法和数据结构不再构成主要的设计问题;当系统由许多部分组成时,整个系统的组织,也就是所说的"软件架构",导致了一系列新的设计问题。 1.4 架构设计的目的 架构设计的主要目的是为了解决软件系统复杂度带来的问题 设计一个系统时需要考虑: 性能、可扩展性、高可用、安全性、成本。 2. 复杂度来源 2.1 高性能 软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度。 单机复杂度 操作系统为软件系统提供了运行环境,前者的复杂度也决定了后者的复杂度。操作系统由最初的手工操作,到批处理系统,然后进程的提出+分时复用,使用任务看起来像是并行执行,然后发展到多线程。最后发展到多核CPU。单机的复杂度来源于多进程、多线程、多核共享、通信、互斥等。 集群复杂度 通过增加机器来提升系统的性能。常见的方法: 任务分配 每台机器都可以处理完整的业务。随着业务越来越复杂,分配器集群和业务集群变得更加庞大。主要面临:如何将用户请求分配到分配集群的节点上,连接建立、检测、中断后处理。分配节点到业务节点如何分配。机器集群的状态管理、故障处理等问题。 任务分解 任务分配的方式中,每个业务节点拥有完整的业务逻辑。但是若是业务逻辑过于复杂,单机的性能会越来月拆,通过任务分配的方式收益将越来越小。此时可以将完整的业务拆分成若干独立的相对简单的子业务。 任务分解方式的理由: 简单的子系统更容易做到高性能 可以针对单子子系统进行扩展 但是并非任务分解越细越好,子系统之间的协作是有损的。 2.2 高可用 高可用:系统无中断地执行其功能的能力。 高可用实现方案本质都是通过"冗余"来实现的。高性能增加机器的目的在于扩展处理性能;高可用增加机器的目的在于冗余处理单元。 计算高可用。 存储高可用。存储高可用的难点不在于如何备份数据,而在于如何减少或者规避数据不一致对业务造成的影响。CAP定理表明,系统不可能同时满足一致性、可用性、容错性,最多满足其中的两个。 高可用状态决策。不论是计算高可用还是存储高可用,基础都是“状态决策”,即系统需要能够判断当前的状态是正常还是异常,并在异常时采取行动保证高可用。但是通过冗余来实现的高可用系统,状态决策本质上就不可能做到完全正确。 独裁式。只存在单个决策者,不会出现决策混乱的情况,但是决策者自身出现问题时系统不可用。 协商式。两个独立个体通过交流信息,根据规则进行决策。为防止两者信息交流出现异常,通常增加更多的连接。但是多个连接的选择也是个复杂的问题。 民主式。多个独立个体通过投票的方式进行状态决策,按照多数取胜的规则来确定最终的状态。为了应对“脑裂”问题(因为连接问题,集群被分割为两个集群,两个集群各自投票,超出大于1个决策者),民主式决策一般采用“投票节点数必须超过系统节点数的一半”的规则。但是这种策略在节点真正故障时,若可用节点少于一半则陷入不可决策的状态。 2.3 可扩展性 可扩展性指,系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者需要少量的修改就可以支持,无须整个系统重构或者重建。系统架构设计具体良好可扩展性,应当具体两个基本条件:正确预测变化、完美应对变化。 预测变化 复杂度在于:不能每个设计点都考虑可扩展性;不能完全不考虑可扩展性;所有预测都存在出错的可能性。 2年法则:只预测2年内的可能变化,不要试图预测5年甚至10年的后的变化。 应对变化 提炼稳定层和变化层。核心是通过变化层来隔离变化。一是变化层和稳定层如何拆分,二是两层之间的接口如何设计 提炼抽象层和实现层。核心是通过实现层来隔离变化。 原则:事不过三,三则重构。1写2抄3重构。

Linux性能分析工具

常用的性能分析工具 mpstat 查看整个系统/cpu维度的资源占用情况 pidstat 查看进程的资源占用情况 vmstat vmstat reports information about processes, memory, paging, block IO, traps, disks and cpu activity. 分析系统的虚拟内存使用情况,也用于分析上下文切换和中断次数。 procs -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu-------- r b swpd free inact active si so bi bo in cs us sy id wa st 0 0 0 234176 4473348 2733180 0 0 0 34 1 1 1 1 99 0 0 0 0 0 234008 4473516 2733184 0 0 0 0 1209 1831 1 0 99 0 0 Procs r: running or runnable, 就绪队列长度,正在运行或者等待CPU的进程数。 b: blocked 处于不可中断睡眠状态的进程数 Memory swpd: the amount of virtual memory used.

Linux性能优化——基础篇(CPU性能)

平均负载 通过平均负载可以查看系统整体性能、负载情况。查看系统平均负载的方法,top、uptime命令。load average后分别是1、5、15分钟的平均负载。 10:08:20 up 232 days, 20:05, 1 user, load average: 0.02, 0.04, 0.03 平均负载含义 关于系统负载uptime命令给出的解释: System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in a runnable state is either using the CPU or waiting to use the CPU. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk. The averages are taken over the three time intervals.

Redis持久化

redis持久化 持久化是为了保证redis数据在单机上的安全性,由于redis是基于内存的服务,在服务重启或宕机时内存数据丢失,需要持久化机制保证不受此影响。 持久化原理 将内存中的数据描述信息写到磁盘中,重启后加载持久化文件,通过记录的描述信息恢复数据,避免数据意外丢失。不同的持久化技术对数据的状态描述方式不同, 也就是生成的持久化文件不同。 RDB Redis DataBase, redis默认的持久化方式。将某一时刻数据库的所有数据以快照的方式保存到rdb文件。 触发 手动触发 save命令 save命令在执行过程中会阻塞redis-server,知道持久化完成。 手动触发 bgsave命令 background save, 生成一个子进程,后台运行save,不会阻塞redis-server。 自动触发 根据配置文件中设置的条件,当任一条件满足时触发bgsave,自动进行持久化操作。 查看持久化时间 lastsave: 返回上一次持久化的时间戳。 SNAPSHOT配置 save point # Save the DB to disk. # # save <seconds> <changes> [<seconds> <changes> ...] # # Redis will save the DB if the given number of seconds elapsed and it # surpassed the given number of write operations against the DB. # # Snapshotting can be completely disabled with a single empty string argument # as in following example: # # save "" # # Unless specified otherwise, by default Redis will save the DB: # * After 3600 seconds (an hour) if at least 1 change was performed # * After 300 seconds (5 minutes) if at least 100 changes were performed # * After 60 seconds if at least 10000 changes were performed # # You can set these explicitly by uncommenting the following line.