缓存投票?

时间:2010-09-21 15:12:11

标签: asp.net linq-to-sql caching

我正在使用ASP.NET控件和Linq-to-Sql为高流量站点构建一个poll小部件。实际上,小部件已经构建完成。但是,它还没有使用缓存。

此轮询可以在多轮询模式下工作,这意味着每个页面加载控件将命中数据库以查找当前用户未采取的任何轮询。回发中还有几个数据库命中:检查以确保用户没有进行轮询,将结果写入数据库,以及最后一系列命中来计算结果。

更新,我已经重复了这些问题:

  1. 对于诸如民意调查之类的控件,是否适合在每个页面上点击数据库?如何将这种性能扩展到20,000个用户的规模。假设服务器有2台服务器,一台负载均衡器,现代多核CPU和2台ram。

  2. 您希望采用何种类型的缓存方案?考虑到例如任何数量的人都可以在任何时间间隔内进行民意调查,并且需要进行民意调查的总人数来计算结果。更有问题的是,在每次加载时,代码都必须访问数据库以查找用户未进行的轮询。

  3. 我有一些想法,但希望得到一些额外的专家反馈。感谢。

    更新

    所以,让我们回顾一下缓存的场景。人们可以缓存民意调查(问题),但仍然可能需要为PollsTaken(用户响应)访问数据库。一种可能性是创建一个阴影,写入内存存储和数据库存储。

    当用户提交成功的轮询(当它发生更改时)时,可以使用刷新方案来转储缓存。可以使用cookie来防止多次攻击,尽管它很容易受到游戏的影响。

    我想进入并查看所提供方案的更多细节。例如,如何使用输出缓存,缓存linq-to-sql等。不仅仅是一般性。

4 个答案:

答案 0 :(得分:2)

  

在放慢“典型”速度之前,SQL Server / ASP.NET可以处理多少次数据库命中   服务器

定义典型服务器。我是否可以假设具有64 gb ram的双四核服务器和足够的光盘来处理IO负载(例如,对于独立系统,24个磁盘的空间)?这是我典型的独立前端服务器/性能数据库系统。你会发现很多其他人都有其他“典型”服务器,这些服务器差异很大。

  

您希望采用哪种类型的缓存方式?

旧规则是:尽可能早地尽可能多地缓存。像IIS输出缓存击败其他一切。数据缓存击败了数据库等。

因此,尝试通过IIS输出缓存尽可能多地缓存。

更新

  

所以,让我们回顾一下缓存的场景。人们可以缓存民意调查(问题),但是   仍然需要为PollsTaken(用户响应)命中数据库。

不,你也可以缓存结果让我们说一分钟。你真的认为人们对最后的第二个实际结果感兴趣吗?每分钟(或15秒等)提供新结果完全没问题。

并且会显着减少服务器负载。

答案 1 :(得分:1)

在降低“典型”服务器速度之前,SQL Server / ASP.NET可以处理多少次数据库命中?

回答这个问题是不可能的,特别是因为你不提供任何信息,甚至不提供你使用的SQL Server版本。

什么是“典型服务器”?您正在谈论的数据库命中究竟是什么?数据库是如何设计的? SQL Server计算机和ASP.NET服务器计算机之间的网络速度是多少?实际上瓶颈是什么? SQL Profiler说的是什么? (还有几十个和其他几十个问题要问这个问题)

您希望采用哪种类型的缓存?

由于您希望减少对数据库的请求数量,请考虑以下事项:

  • 加载当前用户未执行的民意调查列表后,您不必重新加载此列表,直到用户占用一个池。
  • 如果你在回发时缓存要采用的池列表,则不必检查用户是否没有访问池:如果它在列表中,那就没关系。

最后,我不认为在保存结果时可以避免命中数据库。但是用于获取结果的命中可能无用:由于用户刚刚完成了调查,您的应用程序已经知道了结果。

答案 2 :(得分:0)

你的第一个问题是完全模糊的,如果不了解数据库的完整设计,肯定无法回答。

至于缓存,这取决于您的体系结构以及确保用户未进行轮询的重要性。无论何时实施缓存,都存在过时数据的风险,您必须权衡这些风险。

话虽如此,如果陈旧数据不那么重要,我会尝试确定你何时真的需要与数据库交谈,什么可以在空闲时间和什么是不变的。

  1. 常量信息,例如规则,民意调查问题等。可以/应该缓存。

  2. 应在执行时验证业务逻辑。你可以部分缓存这些,但是最好仔细检查befoer,让别人这样做。例如,您可以识别某人未采取的民意调查列表,但是当有人想要实际进行民意调查时,再次确认此特定民意调查尚未进行。

答案 3 :(得分:0)

我会缓存以下内容:

  • 所有民意调查ID的列表(密钥类似于“all_polls”)
  • 所有民意调查及其结果(关键字为“poll_< ID>”)
  • 投票用户的ID列表已完成(密钥为“users_polls_< USER_ID>”)

在页面加载时获取所有轮询ID的列表,使用此用户已完成的轮询的id列表对其进行过滤,然后通过ID请求缓存中的轮询。

在回发时,我会使轮询的密钥,用户的密钥以及提交到数据库的密钥到期。在下一个请求时,缓存中将缺少密钥,并且将使用更新的结果从数据库重新创建密钥。如果你愿意,你也可以直接在回发上更新缓存中的结果,但正常的解决方案就是使密钥到期。

问题主要在于您使用的是两个Web服务器,因此您不能只将这些项目缓存在内存中。在一个Web服务器上更新的轮询在其他Web服务器上不会过期,除非您在服务器之间采用某种形式的通信来同步其缓存。

我建议使用外部缓存,像这样的情况我自己使用memcached。如果在每个Web服务器主机上安装memcached服务器,并将应用程序配置为使用两个memcaches,那么您将始终拥有同步缓存。

对于C#,您可以使用Enyim Memcached客户端(http://memcached.enyim.com/)连接到服务器和Northscale Memcached Server(http://www.northscale.com/products/memcached。 html)用于服务器。

Enyim和Northscale工具都是免费的(开源),两者都非常稳定,非常适合生产。而且,不,我没有受雇于任何一家公司: - )