我们有一个由使用SQL Server2008的多个实例组成的web场托管的ASP.NET web应用程序,在该应用程序中,我们将来自多个源的数据聚合和预处理为优化的格式,以实现快速的最终用户查询性能(在某些表中产生500-1000万行)。聚合和优化是由后端服务器上的服务完成的,然后我们希望将其分发到web应用程序实例使用的多个只读前端副本,以促进最大的可扩展性。
我的问题是,将这些数据从后端数据库发送到只读前端副本的最佳方法是,在此过程中不会影响它们的性能。前端web应用程序实例将处于持续的高负载下,并且需要始终具有良好的响应性。
后端数据库不断更新,所以我怀疑事务性复制不是最好的方法,因为对副本的持续更新流将损害它们的性能。
数据过时并不是一个大问题,因此快照复制可能是可行的方法,但这将导致复制期间的性能较差。
执行drop和bulk insert将导致用户查询期间没有数据。
我真的不想写一种复杂的集群方法,我们在更新过程中将副本从集群中删除--有没有什么我们可以不花太多力气就能做到的事情,或者有没有更好的替代方案?
发布于 2009-09-04 21:53:12
实际上,SQL Server2005(和2008)中内置了一项技术,旨在解决此类问题。Service Broker (我将更进一步称为SSB)。问题是它有一个非常陡峭的学习曲线。
我知道MySpace公开了如何使用SSB来管理他们的SQL服务器:MySpace Uses SQL Server Service Broker to Protect Integrity of 1 Petabyte of Data。我知道还有几个(主要)网站使用了类似的模式,但不幸的是,它们还没有公开,所以我不能提到他们的名字。我个人参与了这项技术的一些项目(我以前是SQL Server团队的成员)。
现在请记住,SSB并不像复制那样是一种专用的数据传输技术。因此,您将找不到任何类似于发布向导和复制的简单部署选项的设置(检查一个表,然后将其传输)。单点登录是一种可靠的消息传递技术,因此它的原语停留在消息交换级别,您必须编写利用data change capture的代码,将其打包为消息,并在目的地将消息解包到关系表中。
为什么仍然有一些公司在您描述的任务中更喜欢SSB而不是复制,因为SSB在可靠性和可伸缩性方面有更好的故事。我知道有一些项目在1500+站点之间交换数据,远远超出了复制的能力。SSB也是从物理拓扑中抽象出来的:您可以在不更改应用程序的情况下移动数据库、重命名机器、重建服务器。因为数据流发生在logical routes上,所以应用程序可以动态地添加到新的拓扑中。SSB还能够适应长时间的断开连接和停机时间,能够在断开连接数小时、数天甚至数月后恢复数据流。通过引擎集成实现的高吞吐量(SSB是SQL引擎本身的一部分,不是卫星应用程序和进程的集合,如复制)意味着积压的更改可以在合理的时间内处理(我知道有些网站每分钟处理50万个事务)。单点登录应用程序通常依赖internal Activation来处理传入的数据。SSB也有一些独特的特性,比如内置的带有粘性会话语义的load balancing (通过路由)、对deadlock free application specific correlated processing的支持、priority data传送、对数据库镜像的特定支持、用于跨域操作的certificate based authentication、内置的persisted timers等等。
这不是一个具体的答案“如何将数据从服务器A上的表T移动到服务器B”。更多的是关于如何在服务器A和服务器B之间交换数据的通用技术。
发布于 2009-09-01 11:37:22
我以前从来没有遇到过这种情况,但我确实想出了一个可能的解决方案。基本上,这需要在主数据库结构中进行更改。您将保留此数据的修改记录,而不是存储数据。因此,如果添加了一条记录,则会存储"Table X,inserted new record with Thus:...“通过修改,只需存储表、字段和更改的值即可。对于删除,只需存储被删除的记录。每一次修改都会存储一个时间戳。
您的客户端系统将保留其数据库的本地副本,并在特定日期/时间之后定期请求所有数据库修改。然后在本地数据库上执行这些修改,它将再次保持最新。
那么后端呢?嗯,它只会保留一个修改列表,也许还会保留一个包含基本数据的表。只保留修改也意味着你在跟踪历史,允许你询问系统一年前的样子。
这将如何执行取决于后端数据库上的修改次数。但是,如果您每15分钟请求一次更改,那么每次都不应该有那么多数据。
但再说一次,我从来没有机会在实际应用中解决这个问题,所以对我来说,这仍然是一个理论原则。这看起来很快,但需要做很多工作。
发布于 2009-09-04 01:35:49
选项1:编写一个使用行级事务传输数据的应用程序。这可能需要更长的时间,但不会导致站点使用数据的中断,因为在读取发生之前和之后,行都在那里,只是包含新数据。此处理将在单独的服务器上进行,以最大限度地减少负载。
在sql server2008中,可以将READ_COMMITTED_SNAPSHOT设置为ON,以确保正在更新的行不会导致阻塞。
但基本上,这个应用程序所做的就是读取新数据,因为它是从一个数据库中读取到另一个数据库中的。
选项2:将数据(表或整个数据库)从聚合服务器移动到前端服务器。如果可能,请自动执行此操作。然后切换您的web应用程序以指向新的数据库或表,以供将来的请求使用。这是可行的,但需要对web应用程序进行控制,而您可能没有这种控制。
选项3:如果您谈论的是单个表(或者这可以用于多个表),那么您可以做的是视图交换。因此,您可以针对指向表A的sql视图编写代码。您需要处理表B,当它准备就绪时,您可以更新视图以指向表B。您甚至可以编写一个函数来确定活动的表,并自动执行整个交换操作。
选项4:您可以使用类似于服务器的字节级复制。不过,这听起来很可怕。这基本上就是将服务器从A点复制到B点,精确到每个字节。它主要用于DR场景,这听起来可能是某种DR场景,但并不是真的。
选项5:放弃并学习如何销售保险。:)
https://stackoverflow.com/questions/1012221
复制相似问题