AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

影响可扩展性的十宗罪

  • 2013-06-24
  • 本文字数:2641 字

    阅读完需:约 9 分钟

Sean Hull 是一名工作于纽约的技术咨询顾问,同时也是 Oracle & Open Source 一书的作者。最近,他在自己的博客上发布了一篇文章,指出5 种“罪过”会对可扩展性产生致命影响。他在2011 年发布过一篇文章,其中也提到5 种罪。加起来,正好是影响可扩展性的“十宗罪”。接下来我们一一列举,看看到底是哪十宗罪。

第一宗:磁盘I/O 慢,使用RAID5,使用多租户EBS

磁盘是所有服务器的基础,也是服务器性能性能的基础。虽然主内存变得越来越大,很多都可以作为缓存使用,但是服务器仍然需要不时从磁盘上读取数据,从内存清出数据。所以磁盘对于性能和可扩展性非常重要。

Raid 5 有什么问题?

Raid 5 是为了用更少磁盘提供更多的空间。常常用于磁盘插槽比较少的服务器,或者就是因为运维人员不知道它对性能的影响有大。在数据库服务器上用会特别不好。

所有的写操作都会影响性能。更大的问题在于:如果你失去了一块磁盘,虽然 RAID 原则上还在线,但是会巨慢无比,就跟掉线了一样。重建需要耗费 N 多小时。更糟糕的是:在重建过程中,可能会有另外一块磁盘也失效。要是你刚订购磁盘要好几天才能到,那该怎么办?

解决方案是采用 RAID 10。每两个磁盘做镜像,然后对它们做 Stripe 操作。即使只有四个硬盘插槽,这么做也值得。读写性能都很好,并且有保护。

多租户的问题是尼玛怎么回事?

在云上,可以共享服务器、网络和磁盘,就像共享某间公寓一样。Amazon 的 EBS(Elastic Block Storage,弹性块存储)是对这个比喻的扩展,为你提供存储网络令人欣喜的灵活性。但是你的瓶颈就是:与其他租户争抢同一个存储网络。

Amazon 提供的默认服务器存在这个问题,不过 AWS 解决了这个严重的问题,用一个不太为人熟知但是超级有用的特性——Provisioned IOPS。用它你可以锁定可靠的磁盘 I/O。

第二宗:用数据库处理队列

MySQL 在很多地方都做得很好,但是在处理应用程序排队方面却并不理想。你的数据库中是不是有类似 JOBS 这样的表,其中有一个状态列,包括“queued”、“working”、“completed”这样的值。如果是,你可能把数据库来处理应用中的队列工作了。这样使用 MySQL 不好,因为会出现锁的问题,还有查找下一个任务时的搜索和扫描任务也会遇到麻烦。

建议使用 RabbitMQ 或者 Amazon 的 SQS 方案,因为这些外部服务更容易扩展。

第三宗:用数据库进行全文搜索

Oracle 提供全文搜索支持,为什么 MySQL 却不能用呢?MySQL确实有这项功能,但是在很多版本中,只能配合老的 MyISAM 存储引擎使用。最好采用 Apache Solr 等经过验证的搜索解决方案,它专门用作搜索,有非常好的库,开发者可以使用多种现代 web 语言进行开发,并且非常容易扩展。只要在网络中增加服务器,或者做整体分布即可。

对于前沿技术感兴趣的同学,MySQL 5.6 中提供了 Innodb 的崩溃安全和事务存储引擎。既便如此,还是建议使用外部解决方案,如 Solr,或者 Sphinx 及 MySQL Sphinx SE 插件解决。

第四宗:每个层次的缓存不够

缓存,缓存,及更多的缓存。在 web 服务器和数据库之间可以使用 memcache 或者其他对象缓存机制。所有这些小结果集将会主流在内存中,等待未来需要它们的 web 页面。

也要考虑使用 varnish 这样的页面缓存,它位于 web 服务器之前,不妨将其看成一个迷你 web 服务器,处理很简单的页面,但是速度非常快。就像在堵塞的道路上开摩托车,让你的 web 服务器加速以完成更复杂的工作。

浏览器缓存也非常重要,但是你无法控制用户的浏览器,也许你可以?当然不是直接控制,但是你可以指导他们缓存哪些东西。还要使用合适的过期报头。让你的管理员配置 Apache 来支持这一点。

第五宗:太多技术欠债

技术欠债总有一天要还的。这是什么?探索新的点子,你会搭建一个原型。当这个原型已经部署给客户使用之后,要修改就变得更困难,因为某些问题可能有些东西还得掩盖起来。一个团队离开,另外的人接手这个应用,问题变得更复杂。随时间推移,你的技术债务不断积累,团队会花更多时间去维护老的代码以及修复 bug,开发新功能的时间会越来越少。在某个时候就有必要重写代码了。

第六宗:对象关系映射器

ORM 很受开发人员的欢迎,但是对于性能专家来说却不是这样。为什么会这样?原因主要是由于这两类人看待 web 应用视角不同。一种是功能开发,以满足业务需求作为考察的结果。性能和可扩展性在这种情况下往往位于较低优先级。ORM 能让开发者更有效率,通过后端的数据存储将 SQL 的交互难度抽象出来,让开发者将注意力集中在功能的开发上。

从性能角度出发,看到的是另外的场景。如果用 ORM 实现 SQL 查询,数据库将无法优化复杂的查询。而且 ORM 不允许对查询的简单调整,拖慢调优过程。

第七宗:同步、串行、耦合或锁定进程

在 web 应用里,锁相当于现实世界中的交通信号灯。如果将交通灯换成环形交通枢纽可以显著提升流量。因为如果你去一个交通流量很小的地方,没有人会在交通灯下做无用的等待。更重要的是:如果有车流量很大,环形枢纽可以让车辆保持流动。如果需要锁,最好使用 InnoDB 数据表,因为它们能提供粒度更细的行级锁定,而不是 MyISAM 的表级锁定。

要避免出现等待其它节点消息而无法执行程序的半同步复制。在高事务并发的 web 应用中,成千上万的并发会话会导致这种等待的增加。

避免任何类型的两阶段提交机制。多阶段提交提供了一个串行入口,让多个节点投票决定数据应该是什么样子,但是它们是扩展性的毒药。最好使用采取最终一致性算法的技术。

第八宗:只有一份数据库拷贝

如果没有复制机制,那么你的数据库就只有一份。所有的 web 服务器只能使用唯一的后端数据存储,它就会成为漏斗或瓶颈。

第九宗:没有定量衡量标准

没有衡量标准是可扩展性的一剂毒药,因为你无法以可视化方式看见系统中发生了什么。没有可视化的线索,业务部门、开发者和执行团队很难对扩展性方面的问题达成一致。如果团队认识不到这一点,要让大家理解:这些简单的工具可以提供基础设施的分析。

第十宗:缺乏功能标志

应用程序如果缺乏功能标志,会很难实现优雅升级。如果你的网站流量猛增,而你不能施展魔法来扩展和提升流量,有内建的功能标志,运维团队就可以在不让网站宕机的前提下,降低服务器负载。你也得以有更多时间来扩展 web 服务器或是数据库,甚至是改进你的应用,允许同时读写多个数据库。

不提供这些开关,扩展性和可用性就受到了很大限制。

以上就是 Sean Hull 提出的:影响可扩展性的“十宗罪”。各位 InfoQ 的读者,以上这“十宗罪”,你在处理扩展性的过程中遇到过吗?你觉得还有哪些“罪”?又是怎么解决这些罪过的?欢迎在留言中说明。

2013-06-24 09:364724
用户头像

发布了 479 篇内容, 共 167.3 次阅读, 收获喜欢 52 次。

关注

评论

发布
暂无评论
发现更多内容

Spring扩展之 深入分析 Aware 接口

chenssy

死磕 Java 死磕 Spring

Spring 扩展之深入分析 InitializingBean 和 init-method

chenssy

死磕 Java 死磕 Spring

Spring 扩展之深入分析 Bean 的类型转换体系

chenssy

死磕 Java 死磕 Spring

Redis为何这么快?

JavaEdge

12月日更

SQS 和 SNS 对比分析

liuzhen007

28天写作 12月日更

面试官synchronized连环问,学会Monitor之后轻松拿下

李子捌

Java、 28天写作 12月日更

Spring 扩展之深入分析 BeanPostProcessor

chenssy

死磕 Java 死磕 Spring

架构实战营 第4期 模块一作业

架构实战营 模块一 「架构实战营」

10 款你不知道的 Linux 环境下的替代工具!

JackTian

GitHub Linux 程序员 运维 命令行终端

Spring 扩展之深入分析 PropertyOverrideConfigurer

chenssy

死磕 Java 死磕 Spring

Spring 扩展之自定义类型转换器

chenssy

死磕 Java 死磕 Spring

38 K8S之CNI插件与选型

穿过生命散发芬芳

k8s 28天写作 12月日更

架构训练营作业一

supermenG

架构师训练营 4 期

毕业设计

毛先生

毕业总结

毛先生

什么?还在用delete删除数据《死磕MySQL系列 九》

咔咔

MySQL delete

MySQL统计总数就用count(*),别花里胡哨的《死磕MySQL系列 十》

咔咔

MySQL conut

Spring 扩展之深入分析 PropertyPlaceholderConfigurer

chenssy

死磕 Java 死磕 Spring

Spring 扩展之之 PropertyPlaceholderConfigurer 的应用

chenssy

死磕 Java 死磕 Spring

在K8s里部署Eureka集群

xiaoboey

Kubernetes Spring Cloud Eureka Gateway 服务发现

MySQL探秘(八):InnoDB的事务

程序员历小冰

MySQL 事务 28天写作 12月日更

说说个人影响力

张老蔫

28天写作

字符串可以这样加索引,你知吗?《死磕MySQL系列 七》

咔咔

MySQL 字符串 加索引

打开order by的大门,一探究竟《死磕MySQL系列 十二》

咔咔

order by MySQL高级

字典树之旅01.开篇

极客志

自然语言处理 数据结构 算法 nlp 字典树

字典树之旅02.Trie 的标准实现

极客志

自然语言处理 数据结构 算法 Trie 字典树

TypeScript 之 Class(上)

冴羽

JavaScript typescript 翻译 大前端

为什么MySQL字符串不加引号索引失效?《死磕MySQL系列 十一》

咔咔

MySQL 索引失效

技术人创业过程中应保持开放的心态

wood

创业 技术 28天写作

无法复现的“慢”SQL《死磕MySQL系列 八》

咔咔

MySQL 慢SQL

Spring 扩展之深入分析 BeanFactoryPostProcessor

chenssy

死磕 Java 死磕 Spring

影响可扩展性的十宗罪_数据库_郑柯_InfoQ精选文章