如何防止两个应用程序发生冲突,因为它们使用一个数据库?

时间:2015-05-26 15:18:08

标签: .net sql-server performance nhibernate architecture

情况

有两个应用程序:

  • Windows服务
    • 处理队列消息
    • 执行大量数据库I / O(SELECT / UPDATE / INSERT)
  • ASP.NET应用程序
    • 主要使用数据库进行SELECT查询

两个应用程序都使用一个(镜像)MSSQL数据库(SQL Server 2014)。我们使用NHibernate ORM查询数据。应用程序和数据库服务器都拥有自己的专用服务器。

问题

数据库中有数百万条记录,因此查询仅在有足够索引可用时才有效。 Windows服务主要使用Clustered索引进行查询,但是有很多非聚集索引用于查询Web应用程序中的其他字段。 Windows服务应该尽可能快。

  • 这些非聚集索引使更新和插入查询变慢。
  • 使用Web应用程序会对服务性能产生很大影响。

到目前为止我们的解决方案

  • 向上扩展服务器
  • 存档数据
  • 改善指数

问题

除了我们目前的努力之外还有其他解决方案吗?我们不想添加额外的服务器,我们希望使用新的架构或软件来解决这个问题。在理想情况下,使用Web应用程序根本不会影响Windows服务的性能。

3 个答案:

答案 0 :(得分:2)

不是一个理想的世界。桌面上的任何活动都将影响其他活动。

如您所知,索引会降低插入,更新和删除速度。

索引维护将有助于(碎片整理)

小于100的填充因子将有所帮助(如50)

尝试按PK的顺序执行插入 如果不是尽可能多的索引的PK

尽可能设置基础更新,插入和删除 获得一次写锁和1000次插入的效率比一次更高效

Web应用程序的主要影响是锁定 你可以选择....带(nolock)吗?
使用(nolock)是脏读,所以只能谨慎使用。

答案 1 :(得分:2)

您没有说出您所使用的SQL Server版本,也没有描述您的硬盘方案(共享存储,本地存储等),但您确实说硬盘是瓶颈(不是内存,正确) ?),但没有说是由于写入还是写入+读取。但是,由于您只需要几分钟的时间,并且您不想引入报告服务器 - 如果您使用的是SQL 2012,则可以将AlwaysOn与Async Replica一起使用,只需确保辅助副本处于不同的状态一组磁盘而不是主数据库。通过分离辅助数据库,读取不会与写入冲突,同时仍然只比主数据库落后几秒。

答案 2 :(得分:1)

除了Blam的建议之外,您可能希望查看ASP.NET应用程序的缓存读取,可能使用ASP.NET的缓存类:https://msdn.microsoft.com/en-us/library/system.web.caching.cache%28v=vs.110%29.aspx - 请参阅https://msdn.microsoft.com/en-us/library/vstudio/ff477235%28v=vs.100%29.aspx以获取实现示例

如果您可以容忍脏读(可能是也可能不是这样 - 应用程序用户可以查看部分更新的数据吗?),您可以将其与SELECT ... WITH(NOLOCK)结合使用。

基本的想法是,您的数据库每5分钟左右才能被WebApplication攻击(但是对于更大的读取)而不是实时的。这里的问题将变成你每5分钟要缓存多少数据。如果您可以缓存用户在合理大小的缓存中使用的大部分数据,那就太好了。你可以在这里采取一些策略:

  • 仅缓存不经常更改的数据,并且不那么频繁地更新缓存
  • 仅缓存与最近更新的对象/实体相关的数据
  • 仅缓存网站经常请求的数据

所有这些都需要分析您的ASP应用程序何时以及如何访问数据库。

您可以将此与轮询模式结合使用以进行进一步的改进,即当服务更新数据库中的实体时,它还会在另一个表中创建一个记录,您的ASP.NET应用程序正在轮询该记录以使缓存保持为日期。轮询表将包含访问实体的主密钥(或密钥集),因此您的ASP缓存更新程序只能请求那些过期的实体。