如何设置新的SQL Server数据库以允许将来可能的复制?

时间:2010-02-08 20:35:00

标签: sql-server database-design replication

我正在构建一个系统,它有可能需要支持500多个并发用户,每个用户每分钟都会进行数十次查询(选择,插入和更新)。基于这些需求和具有数百万行的表,我怀疑将来需要使用数据库复制来减少一些查询负载。

过去没有使用复制,我想知道在架构设计中是否需要考虑什么?

例如,我曾被告知有必要使用GUID作为主键来启用复制。这是真的吗? 对于要复制的数据库,数据库设计有哪些特殊注意事项或最佳实践?

由于项目的时间限制,我不想在可能不需要时通过实施复制来浪费任何时间。 (我现在有足够的明确问题需要克服,而不必担心必须解决可能的问题。)但是,如果/将来需要复制,我不希望必须进行可能可避免的架构更改。

关于这个主题的任何其他建议,包括学习实施复制的好地方,也将不胜感激。

3 个答案:

答案 0 :(得分:3)

虽然每一行都必须有rowguid列,但

实际上,您甚至不需要拥有主键(尽管如果您未能创建主键,您将被扔石头死亡)。即使您将主键定义为guid,但未将其设为rowguid列也会导致Replication Services为您创建其他列。你绝对可以这样做,这不是一个坏主意,但它绝不是必要的,也不是特别有利。

以下是一些提示:

  1. 保持表格(或者说,)的尺寸较小;除非您使用列级复制,否则即使只有一列发生更改,您也将下载/上载行的全部内容。此外,较小的表使冲突解决更容易,也更不频繁。
  2. 不要使用顺序或确定性算法驱动的主键。 这包括标识列。是的,复制服务将自己处理标识列并分配密钥分配,但是您想要处理的是一个令人头疼的问题。仅这一点就是使用Guid作为主键的一个很好的理由。
  3. 不要让您的应用程序执行不必要的更新。这显然是一个糟糕的主意,但从带宽使用和冲突解决的角度来看,这个问题在复制方案中呈指数级变差。

答案 1 :(得分:1)

您可能希望将GUID用于主键 - 在复制的系统中,行在整个拓扑中必须是唯一的,而GUID PK是实现此目的的一种方法。

这是一个简短的article about use of GUIDs in SQL Server

答案 2 :(得分:1)

我会说你真正的问题不是如何处理复制,而是如何处理扩展,或至少扩展可查询性。虽然这个难题有各种答案,但有一个答案会突出:使用复制。

复制问题,特别是合并复制,是写入在复制中成倍增加。假设您有一个系统每秒处理100次查询(90次读取和10次写入)的加载。您想要扩展并选择复制。现在您有2个系统,每个系统处理50个查询,45个读取和5个写入每个。现在必须复制这些写入,因此实际写入次数不是5 + 5,而是5 + 5(原始写入),然后是另外5 + 5(副本写入),因此您有90次读取和20次写入。因此,虽然减少了每个系统的负载,但写入和读取的比率却增加了。这不仅改变了IO模式,而且最重要的是它改变了负载的可靠性模式。添加第三个系统,你将有90个读取和30个写入,依此类推。很快你会有更多的写入而不是读取,复制更新延迟与可靠性问题和合并冲突相结合将使项目脱轨。它的要点是'很快'比你预期的要快得多。很快就可以证明放大规模了,因为无论如何你最多只能谈论6-8个同行的规模,并且使用扩大规模的容量增加6-8倍会更快,更简单,甚至可能更便宜从...开始。

请记住,所有这些都只是纯粹的理论数字。实际上,复制基础架构不是免费的,它会在系统上增加自己的负载。需要跟踪写入,必须读取更改,分发器必须存在以存储更改,直到分发给订阅者,然后更改必须是写入并且为可能的冲突进行调解。这就是为什么我看到很少有部署可以通过基于复制的横向扩展策略取得成功。

另一种方法是仅扩展读取,此处复制执行工作,通常使用事务复制,但使用数据库快照进行日志传送或镜像也是如此。

真正的替代方案是分区(即分片)。请求在应用程序中路由到适当的分区,并在服务器上着陆适当的数据。需要在另一个分区上反映的一个部分的更改通过异步(通常基于消息传递)方式发送。数据只能在分区中连接。有关我正在谈论的内容的更详细讨论,请阅读how MySpace does it。毋庸置疑,这样的策略对应用程序设计有重大影响,不能简单地粘贴在v1之后。