首页 > 代码库 > Oracle Coherence 3.5 读书笔记之3 - 满足性能,可扩展和可用性目标
Oracle Coherence 3.5 读书笔记之3 - 满足性能,可扩展和可用性目标
满足性能目标
影响操作执行时间的重要因素有算法和数据结构。在分布式系统中,还有一个重要的因素就是网络延时。
处理延时
开发人员在开发时通常没有考虑延时,测试时亦是如此。
作者给了一个示例,对于一个20ms的操作(典型的web操作完成时间),在本地执行只有0.067ms延时,而跨国执行时,需要264ms。
而通常一个web请求需要多次往返web服务器,延时就更加严重。因此应减少往返次数,即使对于内存的访问也需如此。
通常听到的建议”make your remote services coarse grained” 或 “batch multiple operations together” 也会同样的意思。
减少带宽使用
依据摩尔定律,带宽通常不是问题。
网络延时与光速有关,不大容易改善。而带宽却在不断增加,但不代表带宽问题可以忽略。
无论如何,应尽量减少网络上的I/O,只获取必要的信息,如果数据量过大,就将处理下放到数据,而非相反。
Coherence 与性能
Coherence 可以解决延迟和带宽问题,通过以下几个手段:
- 通过将后端数据库的数据缓存降低延迟
- 以及通过near-cache缓存最近使用的数据降低延迟
- 在数据节点可并行执行,降低延迟并减少带宽使用
满足可扩展性目标
可扩展性可通过两种手段实现,scaling up 或 scaling out
scale up:
通过添加CPU/磁盘/内存等将小服务器变为大服务器
问题在于平衡,有时添加完CPU却发现内存成了新的瓶颈,比较昂贵。
scale out:
添加更多的集群,并分享工作负载。更廉价。
不过设计和管理上更复杂,例如需要从架构上消除单点故障,需要保证服务的无状态化(stateless)
无状态服务并不存在
应用层无状态化时为了更好的扩展。但应用仍然需要状态这点是不变的。
通常,状态会下移到最难扩展的数据库层。
扩展数据库非常困难
数据库必须满足ACID (atomicity, consistency, isolation, durability) 。
磁盘系统非常重要:为了提高并发,磁盘需要合理分布;为了保证durability,数据库最终受限于磁盘性能。
当数据量增加,用户访问增加时,数据库总会到达极限,这时就需要扩展。通常采用scale up方法,但此法昂贵且不可持续。
这时,可以转而考虑scale out的方法。
数据库横向扩展方法
参见前文:关系型数据库横向扩展的三种方法
重新回到状态
从应用端去掉状态极大加重了数据库的负担,为了减轻数据库负担,我们还需要使状态回到应用层。
当然并非加到stateless的服务中,而是在无状态的应用逻辑和数据库间引入一个新的层次。
正如Bellovin 教授所说:
any software problem can be solved by adding another layer of indirection
这里的indirection可以理解成abstraction
此新抽象层需要具备以下的能力:
* 管理对象数据,因为应用可以直接操纵对象
* 对象存于内存,以提高性能和减低I/O
* 可以透明的将后端数据库数据加载到内存
* 可以将数据修改持久化到后端,通常是异步的
* 易于横向扩展,如同无状态的应用层
Coherence满足以上所有要求
使用 Coheren减少数据库负担
通常的数据库查询都是基于主键的,将这些查询转移到应用层缓存可以大大减轻后端数据库的负担。
Coherence的分布式架构还可以做更多复杂的工作。
有了coherence,主从复制就不必要了。只读的从库被分布式缓存替代,同时,主库和从库的数据不一致问题也没有了。
后端的数据库仍需要集群,但coherence降低了后端数据库的压力,集群可以简单,节点可以变少。
而分片方面,coherence内置了distributed queries 和 aggregations特性。使多节点的查询变得简单,应用也无需做太多修改,而且通过复制对数据进行保护。
Coherence与可扩展性
coherence是理想的可扩展数据管理方案。
通过添加节点就可以添加容量和吞吐量(处理能力)。
当然,应用还是需要好好的设计架构的,把一个好产品用烂的情况太多了。
好的产品 + 差的设计 = 差的产品
满足高可用性目标
为了达到高可用目标,我们需要在架构中去掉所有单点故障。
整体可用性=所有部件可用性的乘积
AS = A1 * A2 * … * An
这同时也意味着,一个部件不可用,整个系统就不可用。
因此我们需要做两件事:
1. 为每一个部件提供冗余
2. 使部件松耦合,而是故障隔离
第二点通常通过引入异步实现,例如引入消息队列,文件缓存等。而Coherence也可以缓存更新,即使后端数据库失败也没有影响。异步还可以提高吞吐量。
为系统添加冗余
F = F1 * F2 * … * Fn
F是部件失效的可能性
而 Fc = 1 - Ac(可用性)
例如一个系统有3个部件,每个部件的可用性为0.99;
As = 0.99 * 0.99 * 0.99 = 97%
每一个部件失效可能性为1-0.99 = 0.01
如果为每一个部件增加一个冗余部件。
则每一部件失效可能性为0.01 × 0.01 = 0.0001
新的As = (1-0.0001) * (1-0.0001) * (1-0.0001) = 99.97%
可用性提高了。
仅有冗余是不够的
仅有冗余是不够的,还需要系统有足够的容量来满足峰值请求,避免系统崩溃。
如果系统需要N个服务器处理峰值请求,假设X个服务器失效后系统仍可以工作,那么系统需要N+X台服务器。否则,如果峰值时服务器失效,剩余服务器将不能处理请求,从而导致响应时间下降,性能降低,甚至无法服务。
Coherence 和 可用性
Coherence在设计上就是高可用的,任何节点失效都不会有影响。这时通过在集群中加入复制来实现的。
每一个对象都在另一个节点有冗余,当然对于对象的更新也会增加开销,不过开销相较于集群数据库还是会小很多。不过Coherence集群的Sizing仍很重要。
另外,Coherence集群的高可用并不意味着整个系统的高可用。其它如负载均衡,路由器,交换机等都需要冗余。
综合考虑
为性能和可用性设计
为达到性能和可用性目标,必须定位系统中的单点故障和瓶颈并消除它们,这需要仔细的设计架构,并在架构的最初就考虑可扩展性。
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.
很多人断章取义,只看到后面这句:premature optimization is the root of all evil,从而逃避复杂的架构设计。而延迟和可扩展性绝不是小事,必须在系统设计之初就妥善考虑。
Scalability is a prerequisite to functionality, a priority-0 requirement, if ever there was one.
Randy Shoup - eBay架构师
在每一层设定性能目标
用户响应时间不超过2秒,这样的目标是不够的,我们需要继续分解,如网络上耗时多少,后台处理多少时间,访问数据库多少时间等等。如此我们才能准确的定位瓶颈,做相应的优化。
测量和监测
Count what is countable, measure what is measurable, and what is not measurable, make measurable.
–伽利略
应用是否满足目标,需要测量。如测量服务执行的时间,测量单个服务器所能承受的负载,以及扩展后所能承受的负载,如此才能合理的规划系统,以及预期扩展所需投入的成本。
在开发阶段可以使用的测量工具包括:
* 服务器端代码 - YourKit (www.yourkit.com),
* 客户端网页测量工具 - FireBug (getfirebug.com), YSlow (developer.yahoo.com/yslow) 或 Page Speed (code.google.com/p/page-speed)
* 压力测试工具 - HP LoadRunner, or an open source tool such as Apache JMeter (jakarta.apache.org/jmeter), The Grinder (grinder.sourceforge.net), 或 Pylot (www.pylot.org).
运行阶段的监控工具:
* JMX, 或 ERMA (erma.wikidot.com),
* coherence监控 - JConsole
* 商用工具 - Evident ClearStone Live (www.evidentsoftware.com) 或 SL RTView (www.sl.com).
教育你的团队
让团队达成一致的性能和可用性目标,并了解达成目标需要克服的问题。
推荐的书有:
1. Scalable Internet Architectures - Theo Schlossnagle
2. Building Scalable Websites - Cal Henderson
3. High Performance Websites: Essential Knowledge for Front-End Engineers
4. Even Faster Web Sites: Performance Best Practices for Web Developers - Steve Souders
总结
本章讨论了如何实现性能,可用性和可扩展性目标,以及coherence如何帮助我们实现目标。
为了提高性能,需要减少延时和移动的数据量。Coherence 的 near caching和 entry processors可以帮我们达到这个目标。
通过把coherence引入架构,coherence可以实现最难扩展的一层 - 数据管理层的横向扩展,从而避免复杂的数据库扩展,如cluster和sharding。
为实现高可用性,你必须消除任何单点故障,虽然Coherence设计上就是高可用的,但你还需保证其它部件也是同样高可用。通常可以引入冗余,通过复制。
最后,需要强调,性能,可扩展性和可用性应该从系统最初设计时考虑,并且在运行时需要测量和监控,而不能靠后期的补救。
Oracle Coherence 3.5 读书笔记之3 - 满足性能,可扩展和可用性目标