一般而言,哪种设计决策有助于应用程序很好地扩展?
(注意:刚刚学习了Big O Notation,我想在这里收集更多的编程原理.我试图通过回答下面的问题来解释Big O Notation,但我希望社区能够改进这个问题和答案.)
到目前为止的响应
1)定义缩放.您是否需要扩展虚拟环境中的大量用户,流量和对象?
2)看看你的算法.他们的工作量是否会与实际工作量成线性关系 - 即循环的项目数量,用户数量等等?
3)看看你的硬件.您的应用程序是否设计为可以在多台计算机上运行,如果无法跟上?
次要想法
1)不要过早优化太多 - 先测试一下.也许瓶颈会发生在不可预见的地方.
2)也许扩展的需要不会超过摩尔定律,也许升级硬件会比重构更便宜.
我唯一要说的是编写你的应用程序,以便它可以从一开始就部署在集群上.以上任何事情都是过早的优化.您的第一份工作应该是让足够多的用户遇到扩展问题.
尽可能简单地构建代码,然后对系统进行概要分析,并仅在存在明显性能问题时进行优化.
通常,分析代码的数据是违反直觉的.瓶颈往往存在于你认为不会很慢的模块中.在优化方面,数据是最重要的.如果您优化了您认为会很慢的部件,您通常会优化错误的部件.
好的,所以你在使用"大O符号"时遇到了一个关键点.如果你没有注意的话,这个维度肯定会让你陷入困境.还有一些其他方面正在发挥作用,有些人看不到"大O"眼镜(但如果你仔细观察他们真的是).
该维度的一个简单示例是数据库连接.构建一个"最佳实践",例如,一个左内连接,它将有助于使sql更有效地执行.如果您分解关系演算或甚至查看解释计划(Oracle),您可以轻松查看哪些索引正在以哪种顺序使用,以及是否正在进行任何表扫描或嵌套操作.
分析的概念也很关键.您必须在架构的所有移动部分中以完全正确的粒度对仪器进行检测,以便识别和修复任何低效问题.比如说你正在构建一个3层,多线程,MVC2基于Web的应用程序,自由使用AJAX和客户端处理以及应用程序和数据库之间的OR Mapper.简单的线性单一请求/响应流程如下所示:
browser -> web server -> app server -> DB -> app server -> XSLT -> web server -> browser JS engine execution & rendering
您应该有一些方法来测量每个不同区域的性能(响应时间,以"每单位时间的东西"测量的吞吐量等),不仅在盒子和操作系统级别(CPU,内存,磁盘I/O,等),但具体到每一层的服务.因此,在Web服务器上,您需要知道您正在使用的Web服务器的所有计数器.在应用程序层中,您需要加上对正在使用的虚拟机的可见性(jvm,clr等).大多数OR映射器都在虚拟机内部显示,因此如果在该层可见,那么请确保关注所有细节.在DB内部,您需要了解所有内容正在执行的程序以及适合您的DB风格的所有特定调整参数.如果你有大笔钱,BMC Patrol对于大多数人来说都是一个不错的选择(使用适当的知识模块(KM)).在便宜的一端,你当然可以自己动手,但你的里程将根据你的专业知识深度而有所不同.
假设一切都是同步的(没有你需要等待的基于队列的事情),性能和/或可扩展性问题有很多机会.但由于您的帖子是关于可伸缩性的,所以让我们忽略浏览器,除了将从Web服务器调用另一个请求/响应的任何远程XHR调用.
因此,鉴于此问题域,您可以做出哪些决定来帮助实现可伸缩性?
连接处理.这也绑定到会话管理和身份验证.必须尽可能保持干净和轻便,同时不影响安全性.度量标准是每单位时间的最大连接数.
每层的会话故障转移.是否有必要?我们假设每个层在一些负载平衡机制下将是一个水平集群.负载平衡通常非常轻量级,但会话故障转移的某些实现可能比期望的更重.此外,您是否使用粘性会话运行可能会影响您在架构中更深入的选项.您还必须决定是否将Web服务器绑定到特定的应用服务器.在.NET远程处理世界中,将它们连接在一起可能更容易.如果您使用Microsoft堆栈,那么执行2层(跳过远程处理)可能更具可扩展性,但您必须进行实质性的安全性权衡.在java方面,我总是看到它至少3层.没理由不这样做.
对象层次结构 在应用程序内部,您需要尽可能最轻,最轻的重量对象结构.只在需要时提供所需的数据.恶意删除任何不必要或多余的数据.
或者映射器效率低下.对象设计和关系设计之间存在阻抗不匹配.RDBMS中的多对多构造与对象层次结构(person.address与location.resident)直接冲突.您的数据结构越复杂,OR映射器的效率就越低.在某些时候,你可能不得不在一次性情况下削减诱饵并做更多...呃...原始数据访问方法(存储过程+数据访问层),以便从特定的方面挤出更多性能或可扩展性丑陋的模块.了解所涉及的成本并使其成为有意识的决定.
XSL转换.XML是一种很好的,规范化的数据传输机制,但是人类可以成为一个巨大的性能狗!根据您携带的数据量以及您选择的解析器以及结构的复杂程度,您可以轻松地使用XSLT将自己描绘成一个非常黑暗的角落.是的,在学术上它是一种非常干净的表达层方式,但在现实世界中,如果您不特别注意这一点,可能会出现灾难性的性能问题.我已经看到一个系统在XSLT中消耗了超过30%的事务时间.如果你试图增加4倍的用户群而不购买额外的盒子,那就不太好了.
你能从可扩展性堵塞中找到自己的方式吗?绝对.我看过它发生的次数比我想承认的要多.摩尔定律(正如您已经提到的)今天仍然有效.有一些额外的现金,以防万一.
缓存是减少发动机压力的一个很好的工具(提高速度和吞吐量是一个方便的副作用).虽然在内存占用方面以及在缓存过时使缓存失效的复杂性方面需要付出代价.我的决定是开始彻底清理并缓慢添加缓存,只有在你认为它对你有用的地方.很多时候,复杂性被低估了,最初作为解决性能问题的方法最终会导致功能问题.另外,回到数据使用评论.如果您每分钟创建一个价值千兆字节的对象,那么无论您是否缓存都没关系.你很快就会占用你的内存,垃圾收集会破坏你的一天.所以我想要的是要确保你明白了什么'
很抱歉.刚刚滚动,忘了抬头.希望其中一些涉及到你的探究精神,并不是一个基本的谈话.