数据库中的功能是否阻碍了可扩展性?


17

我可能无法为该问题提供正确的标题。但这是

我们正在开发财富管理的金融门户。我们期望超过10000个客户端使用该应用程序。门户根据股票市场的技术分析计算各种绩效分析。

我们通过存储过程,用户定义的函数,触发器等通过数据库开发了许多功能。我们认为,与通过C#代码相比,直接在数据库中执行操作可以大大提高性能。实际上,我们确实获得了巨大的性能提升。

当我试图向我们的CTO吹牛时,他反驳了我决定在数据库中而不是代码中实现功能的决定。据他介绍,此类应用程序存在可伸缩性问题。用他的话说:“如今,这些东西都保存在内存/缓存中。随着时间的推移,很难管理集群数据。Facebook,Google在数据库中什么也没有。这是瘦服务器和胖客户端的时代。DB仅用于存储纯数据并且功能应该与数据库完全分离。”

你们能给我一些关于他说的是否正确的建议。如何进行架构师这样的应用程序?


3
与什么相比,“实际上我们确实获得了巨大的性能提升”?当您从未在客户端上实现相同功能时,您怎么知道?
Doc Brown

3
我认为这将是平常的事-它取决于项目,数据实施和团队的技能。
Daniel Iankov 2012年

1
您应该问您的CTO,是什么让他认为数据库没有使用他偏爱的技术,以及为什么存储过程不符合“代码”的条件。
Blrfl 2012年

3
Facebook和Google面临的问题与大多数应用程序完全不同,在市场数据方面,您必须处理的数据量可能存在问题,但现代SQL数据库是为应对数量惊人的数据而构建的。
Murph 2012年

1
除非您可以证明他的解决方案的性能不足,并且没有其他管理方法,否则我可能会以与CTO相同的方式思考。存储过程,尤其是当它们的数量很大时,如果需要,将导致向其他DB转移的巨大障碍...无法预测未来。
钻机2012年

Answers:


23

简而言之,我同意您的CTO。您可能已经牺牲了可伸缩性而获得了一些性能(如果这些术语令人困惑,我将在下面进行说明)。我最担心的两个问题是可维护性和缺少水平扩展的选项(假设您将需要此功能)。

接近数据: 让我们退后一步。将代码推送到数据库中有一些很好的理由。我认为最大的是接近数据-例如,如果您期望计算返回少量值,但是这些是数百万条记录的汇总,则按需发送数百万条记录(按需)要在其他地方聚合的网络非常浪费,并且很容易杀死您的系统。话虽如此,您实际上可以通过其他方式实现数据的接近性,本质上是使用缓存或分析DB(其中一些聚合是预先完成的)来实现的。

数据库中代码的性能:诸如“执行计划缓存”之类的次要绩效影响则更难辩驳。有时,如果缓存了错误的执行计划,则缓存的执行计划可能是非常不利的事情。根据您的RDBMS,您可能会从中获得最大的收益,但是在大多数情况下,参数化的SQL并不会带来太多好处(通常也会缓存这些计划)。我还要指出,对于基本操作和非关系编程(字符串操作,循环等),大多数已编译或JIT编辑的语言通常比SQL等效语言(例如T-SQL或PL / SQL)性能更好,因此您不会如果您使用Java或C#之类的方法进行数字运算,那么这里不会丢失任何东西。细粒度的优化也非常困难-在数据库上,通常,您只能使用通用B树(索引)作为唯一的数据结构。公平地讲,完整的分析(包括诸如具有更长运行时间的事务,锁升级等)可能会填满书本。

可维护性: SQL是一种设计出色的语言。我不确定这是否适合应用程序逻辑。使我们的生活可以承受的大多数工具和实践(TDD,重构等)都难以应用于数据库编程。

性能与可伸缩性:为了澄清这些术语,我的意思是:性能是指假设低负载的情况下,您期望单个请求通过系统(并返回给用户)的速度。这通常受到诸如经过的物理层数,这些层的优化程度等因素的限制。可伸缩性是性能随着用户/负载数量的增加而变化的方式。您可能具有中等/低性能(例如,一个请求需要5秒以上的时间),但是性能却很棒(可以支持数百万个用户)。在您的情况下,您可能会体验到良好的性能,但是可伸缩性将受到您可以物理构建的服务器规模的限制。在某个时候,您将达到该极限,并被迫转向分片之类的东西,根据应用程序的性质,这可能不可行。

过早的优化: 最终,我认为您犯了过早优化的错误。正如其他人指出的那样,您实际上并没有度量来显示其他方法的工作方式。好吧,我们不能总是建立完整的原型来证明或反驳理论。但是总的来说,我总是不愿意选择一种以可维护性(可能是应用程序最重要的质量)为代价的方法。 。

编辑:从积极的角度看,垂直缩放在某些情况下可能会延伸得很远。据我所知,SO在单个服务器上运行了相当长的时间。我不确定它如何与您的10,000个用户匹配(我想这取决于他们在系统中执行的操作的性质),但是它使您对可以执行的操作有所了解(实际上,更令人印象深刻的例子,这恰好是一个人们可以轻易理解的流行)。

编辑2:澄清和评论其他地方提出的一些事情:

  • 回复:原子一致性-ACID一致性很可能是系统的要求。上面的内容并没有真正反对这一点,您应该意识到ACID一致性并不需要您在数据库中运行所有业务逻辑。通过将不需要存储在数据库中的代码移动到数据库中,您将不得不在其他数据库的物理环境中运行-它正在与数据库的实际数据管理部分争夺相同的硬件资源。至于仅将代码扩展到其他数据库服务器(而不是实际数据)-当然可以,但是在大多数情况下,除了额外的许可成本之外,您在这里还能得到什么?将不需要的东西放在数据库之外。
  • 回复:SQL / C#性能-因为这似乎是一个有趣的话题,所以让我们在讨论中多加一些。您当然可以在数据库中运行本机/ Java / C#代码,但据我所知,这不是这里讨论的内容-我们正在比较以T-SQL之类的典型应用程序代码与C#之类的典型应用程序代码的实现。过去,使用关系代码很难解决许多问题-例如,考虑“最大并发登录数”问题,其中有记录表明登录或注销以及时间,并且您需要确定一次最多可以登录的用户数是。最简单的解决方案是遍历记录,并在遇到登录/注销时保持计数器递增/递减,并跟踪该值的最大值。可以,我不知道),您能做的最好的事情就是CURSOR(纯关系解决方案的复杂度都不同,尝试使用while循环解决它会导致性能降低)。在这种情况下,是的,C#解决方案实际上比您在T-SQL期间所能达到的速度更快。这似乎有些牵强,但是如果您要处理代表相对变化的行,并且需要计算这些变化的窗口汇总,则此问题很容易在金融系统中显现出来。存储的proc调用也往往会更昂贵-调用一个普通的SP一百万次,并查看与调用C#函数相比如何。我在上面提到了其他一些示例-我还没有遇到任何人在T-SQL中实现适当的哈希表(实际上可以带来一些好处),尽管在C#中很容易做到。同样,DB擅长做某些事情,而DB却不那么擅长。就像我不想在C#中进行JOIN,SUM和GROUP BY一样,我也不想在T-SQL中编写任何特别占用CPU的内容。

我倾向于将功能推送到数据库的原因之一是,它比应用程序级代码要少得多。SQL是声明性的,不会遇到命令式语言所遇到的许多问题。
wobbily_col

关于可维护性,使用SQL Server数据工具可维护性是一个小问题。实际上,对于任何非平凡的数据库(一个具有超过5个表的数据库),我都认为这是一个要求。
Jon49 '17

4

可伸缩性与数据所在位置或计算方式无关。可伸缩性是关于如何管理全局状态和数据相互依赖性的。如果您的体系结构因各种数据相互依存而混乱不堪,那么将代码放在何处转换该数据都无所谓。相互依存关系将迫使您动手,并减少任何扩大规模的可能性。另一方面,如果您的数据是松散耦合的,并且几乎没有或没有全局状态,那么再次计算在何处都没有关系。扩展事物将变得更加容易。

我不确定您的CTO从何处获得有关可伸缩性问题的信息,但是从您所说的来看,这听起来似乎除了软件流行趋势外,他没有任何真正的理由质疑当前的架构决策。根据这样的趋势做出建筑决策通常是一个坏主意。


1
+1 forScalability is all about how you manage global state and data inter-dependence.
Estefany Velez

2

实际上,我们确实获得了巨大的性能提升。

我认为您需要设置性能基准并首先开始构建原型。将所有逻辑保留在DB中是处理客户机-服务器体系结构的老派(恕我直言,我对此没有任何反对)。尽管它有其优点,但仍有许多缺点需要考虑。

这种可销售应用程序的常用方法是通过SOA完成的。因为从长远来看,这是向项目中添加新客户端应用程序的最简单方法。

您还提到了触发器。在应用程序的支持生命周期的后期,触发器的使用可能会变得很困难,我会倍加小心,甚至尝试跳过它的使用。


2

您的CTO是100%错误的。

您的财务数字必须始终加起来。这意味着您需要ACID,而关系数据库是确保这一点的最佳选择。NoSql DB的性能提升通常以ACID费用为代价,这对于Google和Facebook而言是可以的,但对于包含财务状况的系统而言则不是。

说C#的性能比SQL代码更好,这也是愚蠢的……


说C#的性能比SQL代码更好是愚蠢的…… -但是您并不否认C#的代码具有更高的可扩展性,对吗?
Jim G.

没有,它的可伸缩性更高,因为这不是瓶颈所在,所以我可以像水平缩放C#代码一样轻松地水平缩放Sql代码(而不是数据)。
Morons 2012年

@吉姆 只是为了澄清一下,“如果可以这样做,那么我可以像水平缩放C#代码一样轻松地水平缩放Sql代码(而不是数据)” ...与C#相同,必须将其设计为可缩放。您不能只是说C#的扩展性更好,而是计划而不是语言的问题。
Morons 2012年

@JimG .:不能缩放的软件可以用任何语言编写,包括C#。任何有价值的数据库都可以使用非本机SQL-ish实现的语言编写存储过程,而那些在需要ACID的情况下使用NoSQL的人通常会重新发明大多数本来很好的方法由DBMS实施。
Blrfl 2012年

@Morons:我认为我们同意。我实际上在将数据与“ SQL”混淆。扩展数据库要昂贵得多。
Jim G.

2

每当有人提到可扩展性和Google / Facebook / Twitter / etc等时,这都是一个红色的鲱鱼。除非您提供的是基本相同的服务,否则适用于他们的服务可能不适合您。通常,如果您可以从一台计算机扩展到八台计算机集群,那么您可能已经涵盖了所有基础。除非您对每天要提供2000万次页面浏览量有严格的业务要求,否则不必担心超大规模。做对您的应用程序实际需求有意义的事情,并担心在您明显需要扩展时进行扩展。而且请不要忘记,大多数数据库服务器也可以集群,因此仅因为它全部位于一个数据库中并不意味着它位于一台服务器上。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.