《网站运维》读书笔记

参考:

  • 《网站运维:保持数据实时的秘籍》(Web Operations: Keeping the Data on Time)





作为职业的运维

互联网变化如此之快,以至于几乎没有时间认真思考一下我们在做什么,以及为什么做。我们奋力拼搏,才避免被淘汰出局,哪里还敢谈论什么引领潮流呢!这种高压、过度刺激的环境使得所有努力都只是为了一份工作,而没有职业的概念了。

职业是指占去你人生大部分时光的事业,并能够逐步晋升。工作只是拿钱干活儿,换句话说,工作就只是工作而已。


为什么运维如此艰难

运维对如下领域都有深入的理解:网络、路由、交换、防火墙、负载均衡、高可用性、灾难恢复、TCP与UDP服务、网络运维中心管理、硬件规范、各种Unix、各种Web服务器技术、高速缓存技术、数据库技术、存储基础架构、密码学、算法、趋势分析、容量规划…

运维要求广博,可以说几乎是不可接受的。

运维领域成为一个合格的人选,需要具备三点素质:扎实的计算背景、娴熟的决断力、沉稳的性格


扎实的计算背景

运维要求理解架构中的各个组成部分,在理解计算系统的来龙去脉时,扎实的计算背景对你会有莫大的帮助。具有扎实的基础,对于理解为什么及如何架构解决方案,以及识别出问题所在,是非常重要的。毕竟,计算是架构我们的智能系统的基础。此外,工程师的思维方式和对物理定律的基本理解,也是一个很大的优势。

运维会经常遇到随意的、不切实际的期望。
运维,就是理解理论和实践在哪里发生冲突,并发明适当的方法,以便在发生事故时减少损失。


娴熟的决断力

虽然优柔寡断在任何领域都不算是一个优点,但在运维中却几乎不能容忍。


沉稳的性格

一个沉稳与可控的思维过程是非常关键的,需要保持自己是清醒的一方。

在运维领域,目标很简单,使所有事情在所有时间正常运转。一个简单的定义,但却是一个不可能的期望。或许在这个领域成为一名工程师的更大挑战是组织内的同事对你的不切实际的期望。




从学徒到师傅

掌握任何知识领域都需要四项基本要求:知识、工具、经验和纪律


知识

互联网行业的一个独特之处就是几乎所有的东西都是公开的,事实上,有专有权的东西也是极少的,而更为独特的是,几乎所有规范文档都是免费的。

在你走在从从学徒到师傅的路途中,尽可能多滴占有信息是你的职责,这样你的大脑才能将那些细微之处进行排序、过滤、关联,使其成为一幅简明、精确的图画,从而有助于你的决策——不管是长期的架构设计的关键决策,还是临时的排除故障的决策。


工具

虽然工具各有优缺点,然而人们使用这些工具都取得了成功。制造和使用工具使我们人类的本性。
所有的工具归根结底都只是人类肢体和感觉器官的延长。

师傅不适用工具炼成的。在互联网应用的环境中,你会看得更清楚,五花八门的语言、平台、技术都能够成功地结合在一起,将这些成功地构建为一个架构的,不是Java或PHP,而是设计与实现它的工程师——那些师傅们。

工具上的一个真理是,不管在用的工具是什么,要了解你的工具,这是在这个行业登堂入室的前提。灵巧地运用工具的能力,比工具本身的质量要重要的多。话虽如此,有经验的工程师还是应该手边备一件合适的高质量的工具。


经验

从最本质的意义上来说,经验意味着良好的判断力,而良好的判断力却是从很多失败中取得的。

经验与知识是紧密相关的,知识可以认为是他人经验的总结。
经验既是一个名词,也是一个动词。获得经验与应用经验,同样容易也同样困难。

一名资深工程师最大的特点是其一致与可靠的良好判断力。很显然,这要在需要做出判断的场合经受锻炼。

对进入运维这个领域而没有什么经验的工程师,我的忠告是:耐心


纪律

通过尽可能正确而高效地做事,从而为解决同样问题,而尽可能地少做工作。






如何应用云计算(Elastic Compute)

云服务器(ECS, Elastic Compute Service)


什么地方适合云计算

灵活性和一定程度上的自由是云服务器的特点,当然,本地服务器同样有这个特点。


混合计算

混合计算=云计算+本地计算


什么地方不适合云计算

当然,最先考虑的肯定是经济层面。

服务层与数据库是紧密耦合的,所以使它们之间的网络延迟最小化是很重要的。这意味着它们要么全在云里,要么全在云外。


结语

尽管有大量广告吹嘘完整托管在云里,但从运维角度来说,混合应用架构模式或许是最有趣的。有些事情在云里做的不一定好。脚踏两只船,你才会游刃有余。

混合应用还强调一点,就是传统运维中的最佳时间仍然是成功的公司的云应用所必须的。






基础架构与应用程序测量

任何规模的运维,采集测量数据就像将服务器连接到网络上一样重要,对于一个规模不断增长的基础架构来说,或许更加重要。

我们不光讨论你要采集并监视的测量数据的种类,还要讨论为了应对各种情况,你能利用这些数据做些什么。

测量数据的采集和带有报警(alerting)功能的监控有明显的区别。




时间刷新率和存留时间的考虑

随着采集的数据不断增长,确保这些数据能够一直可查询和移动,这是很明智的。

如Zabbix中——获取数据的时间刷新率和数据保存时间。历史数据保留时长和趋势数据存储时间。
比如有的数据要30s获取一次,而有的信息只需要1h获取一次。

测量数据真正出彩的地方:

  • 对于某个特定的资源,每天的峰值是哪些?每周的峰值日是哪些?每年的峰值月是哪些?
  • 有季节性模式吗?
    • 如夏时日和节假日会高一些
  • 最大(波峰)值与最小(波谷)值比较起来怎么样?
  • 在用户分布广泛的情况下,波峰与波谷是否发生变化?




测量数据采集与存储的地点

无论使用什么采集工具,易于采集和便于得出结果都是必须要考虑的。




测量数据的层次

不同层次的数据存储在不同的数据库中。


高层业务或功能特定的测量数据

有了这些高层数据之后,面向产品的那些人对这些数据也抱有极大的兴趣,你一点都不用感到惊讶。

对于应用层面的数据,最有用的是能够跟踪用户的交互情况。


系统及服务层面的测量数据

这些是在运维工程师电脑上以图形方式显示的数据。


测量数据的层次:

- 例子 测量项目
应用层 网页或API 故障:类型、延迟、发生率…
服务层 Nginx, MySQL, MongoDB… Nginx: 请求频率、响应时间、忙碌的工作进程…
MySQL/MongoDB:导致故障的查询类型、慢查询、连接数…
物理层 CPU、内存、网络、硬盘 内存:繁忙程度
内存:空闲内存
硬盘:可用空间,I/O速率
网络:网络I/O带宽情况

有了这些数据,就能够回答如下问题:

  • 平均的Web请求时间
  • CPU时间
  • 调用最多的数据库查询
  • 数据库慢查询
  • 文件系统缓存
  • 最大的页面响应




为异常检测和报警提供环境

在本地采集的测量数据的主要理由,就像油表一样,有了这些数据,就可以明白基础架构正在发生什么,以及正在驶向何方。
知道哪里的资源在增长或缩减,能够进行预测。使用预测对基础架构的容量需求进行预报,称为容量规划。
观察网站运行是否有异常时,测量数据就派上用场了。

发生异常是,测量数据回味报警提供相关信息。报警的信息要尽量简明,告知检测到了什么,以及何时检测到。而测量数据会告诉你报警都发生了什么。




日志记录也是测量数据

应用程序的日志文件也提供了测量数据和使用情况的信息。这些信息用于追踪过去发生的事件。




将变化管理和事件的时间线建立关联

更新生产系统会带来风险。
记录更新发生的时间,从而保留更新的踪迹,这在发生问题需要进行追踪时是非常有价值的。




给测量数据加入报警机制

Zabbix、Nagios等就是一个测量数据采集系统配合使用的监控/报警工具。




使用测量数据建立加载-反馈机制

采集时序数据的另一个好处,就是能够通过编程使你的应用生成测量数据,从而可以建立安全、精密的反馈循环。




结语

测量数据的采集、存储、显示,可以认为是web基础架构的关键部分。不论是及时排查错误,预测容量、规划产品的发布,还是建立应用的反馈机制,如果没有正确的测量数据为你提供一个基础架构运行的全景图的话,你会损失惨重。

设计数据如何经过系统时,要考虑安全问题,而且数据要易于导出到其它应用。一旦运维部门采集了测量数据,你会发现,追踪数据是一件多么有趣的事情,同时也能使工作更加轻松。






连续部署

软件应该以小批量的方式进行设计、编写和部署。

批量大小是产品在开发过程的各个阶段转移的单位。对于软件而言,最容易看到的批量是代码。每次工程师检入代码,都是在提交一定量的工作。有很多技术用来控制这些批量,从连续部署所需的最小批量到更为传统的分支开发,在分支开发中,多个开发者工作数周或数月产生的所有代码将被成批处理,并集中到一起。

结果证明,以远小于传统做法的建议的批量工作,有极大的好处。




小批量意味着更快的反馈

工作转移到下一阶段越快,则也就能越快地发现下一个阶段是如何接纳你的工作的。




小批量意味着问题即刻被本地化

问题发现得越快,则解决的也越快。

每次部署,都只有少量代码有变化,所以导致回归或料想不到的性能问题的任何变化,都能够快速识别出来,并进行改正。当然,由于需要改正或回滚的变化数量不仅是确定的,也是很小的,所以解决问题的平均时间也就很低了。




小批量能够减少风险




小批量可以降低总开销

大多数机构都会降低自己的批量大小,以降低总的开销。
大批量导致的瓶颈经常是隐含的,是这些隐含的瓶颈显现出来,是需要开销的,甚至要投入更多的工作才能修正这些瓶颈。

连续部署的目标,是在减小批量的同时,帮助开发团队清除开发过程中的垃圾,加快工作步伐。这样就能使各个团队处于持续的流动状态,这种状态使得团队的创新、试验变得非常容易,从而形成可持续发展的良性循环。




质量卫士的挽歌

产生开发过程中的垃圾的一个很大原因是重复检查。

连续集成,有助于加快缺陷反馈流程;故事卡和看板,用于降低批量大小;日站,有助于加快步伐;连续部署也是这样的技术,有能力是开发团队更有活力。


为什么连续部署能行

连续部署区分了发布的两种不同的定义:

  • 一个是工程师使用的,指的是将代码完全集成到生产环境中的过程;
  • 另一个是市场部门使用的,指的是客户看到的东西

使用连续部署,代码一旦写完,就在去往生产环境的路上了。
连续部署也起着速度调节器的作用。

这种速度调节,对于习惯于通过个体效率来度量其进步的团队来说,是一种技巧性的调整。在这种团队中,每个工程师的头等大事就是保持忙碌。不幸的是,这种观点忽略了团队的整体生产能力。对于有些情形,大家坐下来讨论,找出协调方法,从而不需要做重复工作,这时候才是有效率的。




让我们开始吧

步骤1:连续集成服务器

这是连续部署的脊梁。我们需要一个中心服务器,运行所有的自动化测试,并监控每一次的提交。


步骤2:源代码控制提交检查

下一个需要的基础框架是源代码控制服务器,并带有能进行提交检查的甲苯。如CVS、SVN、Git等。

作为一个团队,我们的目标是在能够可靠地生产高质量代码的前提下,尽可能快地工作,但不要过快。


步骤3:简单的部署脚本

建立一个关键的部署脚本,用于逐台机器进行增量备份,与此同时,监控集群和业务的运行情况。这样一旦出现异常,就可以快速恢复。


步骤4:实时报警

无论部署过程多么完美,缺陷仍然会通过部署而进入生产环境。需要一个监控平台,以便事情一旦偏离正常,能够进行提醒,并找到人来调试。


步骤5:根本原因分析

无论问题多小,都要做些投资,而且各个级别都要做。
小的改进,经过经年累月,非常像复利。




连续部署用于关键应用

连续部署要求的第一个心态转移是:如果一个更新假设是无副作用的,马上发布。不要再等着与其它相关的更新捆绑在一起,否则,一旦发生副作用,就很难确定到底是哪个更新产生的。

第二个是心态转移是把市场发布的概念和工程发布的概念区分开。


  • 更快更好的反馈
  • 更多的自动化
  • 对真实环境测量数据的监控
  • 更好地处理间歇性错误
  • 更小的批量






作为代码的基础架构

只需要源代码库、应用程序数据备份、硬件裸机就能够把整个业务重建起来。

理想情况下,重组业务的最大制约是还原应用程序数据所需要的时间,应用程序数据是真正的业务价值所在。




面向服务体系结构

将系统的每个组件都分解为可通过网络访问的服务,这些服务集成在一起就构成了一个功能性应用程序。

通过将每个基本组件都呈现为服务、应用开发者可自由组装的新的应用,结果就是重用更为容易、封装更为清洁、错误排查更为简单。

  • 应该是模块化的

    • 做一件事,并且做好
      在SOA中,每个服务都很小——只做一件事,并允许其它服务调用。每个服务都很简单,但应用程序员要做很多集成工作。每个服务都专注于自己的狭小领域,则管理、开发、测试都会很容易。
      基础架构服务也是一样的,缩小每个服务的操作范围,就可以降低复杂性,从而他人也就易于理解其行为。
  • 应该是协作的

    • 让我们团结起来
      在构建通过网络API呈现的基本服务时,要鼓励别人和你协作,而不是重复实现相同的功能。每个服务都要设计成与其它服务协作的,尽量少假设服务的使用方式。
      服务的协作本性决定了用的人越多,则服务本身就越有用。对于基础架构服务而言,这种本性是至关重要的——随着基础架构的每个部分都成为可集成的服务,服务之间相互协作的方式会呈指数增长。
  • 应该是可组合的

    • 应该一切准备就绪
      理想情况下,每个服务都应该通过易于访问的网络API呈现自己的配置和功能,实际情况是:大部分都没有。


配置管理

配置管理是一种管理活动,从技术和管理两个方面作用于产品和生命周期、配置项,以及相关的产品配置信息。

配置管理是指对所有那些事情的跟踪,那些事情是把一个系统从裸机(baremetal)转变成做自己的事时必须要做的。系统管理员手工配置系统,并将笔记贴到wiki上时,他就是在实践着最基本的配置管理。软件开发者写了一个脚本来自动部署自己的应用程序,她就是在实践着自动化的配置管理。


配置管理是策略驱动的

  1. 把问题和解决方案的最终结果记入文档(设立策略);
  2. 写出在策略中要执行的代码(执行策略);
  3. 确认最终结果是正确的(审计策略);
  4. 重复这个过程,确保以后呢能够可靠的执行(测试策略)


系统自动化就是用代码实现配置管理策略

自动化几乎总是使用高级语言,自动化方式展现了三个原则:

  • 应该是灵活的
    • 无论需要什么,都应该有能力做
  • 应该是可扩展的
    • 遇到新情况时,要易于扩展
  • 应该是可重复的
    • 不管重复做了多少次,结果都一样


系统管理中的配置管理

配置管理工具应该有如下思想:

  • 描述的
    • 说明做什么,而不是怎么做
  • 抽象的
    • 让工具为你操心细节
  • 幂等的
    • 旨在需要时才采取行动
  • 聚合的
    • 只关心自己,并信赖其他服务亦然


系统集成

系统集成是指将各个组件整合为一个功能正常的、完全自动化的系统。系统集成侧重于广度,能否成功则依赖于对两个方面的理解:

  • 系统中的每个组件是如何工作的
  • 这些组件是如何相关的

应该遵循这两个步骤将基础架构构建为代码,这两个恰好也是系统集成阶段使用的步骤。系统集成就是将所有的东西整合在一起。


将基础架构分解为可重用的,可通过网络访问的服务

良好基础架构的十大核心原则:

  • 应该是模块化的
    • 启动过程将只处理这样的任务:使资源成为网络可访问
  • 应该是协作的
    • 启动服务应该能够将启动后的工作传给其他服务
  • 应该是可组合的
    • 能够从不同的服务中调用启动服务
  • 应该是灵活的
    • 足够灵活以应付不同类型的物理系统
  • 应该是可扩展的
    • 易于扩展,义启动新的资源类型
  • 应该是可重复的
    • 每次启动,都要生产相同的系统
  • 应该是描述的
    • 应该描述需要的系统类型,而不是如何安装和构建这些系统的细节
  • 应该是抽象的
    • 应该隐藏底层机制
  • 应该是幂等的
  • 应该是聚合的
    • 应该尽快将每个系统都启动起来,并为随后的操作系统做好准备,而不用担心其他系统的状态


将服务集成在一起

现在,你已经创建了一个如何引导和配置系统的策略,你知道接收标准是什么、能够列出实现步骤、能够对策略进行测试。这种做系统集成的方式类似于做一个多层蛋糕:每一层都建立在前一层的美味基础上,使得整个蛋糕更为诱人。






监控

我以前假定服务器资源是无限的,实际情况却是服务器正在为获得必要的内存而努力挣扎着。操作系统开始进行交换,CPU开始过载,从而响应时间开始变糟。

技术人员的观点和最终用户/业务的观点并不一致。

监控并不是设置一个系统,它是用来支持业务运转的,是用来保证系统中各个部分都在各司其职地工作着。能够正常工作也可以表述为保持网站的可用性。

可用性(A)可表述为:
A = Uptime/(Uptime + Downtime)

网站可用性受如下4个参数的影响:

  • MTTD(平均故障诊断时间)
    • 诊断该问题所花费的平均时间
  • MTTR(平均修复时间)
    • 用于修复问题所花费的平均时间
  • MTTF(平均无故障时间)
    • 正常运行的平均时间
  • MTBF(平均故障间隔时间)
    • 两次故障间隔的平均时间

A = MTTF/MTBF = MTTF/(MTTF+MTTD+MTTR)

并不是说你的业务需要接近90%或更高的可用性,业务要求的可能性只是一种期望值,如果宕机发生在周末,即使发生在工作日,只要还能工作,用户也不会说什么。你的目标是应该通过降低MTTD和MTTR,以及增加MTTF来增加可用性。




理解你在监控什么

技术组件的依赖项:

组件 依赖关系
应用程序 应用程序服务器、Web服务器、邮件服务器、缓存服务器、队列服务器
Mail服务器 Mail服务进程、网络、主机、存储
DNS服务器 DNS服务进程、网络、主机、存储
应用程序服务 应用程序服务进程、网络、主机、存储
Web服务器 Web服务器进程、网络、主机、存储
数据库 数据库服务进程、网络、主机、存储
主机 设备、OS设备进程
网络 设备、网络设备进程
存储 设备、磁盘、RAID控制器、接口
通用设备 磁盘、内存、CPU、接口、房屋
房屋 UPS、电源、温度

依赖项常常不受你控制,相反,它是由公司内不同的组管理的。从你自己的筒子里走出来,到其他部门获取相关信息,并不是很容易。正是因为你依赖于他们,所以更好地理解他们的就很关键了。这样你就不用在讯早问题的原因上浪费时间,在用户访问服务所依赖的那些组件上也就不会存在盲点。


不同部门之间的边界:

企业部门 依赖项
支援部门 能影响浏览器、桌面设置、防病毒/间谍软件
开发组 专注于应用程序更新
中间件组 经常运行数据库、Web服务器、应用程序服务器、邮件服务器、缓存服务器队列服务器
系统组 操作系统、DNS、DHCP、虚拟化、集群
网络组 交换机、路由器、VPN、代理服务器
存储组 SAN、NAS、备份、恢复
数据中心组 电缆、电力、UPS
安全小组 防火墙、安全策略

这样划分责任,在不清楚问题的真正原因时,会显著增加修复问题的时间。大量精力会花在努力证明自己部门的清白上面,从而延长了解决问题的时间。这份额外时间称为平均清白时间(Mean Time to Innocence)。
为了减少这种相互推诿的时间,良好的合作与协调很重要。持续的知识共享有助于增加这种共同应对问题的责任感。

组织边界到防火墙哪里就停止了,但Internet服务比内部控制的服务有更多的依赖项,这些外部依赖项有ISP、广告商、RSS信息、Internet邮件、DNS服务器、ISP连接等,内部依赖项和外部依赖项的主要区别在于,对于外部依赖项,你不知道这些服务是如何提供的。即使如此,也不能在监控这些服务上止步不前,毕竟它们仍然是你的服务的依赖项。

在无冗余的系统中,一个组件失效,整个服务就会失效。当一个组件的失效会影响整个服务时,这种失效就称为单点故障。这种影响既指服务完全中断,也指对服务质量的影响。
为了避免单点故障,通常是在架构中的多个位置增加冗余,这些冗余是你的环境的安全卫士,而不是对问题的某种补偿方式。通常,增加冗余会增加复杂性,所以不要掉进过度设计的陷阱。

一些冗余机制:

服务/组件 冗余机制
应用程序 负载均衡器、状态复制
Mail服务器 一个域名多条MX记录
DNS服务器 一个域名多条NS记录
应用程序服务器 会话复制、多实例安装
Web服务器 Web服务器服务进程
数据库 集群服务、水平区分
主机 虚拟化、集群
网络 多网关、BGP、VRRP、多ISP
存储 RAID、镜像、多重路径技术
通用设备 多网卡、CPU、内存
数据中心 BGP任播、GSLB


不要忘了检查监控服务的依赖项,如果监控都挂了,那还监控什么呢。

各种检查:

检查种类 例子
可用性 能访问80端口吗?HTTP进程在运行吗?数据库能访问吗?
功能/既时 应用程序在请求数据库,OS在进行DNS查询,控制器在进行磁盘写入,负载均衡器在请求Web服务器
功能/模拟 模拟HTTP请求、DNS请求、发送邮件
质量/利用 CPU、内存、磁盘等硬件信息使用情况,可以知道机器是否有足够的处理能力
质量/效率 Squid缓存命中率
质量/吞吐 订阅数、登录数、请求数、进/出请求数,用户数,数据库连接数,活动连接数,实例数
环境 配置监控,安全监控,备份监控
可信性 邮件域的垃圾邮件防范级别,SSL证书


不同层级的检查:

层级 例子
业务 内部网管理站点
交易 登录、增加文档、分享链接、注销
服务 Mail、DNS、Web服务器、数据库、路由、防火墙
机器 服务器、CPU、内存、交换机




理解正常行为

即使你了解所有依赖项,但设计一个好的监控解决方案仍是要花时间的。需要根据业务实际需求和变化对监控实施改变。

一些监控中的主要问题:
如果多次报警基于同一个原因,应该只发送一次报警;
夜间,备份可能会在生产网络上产生很高的负载,这样由于响应时间的变慢而导致多个ping失败和其它可能的误报,从而产生起起伏伏的报警;
如果我们想要随时待命的支持人员,必须尽可能降低报警和误报的次数。


加入的检查越多,消耗的生产系统的资源也就越多,这些资源可以是传送数据的带宽、计算结果的CPU…
你需要找到正确的平衡:监控太多只会浪费资源,从而降低对整个状况的了解;监控不足将导致不能及时报警。越靠近业务层的检查越有机会检测出问题,而越底层的检查越能够对发生的问题进行定位。

监控被认为是运维环境的一部分,通常是由系统或网络管理员来管理的。开始时是一个很小的系统,在后台运行。随着监控环境的扩大,需要执行更多的配置和定制。虽然运维人员常常是第一个对要部署的新软件进行仔细检查的人,他们的标准却往往并不应用到自己的监控系统上。监控系统是你的关键应用之一,请一视同仁。


监控的最佳实践:

实践 说明
版本 对你的检查进行版本华,并把他们放入版本控制库中
不同环境 使用不同环境开发、测试新的检查
测试 将检查作为通常代码对待,在代码功能中加入测试
可使用性 创建一个所有组件及其关系的可视化总览图,指出失效和组件的关系对工程师很有帮助,只需要看一下仪表板就能明白问题出在哪里
信息架构 使用不同的数据表示法,将数据组织为层次结构以便于导航,同时还要避免信息过载
代码重用 如果能够重用所监控的应用程序中的业务逻辑,就不要自己写
无硬编码 避免将参数编码在脚本中,使用配置文件,这也易于脚本在不同环境中的迁移
部署 要易于部署和分发新的检查
备份/还原 备份监控数据,并了解在什么情况下需要还原
监控 监控你的监控系统
冗余 在监控上,使用高可用性的功能做维护工作
应用的安全规则 监控账号与其它事务账号分开
是用最小特权级
不要将密码保存为明文
限制对系统的访问,不要将其用于其它的测试
将监控系统用防火墙或代理系统保护起来,避免来自易受攻击的主机的访问

所有信息一旦采集和存储,接下来做的就是分析检查结果。服务或系统的状态有可用(Up)不可用(Down),某些监控系统还增加了两个状态,一个用于系统不可达(Unreachable),一个用于系统/服务尚未检查(Pending)

有的时候,在位新服务建立环境时,预先定义的阈值很困难——实际使用可能会超过预期,或者相反。所以,对阈值进行不断的调优就有意义了。先根据理论上的假设定义一组阈值,然后在测试环境中模拟预期的行为,并翻译为技术化的组件使用情况。因为系统及使用情况的复杂性,对系统、应用程序、用户行为建立精确的模型是很困难的。所以,对阈值只能持续不断地研究与改进。趋势分析确实有助于定义阈值,大部分监控软件都可以让你对监控的值做趋势分析,而不产生报警,根据历史数据得出阈值之后,再启动报警设置。

管理报警并不仅仅是状态变化时发出报警信息。所有报警如果一直打开着的话,工程师将无法安心做系统支持,因为报警信息太多了,可能要被报警轰炸。同样,如果有太多假设报警,也会导致同样的问题,这可以看成是你的监控系统存在技术缺陷。
警报应该产生行动。如果一条警报可以忽略或不需要人工干预,这条报警就是一种浪费。然而,消除噪音却是真正的挑战。警报太多会导致狼来了效应,由于警报过载而忽略了正在重要的警报。

为了使网站可以忍受而限制报警是好的,但假如与业务需求不一致的话,就不行了。反之也是对的,如果业务不需要的话,为了显示网站运行正常而发送很多报警信息,也是毫无意义的。使监控保持正确的平衡,这很重要。




有备而学

一个人不可能在每个方面都是专家,有一个清晰定义的升级路径,从而把问题提交给更为专业的人员去处理是明智的。
对紧急报警进行跟踪和趋势分析,有助于提出架构和过程的改进建议。

故障时间本身并不仅仅有功能失效引起的,也可能是由于维护活动产生的。维护活动产生的故障时间被描述为维护窗口。在这种情况下,业务部门是认可默写故障时间的。为了避免不必要的报警,监控系统可能会在这段时间关闭报警。这会导致丢失一些与此次维护无关的系统/服务故障。所以,应该只关掉与维护相关的报警,而不是整个报警系统。然后,一旦服务运行稳定了,就要打开报警。




结语

监控并不是要保持服务器运行正常,也要保持业务运行正常。理解了技术组件和业务行为,你就会有相当的把握减少和修复问题上的时间。错误总是会发生的,但要为此做好准备。万一系统失效,一定要将反馈信息发送给每一个希望听到的人,并对事情做出改进,避免再发生新的错误。愿监控的力量与你同在。






复杂系统是如何失败的

所有复杂系统失败时,都有共同点。Web运维就是这样一个领域。




复杂系统是如何失效的

  • 复杂系统本质上都是灾难系统
  • 复杂系统都被重重地然而也是成功地防护着
  • 灾难要求多点失效——单点失效是不够的
  • 复杂系统包含潜藏在其中的缺陷的变化混合物
  • 复杂系统以降级模式运行
  • 灾难随时会发生
  • 事后归结为”根本原因“是错误的
  • 幕后认识对人类行为的时候评估存在偏见
  • 人类操作员有双重角色:作为生产者,以及作为失效防护者
  • 所有操作者的行为都是赌博
  • 最为困难的行动解决了所有的模糊性
  • 人类操作者是复杂系统的可调整因素
  • 复杂系统中人类专门处理知识处于不断变化中
  • 变化会引入新的失效
  • “原因”观点限制了对未来事件的有效防护
  • 安全是系统的特性,而不是系统的组件
  • 持续创造安全的是人
  • 无事故的运维需要经历事故的历练


针对Web运维而言:

  • 了解系统失效很困难
  • 了解哪部分失效很困难
  • 有意义的响应会被延迟
  • 沟通会产生紧张,而脾气会冒火
  • 维护会成为新的失效的主要源头
  • 从备份中恢复本身就很困难,而且还有潜在的危险
  • 创建测试过程,一线人员用来验证系统状态
  • 对运维进行例行的每日管理
  • 控制维护
  • 定期对性能进行评估
  • 要成为(独一无二)的用户






社区管理与Web运维

运行一个大型且广为人知的网站,意味着会有大批人依赖于网站快速而稳定的服务。这些人会形成一个社区,以各种有趣新颖的方式进行交流,并彼此关照。

社区起着一个交流、沟通、反馈的渠道作用。






处理非预期的访问量激增

有些时候,因为某种原因,Web的访问量会急剧增加(是正常用户访问而不是遭受攻击),我们的服务器就会遭受严重的考验。




一切是如何开始的

开能由于某个原因,导致Web流量激增,而我们服务器却无法应付这么高的并发和流量,所以导致Web瘫痪。




警报连连

监控软件(如nagios, zabbix)警报连连。Web请求太多导致响应很慢或奔溃。




扑灭烈火

查找是哪些环节导致Web响应很慢或奔溃,对之做相应的优化。




未雨绸缪

当我们经历了非预期的流量激增,并处理优化之后,下一步就需要对整个基础架构进行加固,或转向新的架构。




救命稻草CDN

解决带宽问题要靠内容分发网络(CDN)——在多个地点存储文件,为客户提供最近最快的响应。
大部分静态资源适合移动到CDN上,以减轻原始服务器的负担。

但CDN也有一些不足。对于移动到CDN上的数据,你就失去了控制。对于短时间的静态内容,CDN的效果并不好。




代理服务器

代理服务器处于我们系统的最前沿,尽可能让代理服务器转发请求,而不使用任何其它资源。




围剿踩踏

如何避免缓存踩踏?

  • 一个是对数据库进行优化
  • 一个是搭建数据库集群




将代码基流水化




怎么知道它能否工作

确保系统能够处理负载的唯一途径是在流量汹涌而来时,对其进行现场测试。




真实测试

必须要在真实的生产环境中查看其负载效果,才能确保其能正常工作。




教训

总要为未来几年做一个规划——问问你自己:“当前的架构方案能够用于未来几年吗?”

要测试生产环境,经过适当的测试规划,很多问题是可以避免的。

当一个架构方案已经明显不能工作的时候,必须要有重新考虑整个方案的勇气。
重新思考代码、硬件、网络、数据库模式,为可见的未来创建一个伸缩性更好的系统。




改进

针对遭受的问题,之后对系统的改进。






开发者与运维者的协调与合作

很多网站都将其开发和运维分为两个独立的团队,开发负责开发新功能和对现有功能进行改进,运维负责网站的正常运行。
两个团队有不同的目标,工作方式的要求也是迥然有别。

这种设置很常见,但也是保证网站稳定性或及时推出新功能的最糟糕的设置。

这在种情形下,开发人员没有动力将网站做得更易于运维支持,开发团队交付的代码通常是一个黑盒子,一旦发生意外,运维团队没有办法及时去修复问题。这种结构也抑制了新的功能的开发、构建和部署网站的新版本,不仅耗时,成本高,还涉及很多不同团队之间的协调。对运维来说,部署是存在风险的,而且也是造成很多宕机事故的原因。

传统的运维和开发,两者之间存在着很多对彼此很有用的信息。对很多网站来说,性能瓶颈都出在应用程序代码上:开发团队最适合修正这些问题,但运维团队有测量数据,要想找出问题出在哪,是需要这些数据的。关于什么地方可能会出问题,以及如何修复,开发团队有很多很好的想法,但这些却很少会记录在文档里面。

所以,重新评估运维跟开发之间的关系!




部署

以合适的方式进行移交,则不同团队之间就能更好地共同工作,而改变过程这是困难的,需要协助以及每个人的认可。

一项服务之所以受人欢迎,频繁部署也是重要原因之一。小批量代码更新。

用户报告问题后,极短时间内就得到修复,这一做法会彻底征服用户。有了这种响应凡是,则将来有了问题,用户也会很乐意报告给你,这样产品就会越做越好,特别是你能够一直这样快速反应的话。对关键的数据损失或安全缺陷能够在短时间内而不是几周响应的话,用户的数据就会安全得多。

然而最重要的是,频繁部署并不比周部署或月部署风险更大。很多小的更新,每个都单独测试和检查过,比起一次大的更新来说,导致严重宕机的事故的可能性要小很多。

这是因为小更新的影响能够提前单独进行复审和测试,从而错误造成的影响也易于量化及应对。定位代码中的缺陷,复审10行的更新比起10000行来,会容易得多,而且只测试那些受更新影响的功能,比起测试整个系统,也要快得多。而且能够确保每次部署都只是更新一个区域,从而避免同时更新的两个组件之间发生预料不到的交互作用。小部署意味着更容易预言更新对基础架构的影响,而这也就意味着未雨绸缪更加有的放矢。

如果只是部署30行代码,缺陷通常是自明的。如果缺陷不自明,其影响也会非常小,即使回滚也非常容易。


只有在遵循以下三条规则的情形下,频繁的小更新才起作用:

  • 构建与部署系统必须能够完全重复且自动地工作
  • 具有几近完美的预演环境
  • 部署必须尽可能快,理想情况是小于5min

大多数构建和部署系统在某种程度上都是自动化的,少数团队走得更远,把构建和部署做成了一键操作。




共享、开放的基础架构

很多情形下,运维和工程都分为不同的小组,你会发现支持的基础架构也会一分为二。

共享基础架构是在团队之间进行协作的最容易的方式。

为了有效地工作,你需要了解系统的其它方面目前是如何运转的。为了建立信任,你需要使你的工作变得透明。




信任

信任是开发和运维之间最常见的紧张关系之一。多数运维团队对开发团队多少都有点怀疑,开发人员通常也好不到哪去。团队之间的不信任是不健康的,也是不合适的。

信任最终是建立在一种尊敬的感觉之上的。如果你尊敬某人,就很容易信任此人能够做好他的事情。反之,如此人交往便会带有偏见、不满等情绪。

运维和开发之间的许多问题都是由于对两个团队不同角色的重要性认识不同而造成的。

充分尊重你的同事,而不是事后指责他们。




随叫随到的开发人员

只有在开发人员对修正生产系统代码中的问题肩负起责任的情况下,才是有意义的,而这就意味着开发人员随叫随到。


现场调试工具

很多代码对于运维团队来说都是黑盒子。

要想办法在运行时调用额外的调试信息,技术团队的每个人在用管理账号登录系统之后,都可以开启额外的调试信息。


功能标识

禁掉某些依赖于问题架构的功能,而保持网站的其他部分正常运行,功能标识能够实现这一点。

  • 单个标识,用来禁掉每个非核心的基础架构
  • 只要这些服务出现问题,我们都可以暂时并优雅地禁止掉这些功能
  • 如果生产系统出现新的错误场景,也可增加新的标识




避免职责

在很多团队中,没有人愿意成为搞坏所有事情的傻瓜。发生问题时,人们都会将责任推卸给别人。

每个人都有貌似合理的理由将指责转嫁给别人,却没有挺身而出,实实在在地修复问题,组织良好的团队深切地了解,在将问题修复之前,争论到底是谁的责任是没有意义的,为保护自己而浪费的每一分钟,由于问题没有修复,都会成为给用户带来损失的一分钟。用户会尝试各种可能性,知道他们发现系统出问题了。

多数生产环境都有足够的冗余,也足够复杂,任何问题都不太可能存在单一的根本问题。很多问题都是由两个或多个系统发生意料之外的交互作用而引起的。




结语

网站的稳定性是每一个人的责任,而不仅仅是某种应该交给运维团队去处理的东西。

让人人都拥有对网站的主人翁感觉,确实意味着能够减轻运维团队的工作负担。他们不用再花费大量时间呼吁采取防护性措施,一旦发生问题,也能够花更小的时间修复。这非常了不起,因为这意味着网站的宕机时间会减少很多。这也释放了运维团队,让他们能够把精力放在更为重要的任务上,即对基础架构的长期增长进行管理。






你的访问者感觉怎么样:面向用户的测量

对于网站的成功而言,终端用户的测量也就变得和后台测量一样至关重要。




为何要采集面向用户的测量数据

采集数据,从而就可以对业务的健康状况进行分析。

如:

  • 每秒请求数/发布数
  • 带宽
  • 响应时间
  • HTTP错误率
  • 记入日志的异常数
  • 进程重启次数
  • 队列大小
  • 服务器的平均负载和进程数
  • 数据库负载
  • 内存


成功的创业公司所学到的以及必须适应的

创业公司的一大优势就是敏捷,即快速反应的能力。要真正做到敏捷,创业公司需要了解终端用户真正体验到的是什么。

任何网站想要成功,就必须向用户学习,而且必须适应用户的需求。很多Internet巨头,它们现在的业务,都与其当初设定的相比有很大的不同。


性能问题

响应越快的应用程序越好!

响应级别:

  • 加入事情的响应时间在10ms内,我们的大脑就会认为这是真实的
    • 如点击桌面系统上的按钮
  • 如果谈话有100ms左右的延迟,我们不会感觉到这种延迟
    • 如国际长途电话
  • 如果应用程序的响应时间在1s之内,我们的感觉就是仍然在与应用程序互动,仍然在工作
  • 应用程序的响应时间要是明显长于1s的话,我们就会抓狂


研究量化了这种关系

Web应用的速度越快,其Web业务员的优势就越明显!

如果你的网站很慢,你将得到:

  • 更少的用户搜索
  • 更少的精度搜索
  • 更少的每访客收入
  • 更少的点击,更低的满意度
  • 更少的每日搜索
  • 等待访客点击的时间更长
  • 更低的搜索引擎排名
  • 更差的用户体验




是什么使网站变得很慢

简单来说,由以下三点原因造成:

  • 服务器花在处理用户请求上的时间
  • 网络花在传输请求和响应上的时间
  • 用户花在组装并显示结果内容上的时间


服务发现

开始访问网站,用户都需要先找到服务器。

对于带有很多组件的网站——这是一个日渐普遍的模式——都会迫使用户去解析很多网站,并且页面加载的时间也延长了。


发送请求

网络再快,用户与服务器之间的往返也是需要时间的。

请求包含的内容越多,则网络用来传输的时间就越长。加入是一个安全页面的话,还会有另外的延迟,用来在客户与服务器之间进行加密协商。


响应

请求到达服务器之后,另一个导致延迟的罪魁祸首就登场了——主机。不论是从内存中检索静态对象,还是利用后台的第三方服务来完成一个复杂的请求,主机延迟都会对性能造成影响。


发送响应

响应内容一旦准备就绪,服务器就可以通过HTTP协议发送这些请求对象——大多数页面包含多个对象(如html,css,js,gif,png,jpg…),正是这些对象的发送造成了访客体验到的延迟。


异步通信与刷新

某些应用包括一些客户与服务器之间的通信,这些通信是独立于页面进行的。
包含某种异步更新或刷新的应用,有不同的延迟测量指标。


渲染时间

随着客户端越来越复杂,浏览器做的也就越来越多。有可能是启动富互联网应用(RIA),这些RIAs都是构建在Flash、Flex、HTML5、Java、JS…之上的,也可能是运行QuickTime或Windows媒体播放器等这样的插件,甚至决定如何对复杂页面进行布局也是需要花费时间的。
所以,对于大量依赖客户端进行渲染的网站,就必须考虑这种延迟。




测量延迟

有两种测量方法:

  • 综合监控
  • 实际用户监控(RUM)


综合监控

综合监控是通过从多个地点对网站进行一系列正规的校本化测试,对网站的性能进行监控。

要记住,综合测试也是要消耗服务器资源的。


真实用户监控

RUM的工作名副其实:它观察的是网站的真实访客,记录访客打开页面的速度,然后生成报表。

从这点来看,RUM会告诉你系统是否出问题了,因为你可以通过RUM发现问题以及速度变慢的情况,这些情况你没有进行测试,从而也就不知道是否存在。




编写SLA

Web运维收集终端用户的数据的一个主要理由就是用来编写SLA,哪怕与客户之间没有正式的SLA,但对于正常工作时间及页面延迟,也应该有内部的目标,因为网站速度对用户体验有直接的影响。




访客结果:分析

对于成功的Web运维来说,监控就是了解存在哪些不利因素。而当进入Web业务时,这些测量就要让位于Web分析了。


市场营销如何定义成功

对市场营销的最好描述——“更经常、更有效地卖出更多的东西给更多的人,从而得到更多的钱。”
或许应该将成功的在线营销更精确地定义为“让人们有效地去做你要他们做的事情。”


网站的四种类型

  • 交易性网站
  • 协作型网站
  • 作为服务(saas)网站
  • 媒体网站

很多流行网站都是上述模式的混合。

网站分析就是对每种类型网站的成功因素进行追踪,从中识别出使这些因素得以增长的背后动因——不管是广告活动、性能的提升、社会网络上的关注、特殊的定价模式还是某个引人注目的内容。


分析一个简单的模型

有一个简单方式来考虑网站分析,就是做一次访问。

网站分析的目标,就是通过优化网站,将访客的转变最大化,通常是对网站进行试验,并针对各种内部和外部区段,对这些试验结果进行分析。




市场营销关心的其他测量数据

Web交互分析

分析查看的是用户对多个页面的整体访问情况,Web交互分析集中在单个页面的可用性交互上。


用户之声

用户之声工具用来询问客户在想什么。这些工具从网站的访问性中征求反馈,通过请求客户参与调查,或者在页面上提供一个反馈按钮。




用户体验如何影响Web运维

随着新建公司对终端用户体验的关注,Web运维的角色正在发生变化。对线上事务的兴趣越来越浓,而且通过追踪分析,网站的所有事情都能够和业绩联系起来。


将监控作为生命周期的一部分

网站现在已经有了很大的变化,随着敏捷和精简产品开发的流行,监控也需要跟上。所以来的综合监控脚本以及RUM配置也需如此。


Web监控的未来

终端用户体验的监控正在兴起,变化很快。这是业务中最能进行分析、量化的部分,每周都能涌现出新的技术。

  • 从系统转向用户
  • 以服务为中心的架构
  • 云与监控
  • APIs与RSS消息






将关系数据库用于Web的战略战术

如何为产品或应用程序设计一个良好的关系数据库架构,如何构建良好的互联网数据库架构?




Web数据库需求

其实,大多数网站,相对而言,都只是小型数据库。
一些大型公司,可能才是一个大型数据库。


一直在线

数据库通常要7x24小时运行。
一直在线意味着维护和运维任务是很难做的,你不能简单地等到人们回家了然后将服务器卸下来,给硬件升级或备份。必须在不停机的情况下做这些事,而且很多情况下还不能给应用程序增加额外的负载。

话虽这么说,还是极少看到没有峰值时间的数据库。所以,还是有很好的机会,在数据库活动的间歇期来做备份或对数据库产生干扰工作。


事务最多的工作负载

很多互联网应用都匹配以下模式:

  • 应用程序读远大于写
  • 一次读一行和一次读多行是混合出现的
  • 一般,写每次只影响一行

这就是称之为的事务型负荷


简单数据,简单查询

网站的流量很大程度上决定了数据库的流量。

查询通常会满足下面的模式:

  • 读写用户表,一次一行
  • 以区域或集合方式读取用户自己的数据
  • 以区域或集合方式读取其他用户的数据
  • 从该用户到其他用户的关联表中读取区域行
  • 对该用户和其他用户的数据进行汇总与计数

特别低,很多数据可以分区存储的事实说明了为什么分片(sharded)架构是可能的。


可用性胜过一致性

从业务的角度看,最重要的事情是应用程序对用户的可用性。


快速开发

传统应用极少以天或周为周期构建和部署,但对于大量Web应用来说却是常态,这些Web应用是永远的Beta版。


在线部署

模式和数据的更新都做成代码形式,而且也有这样的框架,部署这些代码或将其回滚都很容易。


由开发人员构建

大量的应用程序都是由开发人员做的,都没有一个高水平的DBA。




典型的Web数据库是如何增长的

大多数Web数据库的增长,都经历了一些列的架构变动。这些架构变动,在应用程序的整个生命周期中,相对而言都是可预知的。


单台服务器

一般应用程序都是从单台服务器开始起步的。使用单台服务器有很多好处:

  • 数据只有一份拷贝,不存在你的数据是否正确或不同的问题
  • 易于配置
  • 便宜

当然,缺点就是只有一台服务器!假如发生问题,没有冗余机器做故障转移。性能也会受影响。


主服务器与单复制从服务器

各数据库的复制技术都不一样,但一般而言,发生在主服务器上的数据修改,都要在从服务器上重复一遍,所以从服务器是主服务器数据的只读拷贝。依赖于数据库、系统负载以及执行的查询类型,从服务器不一定时刻与主服务器的数据完全一致(异步复制)。

增加一个复制从服务器有很多好处。数据库读请求可以在主、从指间分担,这称为读写分离。可以在从服务器上执行那些效率不高的查询、备份以及其它有可能对网站造成破坏的任务。


主服务器与多复制从服务器

大多数复制技术对两台或多台从服务器都没问题。
这样确实不错,而且随着从服务器越来越多,系统的数据库读取能力也越来越强。但这种增长不是无限制的,在很多层面上都会遇到收益递减的拐点。

  • 第一个层面就是应用程序中读对写的比例
  • 第二个方式表示主服务器的写操作有多忙,其中你会看到收益递减的情况
  • 第三个限制是操作成本和复杂性
    • 管理一群服务器,比管理单台服务器,要难得多也昂贵得多
  • 最后一个不足是应用的复杂性
    • 从单一数据源走向两个数据源,对于大多数应用程序而言,都是一个重大转移。应用程序不得不连接多个位置来进行查询。连接池、负载均衡器以及类似技术会在一定程度上保护你不受这种复杂性的困扰,但最终应用程序仍然要面对某种程度的复杂性

复杂性的一个最大来源是异步复制。异步意味着写操作先在主服务器上完成,随后送往从服务器执行。结果就是,从服务器总是拖后于主服务器某段时间,即时这段时间很短,但由此而造成的问题却很大。这可能会导致用户体验的不一致到数据完整性等一系列问题。

一般而言,不存在修复这个问题的神奇方法,应用程序必须自己处理这种延迟复制。
一种不错的简单技术是基于会话的分裂。用户做了更新之后,一段时间之内,该用户的所有查询都导向到主服务器。认为能够安全地查询从服务器所需的时间戳通常都存储在会话里。


功能分区

复制只对读有伸缩,对写没有。随着应用的规模越来越大,写操作的负载最终会大到系统无法处理。

功能分区(functional partitioning),假如将某些部分与其余部分分开,则这些部分可以独立增长。
如,对于博客服务,可将评论功能分离到它自己的服务器中。

从运维角度来看,不同部分处在不同位置,则应用程序的功能也就能够单独对待。比起网站宕机,将评论改为只读模式,用户的反感可能要小得多。

这种做法的不利之处是增加了复杂性。应用程序需要从多个位置获取数据,而运维团队必须保持这些服务器正常运行。


分片

分片(sharding),是将单一逻辑数据划分为多个片段并发布在多台服务器上的一种方式。所有的片段在逻辑上和功能上都是相同的,虽然这些片段分别包含数据的不同子集。

分片架构的主要设计目标和优势都是双重的。第一是允许写伸缩,因为负值无法实现写伸缩,假如应用程序的写操作草果了任何单台服务器能承受的程度,就必须要分片以减少写操作的负载,写操作的负载必须分担到完全隔离的服务器上,对一个分片的服务器的写操作不能复制到另一个分片服务器上。第二个目标和优势是,随着数据集的增长,能够增加更多容量的能力。

在分片架构中,许多查询也变得困难或不可能了。例如,需要访问所有客户数据的查询,通常都要在每个分片上分别执行,然后在应用程序代码中在聚合在一起。

分片架构还存在很多其他的不足和复杂性。


缓存层

缓存层的目的是阻止查询到达数据库。
标准的例子是:memcached,redis

缓存层的主要优势是极为容易,并且简单。

从运维的立场来看,需要考虑缓存服务器的冗余和可用性,就像为其他服务器所做的一样。




对集群的渴望

在应用程序出现某种问题,或关于可用性或伸缩性的困难问题来的时候,人们的思想就会转向集群(cluster),就像年轻人的思想转向春天和爱情一样。


CAP定理以及ACID和BASE

CAP原理: 一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)。你可以具有两者,但不能三者皆具备。

ACID: 原子性(Atomicity)、一致性(Consisitency)、分离性(Isolation)、持续性(Durability)。

BASE: 根本可用性(basically available)、软状态(soft state)、最终一致性(eventual consistency)。


MySQL集群的状态

MySQL Cluster是将MySQL服务器作为一个完全不相干的、称为NDB的软件的前端。NDB的意思是网络数据库,这是一个极快、分布式、无共享、高可用的数据库。


DRDB和Heartbeat

DRDB在服务器之间对块设备进行复制,将修改的块通过网络复制给备机。如果主服务器失效了,则Heartbear激活备机。

从运维的角度来说,DRDB非常棒,装上就能工作,但却不能满足在线用户的需求。它不是为满足典型Web应用的高可用性而设计的。相反,它非常适合用户保证你不丢失数据的情况,也就是说,它关注的焦点是一致性而不是可用性。

另一个问题就是基于DRDB的集群不能改进性能。Web应用需要的是正常工作时间和性能,而基于DRDB的集群是以性能为代价来提供一致性,而一旦失效,宕机时间就会很长。


主服务器到主服务器的复制管理器(MMM)

MMM是一系列的Perl脚本,管理复制和虚拟IP地址,从而为MySQL提供一个伪集群(pseudocluster)。

应用程序连接到虚拟IP而不是服务器的真实IP。服务器发生问题时,MMM将该服务器的虚拟IP移动到另外的可用服务器上。它也可以将复制从服务器从失效的主服务器移动到正常的主服务器上。MMM允许手工将服务器离线执行维护任务。


带复制的Heartbeat

如果MMM无法完美地管理复制和虚拟IP地址,heartbeat考虑以下?

不管怎么说,复制延迟仍然是一个复杂的问题。必须在应用程序层解决这一部分问题。


基于代理的解决方案

有一种可供选择的方案,基于代理(proxy),需要人工介入,MySQL Proxy位于前端。HAProxy是另一个流行的方案。

  • MySQL Proxy,事实上能够理解MySQL的协议,并且拦截、解释以及传递消息
  • HAProxy,只是传递TCP流,并不对内部进行窥探

基于代理的解决方案仍然没有入人们所愿的那样解决复制延迟问题,而且还引入了单点故障,并且影响性能。


小结

前面讨论这么多,简而言之,就是没有一个完美的、万能的答案。

最好的数据库架构是为了应用而建的,期待集群所承担的指责分布在数据库、网络以及应用程序上,有运维的适度介入,以及起粘合作用的软件,就能把各部分整合在一起。




数据库战略

如何选择一个对于大量的互联网架构来说都能够运转良好的架构。


架构需求

最好定义你的需求,特别是,把那些超出你的范围从而成为别人的问题的内容写成文档。


有把握的架构

以下数据库架构,是比较有把握的。


  • 单主服务器,多从服务器
    这种主-从架构很难自动实现主服务器的故障转移,因为主服务器和从服务器的配置是不一样的,所以,一旦主服务器失效,则必须手动进行失效转移。

  • 主服务器-主服务器复制,外加从服务器
    这种方式实际上与一台主服务器加多台从服务器的架构一样,但有时候主服务器本身也成为从服务器。这种架构的优点是,在协同的主服务器之间更容易实现失效转移和失效转回。缺点是,向两台主服务器进行写入存在风险,会导致数据库存在某种不一致性,也很难解决。

  • 功能分区
    随着应用的增长,将应用中某些部分转移到特定的服务器或特定集群上。

  • 失效转移和负载均衡
    使用负载均衡器,或者浮动的虚拟IP地址。

  • ACID仍然是有意义的
    高可用性要求快速而可靠的灾难恢复。

  • 使用正确的工具
    不要使数据库处于关键路径上,不要讲应用程序的静态信息放入数据库中。数据库应该存储数据,而非应用程序本身。将数据库简单化,因为这是最难于伸缩,也是最昂贵的资源。但是,对于Web应用,还是应该分离应用程序和数据库,将数据库仅用来存储和检索数据。


有风险的架构

建议不要使用这些架构


  • 分片
    除非不得已,不要分片。
    对于一个中等规模的应用,将其构建在数百台低档机器的分片架构上,试图提供无线伸缩能力,是非常愚蠢的。其实,只需购买几台足够好的机器,在工程上多做一些考虑就足够了。
    分片架构比你预想要昂贵的多,甚至在短期内也是如此,长期则一定如此
    分片问题设计过度设计的风险

  • 写入多台主服务器
    不要将多台服务器配置为可写,这会造成数据一致性问题。非常麻烦。

  • 多级复制
    尽量不要使用多级复制。
    使用一主多从而不是从的从的从服务器,要简单的多。孙子辈的从服务器和重孙辈的从服务器很难管理。

  • 环形复制
    避免使用环形复制,其失效情形,不管是数量还是复杂度,都打得超乎想象。

  • 依赖于DNS
    DNS很脆弱,依赖DNS最终会自食苦果。




数据库战术

数据库战术,即为保持数据库基础架构的可靠性而做的日常运维任务。


在从服务器上做备份

一些小提示:

  • 在备份上不要拖延,做备份其实并不难
  • 做事不要追求完美,而要追求可恢复
  • 至少对于可接受的数据损失、可接受的宕机时间、数据持续策略以及安全需求要形成文档
  • 对恢复过程要进行练习并形成文档,恢复比备份要重要的多
  • 对于备份成功与否,要进行外部验证,不要依赖于作业自身对你的提示

可以专门配置一台复制(备份)从服务器,将复制延迟一段时间——如30min,以避免主服务器上的某些误操作——如DROP table


在线模式修改

将表做的小一点是很有好处的。

一般的想法是设置主-主复制对,但只有一台服务器可写。在只读上执行更新,但不要复制到可写服务器上。更新一旦完成,则用正常方式使应用程序实现失效转移。这样,读和写便实现了角色转换。然后在另一台服务器上重复执行风险。这就实现了对应用程序隐含宕机时间的目的。


监控和图示

构建用于测量和监控的系统是很值得做的事情,这些系统是基础架构非常重要的核心内容。


性能分析

一般步骤是,在产生麻烦的时间内手机详细的诊断数据,消除掉可能的原因,集中在问题的现象上。
问题往往是服务器产生大量负载,而这通常是由于糟糕的查询产生的。

MySQL所谓的慢查询日志(slow query log)可以回答这个问题,不仅是因为日志收集了慢查询的信息,而且对于每个查询还有时间信息。

加入性能问题不是查询引起的,则需要对MySQL本身进行性能测试。


归档和删除数据

从一开始就要规划归档和删除不活动或不需要的数据,这样有助于减小“工作集”的大小。

  • 将极不活跃的用户数据移动到慢速服务器,或仅仅将用户设置为过期。当用户登录或重新激活时,在倒回到正常表中
  • 另外一类可归档或删除的数据是陈旧的历史数据,或将历史数据移到另外的服务器上




结语

尽最大可能将数据库架构建立在逻辑的基础上,而不是做一些看起来很酷的事情。

努力使系统保持小巧,不要大——而当不得不变大时,也要保持在能够掌控的范围内。要确定应用程序的真正需求,尽可能满足这些需求。要尽早及经常做缓存,但不要尽早及经常做分片。

最重要的,请记住:做备份






如何优雅地失败:事后处理的艺术与科学

宕机意味着实际的金钱损失。
客户才不会管这些故障,他们要的就是可靠性。互联网已经变得非常重要,宕机成本也越来越高。

但正如一个刚毕业的年轻人一样,只是知道你需要成长,但并没有告诉你如何去成长。我们需要将失败转化为学习经验。

保证网站稳定的首要事情,就是建立一个系统化的事后分析过程。通过阻止事故的重现以及改进处理事故的方法,使得系统稳定之后,事后分析能够让你全面地理解事故的本性。

例行的时候分析,是对运维的复杂问题进行科学分析的最贴近的方法。通过收集实际证据,可将有限的资源集中于解决产生问题的实际原因上。




什么是事后分析

事后分析至少要包含这些内容:

  • 事故描述
  • 根本原因描述
  • 事件是如何修复的
  • 用于解决事故的行动的时间表
  • 事故是如何影响用户的
  • 纠正或改正动作

事后分析时,与事故明显有关的人员都要同时到场,对事故的真实情况作出共同的描述,从而正确地采取行动。

减少事故的修复时间,就跟消除事故本身一样重要。

对问题赋予严重级别,将帮助你按照轻重缓急来处理纠正项,而且对于活跃事件的评估也是有用的。

事故严重级别:

  • 严重影响大批用户
  • 网站降级运行、性能问题或很难应对的功能故障
  • 对客户影响不大或易于应对




什么时候引入事后分析

在事故处理完成之后,就应该进行事故分析。事后分析过程应该最终使用户获益,而不应该在恢复服务的过程中进行。




进行事后分析

开始事后分析时,要明确基本规则,要明确告知参与事后分析的相关各方,事后分析不是指责谁(人们害怕这样的会议变成政治迫害),主要目的是为了使类似事件不在重复发生。问题不可避免,重要的是我们能够从错误中学到教训。
事情一旦清楚之后,就可以开始讨论为了使类似事情不在发生,需要做些什么。确保相关各方对各自领域都能得出补救的办法。但切记不可矫枉过正!

一旦有了一套纠正措施,要将其记录在案,包括执行人员和完成日期。




事后分析的后续工作

对纠正措施必须进行追踪,直到执行完成。

一些网站可操作性:

  • 消除单点故障
  • 容量规划
  • 监控
  • 发布管理
  • 运维架构复审
  • 配置管理
  • 随时待命和提升过程
  • 不稳定的组件




结语

最后,对于避免事故的发生,事后分析是最有用的方法。在一个快速变化的环境中,发生问题时可以理解的,但问题重复发生却是不能原谅的。花些时间高清楚问题的实质,从而确定、记录以及实施高强度的纠正措施,就可以避免事故的重复发生。




存储

数据是一项最重要、不可替代的商业资产。


数据资产的库存

在开始一项新的存储工作时,首要的事情是要知道数据存在哪里。
对于不了解的数据,你是无法进行保护的。




数据的保护

数据保护对所有系统都是很重要的。
良好的数据保护实践有助于处理范围广泛的情形,从还原被用户偶然删除的文件,到从灾难事件中恢复。

为了对数据中心问题提供完全的防护,重要的是将关键数据复制到不同的地点。

如今大多数的存储系统都有某种类型的复制技术。复制通常有两种形式:同步和异步。




容量规划

在确保有效的的数据保护之后,作为一名存储专业人员,容量规划就是第二项最重要的职责。
规划在前,确保应用和服务有足够的资源来运行和成长,不至于碰到天花板,这是必须的。

总是确保有足够的空间以应对突然的爆炸性增长,以及软件开发方面出现的延迟。




存储大小的变化

存储是很昂贵的,这是现代基础框架中成本最高的组件。正是由于这个原因,对于存储上的开支进行明智地规划是很重要的。

存储需求要点:

  • 应用是什么
  • 应用位于哪里
  • 存储的是什么类型的数据
  • 需要共享存储吗
  • 是否需要特殊的访问协议
  • 典型的文件大小是多少
  • 数据是压缩的吗
  • 如果描述工作负载
  • 需要批处理操作吗
  • 工作负荷是大部分用于读、写、读写
  • 工作负荷是大部分顺序、还是大部分随机、还是两者
  • 快照是怎么安排的
  • 快照的一致性问题
  • 存储容量在6个月、12个月、18个月的计划是什么
  • 工作负荷在6个月、12个月、18个月的计划是什么
  • 复制策略是什么
  • 业务连续性规划是什么
  • 可用性需求是什么
  • 备份的频度是什么
  • 备份保持的计划是什么样的
  • 归档策略是什么
  • 综合性需求是什么
  • 加密需求是什么




结语

数据是最宝贵的业务资产,且是不可替换的。






非关系数据库

应用的数据存储层的伸缩是很难的。不管用的是什么数据库技术,随着数据量和事务数量的增长,就需要做出改变以适应新的负荷。

SQL数据库的可伸缩性通常归结为四件事:缓存、查询优化、购买新硬件、数据库分片。




NoSQL数据库概览

NoSQL共生系统,可将数据库划分为5大类:

  • 纯粹的键值
  • 数据结构
  • 面向文档
  • 高度分布

每种类别的数据库都面向不同的应用情况,每个类别也都做了不同的这种。




纯粹的键值

如: Tokyo Cabinet、 Kyoto Cabinet、MemcacheDB

正是它们的简单性定义了这组数据库。向数据库存入一个键和一个值,然后用同一个键查询数据库,则会得到相同的值。没有结构或类型系统——通常所处理的只是字节或字符串。因为这种简单性,这些数据库的开销极小,所以非常块。事实上,这些数据库通常都是实现为磁盘上的B树或哈希表。




数据结构

数据结构数据库对键值数据库做了些修改,数据结构数据库将其存储为特定的数据结构,如列表、集合、哈希表等。有了这些附加的结构,就可以对值执行一些原子操作。可以对数据库执行在应用程序中对数据结构进行的各种操作。

Redis默认是在内存中(in memory)存储其全部内容,只是周期性地将内容的快照存储到磁盘。这使得Redis出奇的快,但假如数据库奔溃了,就会对数据造成一些损失,同时也意味着必须有足够的RAM存储这个数据库。




图数据库几乎就是数据结构数据库的一个特定实现,因为图本就是一种数据库。区别是图数据库不再是基于键值,数据是作为图的节点和边存储的。图数据库不是用键来查询值,而是给出根节点的句柄,然后就可以遍历整个图以找到需要的节点或边。

图数据库的优势:存储图或树形的数据。如一个社交图(social graph)。

常见图数据库包含:Neo4j、HyperGraphDB、InfoGrid、VertexDB。




面向文档

面向文档的数据库又类似于键值数据库,但值不再是字节、字符串、列表、集合,而是文档
文档作为JSON(BSON)对象存储,本质上是一种哈希表或字典。这些值都想相同的结构,意味着可以用查询来探测这种结构,并只返回所需要的文档。这种查询能力是建立在通过键来查找文档的能力之上的。

常见面向文档数据库: MongoDB、CouchDB




高度分布

高度分布的数据库多少有些不同——有些本质上更接近于键值存储,其它则像大型的多维哈希图。

HBase、Cassandra是高度分布式数据库。




某些细节

注意这些数据库之间的一些相似性,以及所做决策是如何影响系统可操作性的。




Cassandra

Cassandra是一个高度分布数据库。

它有一些关键概念:

  • 认为写比读更难于伸缩,所以它专门为写操作做了大量优化
  • 认为不应该存在单一故障点
    任何数据可以写入到集群内的任何一个节点,而且读也一样。任何接收到请求的节点都可以,并且将会吧请求转发到合适的节点。




HBase

HBase选择一致性和可用性作为自己的核心价值。这样的结果,导致了在某些网段、集群无法实现优雅的恢复。作为这种牺牲的补偿,HBase有很强的一致性,保证写入一结束,写入的值就立即可以读取。




Riak

Riak实现了向量时钟(vector clocks),一些高度分布的数据库都没有实现——这些数据库选择了依赖于更为简单的基于时间戳的技术。

向量时钟是一种分布式系统中的机制,用于生成偏序事件。使用向量时钟,解决发生在两个独立的不同节点中的相同值的冲突就变得非常简单。从Riak客户端的角度来看,每个客户实例在Riak集群中执行一个动作时,都应该有一个唯一的标识(token)(连同其接收到的向量时钟一起)。然后,客户读取数据时,就可以看到向量时钟和数据值,使用包含的信息连接两个结果,从而将正确的版本写会数据库。

Riak也不存在单一故障点。




CouchDB

CouchDB对世界的看法是一致的:所有东西都是文档,而且都通过RESTful HTTP来访问。
CouchDB可以在数据库中直接存储静态媒体,它实际上是允许将整个应用程序都存储在数据库中的。
CouchDB的数据模型很新颖,即数据以一种只附加的B树进行存储。




MongoDB

MongoDB是一个面向文档的数据库,文档格式使用BSON——一种类似于JSON对象的二进制规范。MongoDB是用C++写的,因而有很高的性能。

所有能用SQL做的事情也能用MongoDB查询表达式来做。
MongoDB与以SQL数据库相同的方式支持索引,同时这些索引也强制了唯一性。

MongoDB有一个mongostat命令来查看数据库状态。

有好几种MongoDB备份方式:

  • 停掉数据库,复制数据文件
  • 锁定数据库写入,复制数据文件,解除锁定
  • 使用mongodump,将数据库转存到一个二进制文件中
  • 可以设置一个从服务器,在从服务器上进行备份,而不是主服务器上




Redis

Redis(remote dictionary server),远程字典服务器。通过INFO可查看相关信息。

不管你将Redis运行在快照模式(rdb)还是只附加模式(aof)上,都可以简单地调用rsync实现备份。






如何高枕无忧

企业持续规划(Business Continuity Planning)BCP。
BCP简单最简单来说,就是什么都是两份。当然,两套设备间的失效转移必须完全自动化。




术语

集中于BCP计划的高可用部分:保证站点正常工作。即使在高可用性领域,也有各种各样的技术,从热/热(Hot/Hot)、热/暖(Hot/Warm)、热/冷(Hot/Cold)到灾难恢复

  • 热/热是高可用性的最高级别。用户可以从任意的数据中心使用全部的应用程序。读和写可以发生在任何地方。折让自动的故障转移变得非常简单,但它不是万能的。你想必须思考如何处理数据一致性的问题。
  • 热/暖是一种很好的方式,如果你不能容忍数据的不一致性的话。很多应用有大量的读操作,仅偶尔写一下(但很重要)。在这种情况下,区别处理这两种操作是有意义的。
  • 热/冷让我害怕。这种架构将读写流量送到单一地点,而让另一个相同的部署在遥远的地平线上闲置。它容易建立,但价值很低。
  • 灾难恢复是最差的技术,本质上是雾件(vaporware)。它的本意不是在平常的时候保护你,而是在大的灾难发生时给你提供重建的选项。




影响持续时间对事件持续时间

当灾难来袭时,所有你需要考虑的是将用户流量以最快速度转移,离开问题区域。你需要立即降低影响。不要过于担心根源问题的修复,一旦将影响制止住,会有很多时间来解决这次事故。

怎样才能将流量从问题站点转出呢?通常方案是使用全局负载均衡(Global Server Load Balancing)GSLB。这实际是一个动态的授权DNS服务器,他能够根据相关因素对同一域名给出不同的IP地址。




数据中心数量

我们知道数据中心会失效,所以你至少需要两个。这就够了吗?三个或更多是不是会好一些?这取决于三个因素,成本、复杂性和性能




逐渐失效

当数据中心出现局部问题(partial problem)时,不要等它解决从而希望你不需要撤离,立即导出复制数据!




不信赖任何人

正如最可靠的数据中心也会时不时宕机,你可以预期即使最好的第三方供应商,偶尔也会有问题。就是你不能完全信赖一个服务提供商。




故障测试转移

通过早期和经常的测试,获取经验,以便当灾难袭来时,不会手忙脚乱,而是立即做出正确的事情。




监控和历史模式

你要知道日、周、月的流量模式。如果清楚正常流量中的不寻常处,你就不会在切换、迁移或升级时感到惊讶。确保监控包括周对周的图形和趋势。




高枕无忧

如果你能够事先有计划,能够解决大的问题,并且在日常工作中操练故障转移,则平台任何部分的失效将会变成容易处理的事件,而不是危机。






March 25, 2018 11:32 AM