SQL Server数据库分片-如何处理公用数据/非分片数据


10

我们有一个非常大型的企业级数据库。作为我们业务模型的一部分,所有Web用户每个月都在同一时间访问我们的Web服务器,这反过来又会破坏我们的sql框。业务量非常大,并且随着公司规模的增长,流量还会继续增加。已执行sql proc优化,并且硬件已经扩展到很高的水平。

我们正在寻求对数据库进行分片,以确保我们能够处理公司的增长和未来的负载。

我们已决定应分拆哪些特定数据。它是我们数据库的一个子集,利用率很高。

但是,我的问题是关于通用/通用的非分片数据。这样的数据示例可能是一个库存表(例如),也可能是雇员表,用户表等。

我看到两个选项来处理此通用/通用数据:

1)设计1-将通用/通用数据放置在外部数据库中。所有写入将在此处发生。然后,该数据将被复制到每个分片中,从而允许每个分片在t-sql proc中读取此数据并内部联接至此数据。

2)设计2-为每个分片提供所有常见/通用数据的自己的副本。让每个分片在本地写入这些表,并利用sql合并复制来更新/同步所有其他分片上的数据。

对设计#1的担忧

1)事务性问题:例如,如果您必须先在一个分片中写入或更新数据,然后再在1个存储的proc中写入/更新一个通用/通用表,那么您将无法再轻松地做到这一点。现在,数据存在于单独的sql实例和数据库上。您可能需要让MS DTS来查看是否可以将这些写操作包装到事务中,因为它们位于单独的数据库中。在这里,性能是一个问题,可能会对写入分片和公共数据的proc进行重写。

2)失去参照完整性。不可能做到跨数据库引用完整性。

3)重新编码系统的大部分区域,以便它知道将公共数据写入新的通用数据库,但从分片中读取公共数据。

4)。增加数据库旅行。像上面的#1一样,当您遇到必须更新分片数据和公用数据的情况时,由于数据现在位于单独的数据库中,因此您将进行多次往返以完成此操作。这里有些网络延迟,但是我不像上面的3一样担心这个问题。

对设计2的担忧

在设计2中,每个分片都拥有自己的所有通用/通用数据实例。这意味着加入或更新公共数据的所有代码将像今天一样继续工作/运行。开发团队几乎不需要进行任何编码/重写。但是,此设计完全依赖合并复制来使所有分片之间的数据保持同步。dbas非常熟练,并且非常担心合并复制可能无法处理此问题,并且合并复制失败,因此从该失败中恢复并不好,并且可能会对我们造成负面影响。

我很想知道是否有人采用了第二种设计方案。我也很好奇我是否忽略了我没有看到的第三或第四设计方案。

先感谢您。


10
在这种情况下,什么是“超大型企业数据库”和“已经扩展到很高水平的硬件”?在10分之10中,分片不是解决方案,所以想知道您要解决的问题是什么。
Mark Storey-Smith

5
认真地说,您是说Web服务器“锤击”了SQL框。读:写的比率是多少?有很多方法可以在不分片的情况下扩展读取,并根据性能,成本或复杂性进行权衡,具体取决于数据的实际需求。当然,还有一些方法可以使写入排队,这再次取决于静态数据需要达到多少纳秒。
亚伦·伯特兰

3
这句话引起了我的注意:“硬件已经扩展到很高的水平了。” 扩大硬件规模的原因是什么?
swasheck

2
您有64个逻辑处理器,而CPU是瓶颈?究竟是什么驱动CPU,重新编译?你知道吗?
亚伦·伯特兰

1
分片完成后检查一下裤子。
swasheck

Answers:


5

您的问题集中在以下方面:

但是,我的问题是关于通用/通用的非分片数据。这样的数据示例可能是一个库存表(例如),也可能是雇员表,用户表等。

在进行分片并且拥有所有分片都需要查看的数据时,您必须使用一些属性对该数据进行分类:

它会经常变化吗?在示例中,您列出了库存,员工和用户。通常,库存变化非常快,但是员工仅记录定期变化(例如每天数百次更新)。

每个分片可以容忍多少延迟?即使库存可能不断变化,您通常也可以在这样的桌子上忍受大量的延迟(几分钟甚至几小时)。如果您要出售数量非常有限的独特商品,而且您永远都无法补货(想想原始艺术品),那么您根本就不会分拆这些数据-您只查询原始数据库。但是,在大多数在线商店中,您并不是每天都卖完所有商品,而且无论如何都要快速补充库存,因此您实际上并不需要最新的库存计数。实际上,在大多数情况下,您只需要一个0或1的“库存中”标志,然后由中央进程更新该标志。这样,您不必将每个计数的上/下颠簸推到每个分片上。另一方面,员工或用户数据,

您将要从分片表加入非分片表吗?理想情况下,这里的答案是否定的-您应该进行两个单独的查询以获取数据,然后在应用程序端将它们加入。从应用程序的角度来看,这变得非常困难,但是它使您能够从每个来源获取最新数据。

是原始数据还是复制的?考虑这个问题的另一种方法:您需要备份什么?备份频率如何?通常,在大容量分片环境中,您希望备份尽可能快且尽可能小。(毕竟,您需要保护每个节点,并且您希望所有分片都在同一时间故障转移到灾难恢复-某些分片的数据要比其他分片的要新。)这意味着分片的数据和非分片的数据分片的数据应该位于完全独立的数据库中-即使它们位于同一服务器上。我可能需要对分片(原始)数据进行持续的事务日志备份,但可能根本不需要备份未分片的数据。对于我来说,仅从单一事实来源刷新雇员或用户表,而不是在每个分片上进行备份,可能会更容易。但是,如果我所有的数据都在一个数据库中,

现在,关于您的担忧:

“交易问题...您将不再能够轻松地做到这一点。” 正确。在分片方案中,将事务处理的概念抛到窗外。情况也变得更糟-对于分片数据,由于群集实例故障转移或重新启动,您可能需要一个分片上线并联机,而另一个分片下线。您需要随时计划系统任何部分的故障。

“不可能实现跨数据库引用完整性。” 正确。当您将一个表拆分为多个服务器时,您会穿上大衣,告诉数据库服务器您将接管艰巨的任务,例如时间点备份,表之间的关系以及合并来自多个来源。现在就在您和您的代码上。

“对系统的大部分区域进行重新编码,以便它知道将公共数据写入新的通用数据库,但从分片中读取公共数据。” 也请在此处更正。没有简单的按钮,但是一旦将其内置到应用程序中,就可以疯狂扩展。我认为,执行此操作的更简单方法是通过读取拆分应用程序的连接

“数据库旅行增加了。” -是的,如果您将数据分为多个服务器,则该应用将不得不更多地与网络连接。关键是也要实现缓存,以便可以将某些数据存储在低成本,高吞吐量,无锁的系统中。最快的查询是您从未做出过的查询。

在这里,我还提出了更多利于划分多租户数据库的利弊,例如对单个分片的性能调整,每个分片的不同备份/恢复策略以及架构部署挑战。


0

在较高级别上,分片(或水平分区)数据的典型方法是分片事务表并复制主级别表。像大多数技术解决方案一样,这当然可以解决一组问题并带来一系列全新的问题……但是我们现在已经习惯了,不是吗?;-)

我想问一下SQLServer是否是您最好的解决方案。工作量更像OLTP还是更像DW / BI?

干杯,戴夫·西克斯


-2

可能的第三个选项。使用关系分片(而不是黑盒分片),您应该能够分片并分发整个数据库。由于它是基于传统的关系数据模型构建的,因此数据库知道哪些数据存储在哪些服务器上以及在哪里可以找到它们,因此所有数据都可以被视为“通用/通用”数据。签出dbShards可以简化整个分片过程。


3
如果不解释关系分片,黑匣子分片,它们的作用,为什么一个比另一个更好,以及最好承认您的雇主是dbShards,那么这个答案就毫无意义。
Jeremiah Peschka 2013年
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.