使用分区或单独的数据库进行表扩展?

时间:2013-02-18 14:28:07

标签: sql-server database-design azure database-performance database-partitioning

假设我有一张桌子(让我们称之为BigTable),每天可以体验 5,000,000个INSERTS (可能只有SELECT一样多)。插入的每行约为50kb。

这些每日INSERT分为5个客户端(该表有一个名为ClientID的FK)。无需跨多个客户端选择或加入数据。

随着这个表的增长,我担心数据库的性能,所以我提出了两个解决方案。

解决方案1:

  • BigTable
  • 分区ClientID
  • 将每个分区存储在服务器上的单独硬盘上(使用Azure博客存储)。
  • 将所有1个月前的数据(存档数据,但仍需查询)分区到另一组READONLY分区中。

本质上,这意味着他们自己的存储设备上有以下分区:

  • 主要(除BigTable以外的所有数据)
  • ClientA的BigTable(每天5,000,000行/ 5个客户x 30天= 30,000,000行)
  • ClientB的BigTable(30,000,000行)
  • ClientC的BigTable(30,000,000行)
  • ClientD的BigTable(30,000,000行)
  • ClientE的BigTable(30,000,000行)
  • ClientA的BigTable存档
  • ClientB的BigTable存档
  • ClientC的BigTable存档
  • ClientD的BigTable存档
  • ClientE的BigTable存档

存档表中的行数将为(5,000,000)x(以天为单位的DB年龄) - (30,000,000)。这仍然是一个巨大的表,但只会用于绘制奇怪的报告。

SQL Server将托管在14GB,8core Azure VM上。

解决方案2:

另一种选择是为每个客户端托管单独的数据库。这意味着每个人都拥有自己专用的SQL Server机器。归档数据仍将进行分区。

由于数据的物理分离,此选项不是最佳选项。必须管理多个数据库的更新可能非常有问题。为每个客户端建立单独的数据库连接也是开发人员的考虑因素。

有人可能会建议这些选项吗?

3 个答案:

答案 0 :(得分:5)

由于您已使用[azure]和[sql-server]标记了此内容,因此我假设您尝试在Windows Azure中执行此操作。如果是这种情况那么a)客户端分区不一定是个好主意,并且b)SQL可能不是最适合你的问题的。(/ p>

在构建可扩展的体系结构时,分区策略不应该基于像“客户端”这样的特定内容,而应该更加随意。原因很简单 - 除非客户端有理由分开,例如不希望他们的数据与其他人混合,或者每个客户端都有不同的SLA,那么选择“客户端”作为分区可能无法呈现最佳结果。如果80%的业务是由单个客户生成的,那么您还没有解决问题,仍然需要维护 n 单独的数据库以进行边际负载。

每天5百万数据库插入数据并不是一个很大的数字,但由于底层商品硬件的性能,可能是Azure IaaS或Azure SQL数据库中托管的SQL Server的一大数目。在确定如何对SQL进行分区之前,先问自己两个问题。首先,您希望从数据中获得哪些用途和性能特征? (它必须立即一致吗?您能异步处理数据吗?)其次,您是否已将这些特性与其他数据存储技术相对应?您是否考虑过表存储(或Redis等非MS解决方案)?

您可以在尝试以下几个选项后找到:

  • 在某些时候,SQL是一些很好的存储数据。
  • 大部分处理可以异步完成,因此插件的峰值性能几乎没有问题(在24小时内进行5密耳插件不是问题)。
  • SQL可能不适合长期存储。
  • 使用map-reduce而不是SQL查询可以有效地查询旧数据。

例如,我有一个应用程序以一秒钟的间隔跟踪车辆。它的目标是100,000辆车,但其架构的方式可以扩展到数百万,而无需更改任何代码或数据库。但从中期来看,它必须每天处理72密耳的插入物。所有这些都运行在一个小于10GB的Windows Azure SQL数据库和一大堆表存储上。这样做的原因是因为虽然我想归档所有数据(72 mil行),但我不需要对它进行复杂的SQL查询访问,因此它可以很好地存放在表存储中。我在SQL中存储的是数据摘要。所以在我的例子中,我只对车辆的行程(起点和终点位置,行驶距离等)感兴趣,这意味着我每天只需要每行一两行或三行,这需要大大减少数据库。此外,我的瓶颈在于数据收集,因此我将数据立即添加到(Windows Azure)队列中 - 并担心在单独的工作负载中汇总数据。

这个答案可能有点长,但是您可以更仔细地考虑您的数据模型,而不是仅仅考虑如何使用SQL来解决问题。有关更多详细信息,请查看CALM中的数据模型。

答案 1 :(得分:3)

为您提供一些想法: 1)使用Azure表而不是SQL。让PartitionKey = ClientID。每张桌子可以是200TB和200TB。支持20k IOPS。每个分区都是2k IOPS,因为客户端在逻辑上是分开的,您将获得自然负载平衡(Azure分区负载平衡)。这也可以让您免于必须运行/管理XL VM 24x7(即便宜得多)。存储成本将是相同的,因为无论如何,VM的数据驱动器都由Azure存储支持。每天5M插入只有~60 /秒,因此会有很大的增长空间。这是特别正确的b / c你做相当简单的插入/选择,不会跨越客户端边界。

2)如果你想为每个客户端数据库做一次,我会选择SQL Azure。配置速度要快得多,每个数据库都是一个单独的扩展单元(这可以防止一个客户端为其他客户端创建问题)。您还可以根据客户端更改动态更改数据库。

3)如果你想要一个单片数据库,我会在虚拟机上使用SQL Server。创建多个数据驱动器并将其作为条带集安装。对于XL VM,最多可以映射16个驱动器。这会将DB的最大大小限制为16TB,因此您需要使用某种机制来进行老化/存档/垃圾收集。

答案 2 :(得分:1)

您不仅需要考虑访问性能,还需要考虑灾难恢复性能。仅在活跃月份的每个客户端为6TB,我强烈建议将客户端保留在单独的数据库中。

如果你有一个像样的Continuos集成和自动部署过程,保持数据库架构同步不应该是一个大问题。