缓存到Web服务器上的本地SQL实例

时间:2009-10-28 23:39:00

标签: sql-server architecture caching

我的流量非常高(每天10万次展示)/使用.net构建的高收益网站。核心元数据存储在SQL服务器上。我的团队和我有一个独特的缓存策略,包括定期从中间层服务器查询数据库中的新元数据,将数据序列化为文件并将这些数据发送到Web节点。 Web应用程序使用这些文件中的数据(一些实际上是序列化对象)来实例化对象并缓存内存中的数据以用于实时请求。

这种模式的优点在于:

  1. 允许Web节点将所有数据缓存在内存中,而不会产生查询数据库的任何IO开销。
  2. 如果数据库意外发生故障或维护窗口出现故障,Web服务器将继续运行并产生收入。您甚至可以启动Web服务器而无需从数据库中检索其初始数据,因为它需要的所有数据都在其自己的磁盘上的文件中。
  3. 允许我们完全水平扩展。如果吞吐量受损,我们可以添加一个Web服务器。
  4. 缺点是这个缓存和持久层会增加查询数据库的代码的复杂性,打包数据并将其解压缩到Web服务器上。只要我们的域模型要求我们添加实体,就必须对更多这种“管道”进行编码。这种架构已经存在了四年,可能有更好的方法来解决这个问题。

    我一直在考虑的一个策略是使用复制将我们的主sql server数据库复制到每个Web服务器上安装的本地数据库实例。 Web服务器应用程序将使用常规的sql / ORM技术来实例化对象。在这里,我们仍然可以维持主数据库中断,我们不必编写专门的缓存代码,而是可以使用nHibernate来处理持久性。

    这似乎是一个更优雅的解决方案,并希望看到其他人的想法,或者是否有其他人有任何其他建议。

5 个答案:

答案 0 :(得分:2)

我认为你是在思考这个问题。 SQL Server已经有了可用于处理这些事情的机制。

首先,实现SQL Server群集以保护主数据库。您可以在群集中从一个节点故障转移而不会丢失数据,停机时间只需几秒钟,最多。

其次,实施数据库镜像以防止群集故障。根据您使用同步还是异步镜像,您的镜像服务器将实时更新或落后几分钟。如果您实时执行此操作,则可以在应用程序内自动故障转移到镜像 - SQL Server 2005&以上支持在连接字符串中嵌入镜像服务器的名称,因此您甚至不必抬起手指。该应用程序只是连接到任何服务器的实时。

在这两件事之间,除了数据中心范围内的断电或网络中断之外,您几乎不受任何主要数据库故障的影响,并且没有复制内容的复杂性。这涵盖了您的高可用性问题,并允许您单独回答缩放问题。

我最喜欢的缩放起点是在应用程序中使用三个单独的连接字符串,并根据查询的需要选择正确的连接字符串:

  • 实时 - 直接指向一台主服务器。所有写入都转到此连接字符串,只有最关键的任务读取才会到达此处。
  • Near-Realtime - 指向通过复制或日志传送更新的只读SQL Server的负载平衡池中的点。在您的原始设计中,这些都存在于Web服务器上,但这是危险的做法和维护的噩梦。 SQL Server需要大量内存(更不用说许可资金了),并且您不希望为每个Web服务器添加数据库服务器。
  • 延迟报告 - 在您现在的环境中,它将指向相同的负载均衡用户群,但在未来的道路上,您可以使用日志传送等技术将服务器池推迟8-24小时。这些扩展得非常好,但数据远远落后。它非常适合报告,搜索,长期历史记录以及其他非实时需求。

如果您设计的应用程序从一开始就使用这3个连接字符串,那么缩放就容易多了,并且不涉及任何编码复杂性 - 只需选择正确的连接字符串。

答案 1 :(得分:1)

您是否考虑过 memcached ?既然是:

  1. in memory
  2. 可以在本地运行
  3. 水平完全可扩展
  4. 可以防止在每个Web服务器上重新缓存
  5. 它可能适合该法案。查看Google for lots of details和使用情况。

答案 2 :(得分:0)

您是否考虑过使用SqlDependency缓存?

如果您担心初始启动时间或数据库中断,您也可以将数据写入Web层的本地磁盘。但至少在SqlDependency中,您不必轮询数据库以查找更改。它也可以相对透明。

根据我的经验,在可扩展性或性能方面,在Web服务器上添加数据库实例通常效果不佳。

如果您担心性能和可伸缩性,可以考虑对数据层进行分区。具体取决于您的应用程序,但作为示例,您可以将只读数据移动到几个填充了复制的SQL Express服务器上。

如果有帮助,我会在书中详细讨论这个问题(Ultra-Fast ASP.NET)。

答案 3 :(得分:0)

RickNZ上面提出的一些补充...... 由于您当前正在缓存的主数据不会如此频繁地更改并且可能在某个维护窗口中更改,因此以下是您应该首先在数据库端执行的操作:

为要缓存的主表创建SNAPSHOT复制。添加新实体同样容易。 在所有Web服务器上,安装SQL Express并订阅此发布。 因为,这不是一个经常变化的数据,您可以放心,没有太多的服务器资源使用问题减去主数据的网络跳闸。

通过以前的机制提供的所有缓存仍然是可用的,减去了添加新实体时出现的所有问题。

接下来,您可以使用上面建议的.NET机制。除非您的Web服务器本身发生故障,否则您将不会遇到memcached群集故障。 .NET可以在这个阶段之后指出.NET中有很多可用的东西。

答案 4 :(得分:0)

在我看来,Windows Server AppFabric正是您所寻找的。 (AKA“Velocity”)。来自introductory documentation

  

Windows Server AppFabric提供了一个   分布式内存应用程序   用于开发的缓存平台   可扩展,可用,和   高性能应用程序。   AppFabric融合了多个内存   计算机给一个统一的   缓存视图到应用程序。   应用程序可以存储任何   可序列化的CLR对象没有   担心物体的位置   存储。可扩展性可以通过实现   只需添加更多计算机   需求。缓存也允许   跨越存储的数据副本   集群,从而保护数据免受攻击   故障。它作为一项服务运行   通过网络访问。在   另外,Windows Server AppFabric   提供与之的无缝集成   启用ASP.NET会话的ASP.NET   要存储的对象   分布式缓存而不必   写入数据库。这增加了   兼具性能和可扩展性   ASP.NET应用程序。