返回 登录
4

可扩展系统的9个性能问题

原文:9 crushing performance problems in scalable systems

作者:Andrew C. Oliver

翻译:Vincent

译者注:你的系统是不是很复杂,而且运行的很慢?其实我们并不缺乏解决这些问题的方法。作者在本文中介绍了9个比较常见的问题,只要你解决了这些问题,那么系统运行缓慢的问题应该在一定程度上得到缓解。以下为译文。



如果你有部署过一些可扩展系统的经验,你就会知道跟其它问题比起来,设计上的问题是最严重的。编写严谨的代码是一回事,而如何避免在系统设计过程中存在严重性的缺陷问题是另一回事。

这里有9个常见的问题——真的是很糟糕的设计选择——这些问题会导致你的系统运行的很慢。与许多糟糕的决策不同,这些问题可以被逆转。

【数据库很慢?使用这21条规则可以提高RDBMS的速度和可伸缩性,获得更快的SQL查询速度。我一直关注着InfoWorld的应用开发者报告简报中最热门的编程话题。】

1.N+1查询

如果你在一个查询中select出了一位客户的所有订单,然后循环通过每个订单中的每个订单的行项,这是n次访问数据库加1。这种情况使用一个外部连接的查询将更有效。如果你需要减少一次,那么你可以使用一种分页形式。使用缓存的开发人员常常会意外地编写n+1问题。你可以使用诸如Oracle Enterprise Monitor(OEM)或APM工具之类的数据库监视工具来发现这些情况,比如狡猾的内向或简单的查询日志记录。还有更糟糕的版本,比如那些试图在平板中存储树的人,而不是使用CTEs。在NoSQL数据库中也存在类似的问题,因此没有人是安全的。

2.页面或记录锁定

哥儿们,我曾经很讨厌DB2和SQL Server。我现在仍然讨厌他们的默认锁定模式。根据平台的不同,DB2会为更新锁定记录的“页面”。你最终会锁定那些与你所做的事情无关的记录。行锁更常见。一个长时间运行的事务对一行进行一个小的更新,这不会对其他任何事情产生影响。所有其他查询块。与此同时,这些事务持有更多的锁,从而造成了级联性能问题。如果你在这两个数据库中,请打开并设计快照隔离。Oracle默认使用一种快照隔离形式。有一些NoSQL数据库可以被配置为偏执程度的一致性。在你伤害自己之前,先了解它的锁定模式。

3.线程同步

这个问题有很多形式。有时它藏在图书馆里。多年以前,XML解析器使用名为Bean激活框架的Java库来验证MIME类型,该Java库使用了与每个方法同步的旧Java“Hashtable”集合。这意味着所有进行XML解析的线程最终都在同一个位置排队,造成了巨大的并发瓶颈。你可以通过阅读线程转储找到这个问题。许多现代开发人员已经习惯了为他们处理大多数线程的工具。这很好,直到有些事情不能正常工作。每个人都需要理解并发性。

4.数据库序列

如果你只需要一个惟一的ID,不要使用序列。只有在合理地需要每个ID时才使用一个序列。顺序。序列是如何实现的?线程锁。也就是说,所有的序列都是这样的。另一种方法是使用随机生成的UUID,使用安全随机算法。尽管理论上有可能得到一份复制品,但在产生了几万亿行之后,你仍然有更大的机会被陨石击中头部。我曾经让开发人员坐在我面前,光着头戴着没有陨石头盔的头盔,告诉我,即使是理论上的复制机会在他们的系统中都是可以接受的,但我猜他们对自己的生活并不重视。至少要用锡箔纸。

5.打开数据库连接

不管是数据库,HTTP,还是别的什么,都要把这些东西进行池化。在更大的系统上,不要尝试同时打开它们,因为你会发现你的数据库并不是这样设计的!

6.交换

你需要的内存总比你所希望的要多。如果你选择了牺牲其它方面从而交换得到内存,那是不好的。我曾经将我的Linux boxes设置为不允许交换,因为与默默地在后台杀死我的软件相比,我更想让它们出现崩溃。

7.I/O 同步

大多数高速缓存软件都有“write behind”的能力,也就是将数据写到至少两台机器上的内存中,而不用等待磁盘。这“软化”了读写波。最终,如果写吞吐量足够高,那么在write-behind缓存崩溃之前,你将不得不阻塞以赶上进度。在其他地方也存在类似的输入/输出同步,在日志文件之类的地方。一些软件仍然经常调用fsync,而这不是你想要的高端分布式可扩展软件——至少在很多帮助下是这样。

8.遗留的进程问题

一些软件包仍然是围绕进程和子进程设计的,每个进程都有一个单独的线程,特别是在Unix操作系统上。你可以把它们组合起来,对它们进行复用,但这不是一个好的设计。每个进程和子进程都有自己的内存空间。有时你可以分配另一个可怕的想法,叫做共享内存。现在的软件都具有管理多线程的进程。现在的多核cpu中,这一比例要大得多,因为每个核心都可以同时处理多个线程。

9.争用网络资源

假设一个分布式的文件系统和内存中计算的火花使你的所有服务器节点协同工作,而生命是盛大的,对吧?实际上,你仍然有网卡和开关以及其他限制带宽的东西。nic可以被绑定,并且交换器每秒的数据包数是固定的(这和一个1G的交换机不同,在所有的20个端口上都不能提供1G)。很好,你有很多节点都在发送数据,但是它们会在自己的网卡,你的实际网络带宽,或者你的交换机实际可用的吞吐量上瓶颈吗?

如果你正在编写代码和架构系统,那么希望你可以跳过这些陷阱。否则,请记住,一些老员工离开了这个行业然后开设酒吧这样的事情是经常会发生。

评论