当前我们正在使用Sessions在我们的页面中存储数据表,以便我们不必使数据库命中一次又一次地获得相同的数据表。但是我的担心是它使用服务器内存,并且如果有一天有大量用户登录,服务器的响应速度会变慢,我们的应用程序也可能会崩溃。使用会话来存储数据表
请告诉我,将数据表存储到会话中还是应该每次从数据库中获取数据表是一个好主意?
当前我们正在使用Sessions在我们的页面中存储数据表,以便我们不必使数据库命中一次又一次地获得相同的数据表。但是我的担心是它使用服务器内存,并且如果有一天有大量用户登录,服务器的响应速度会变慢,我们的应用程序也可能会崩溃。使用会话来存储数据表
请告诉我,将数据表存储到会话中还是应该每次从数据库中获取数据表是一个好主意?
作为一般的经验法则,我会说不要使用会话。我很久没有使用会话了。一旦进入网络农场,会话要么慢得多,要么更复杂,或者两者兼而有之。
您是否会摆脱这个问题真的取决于您在会话中存储的数据量以及在会话超时期限内有多少用户将处于活动状态。
今天有很多缓存和内存数据库选项可能是更好的选择。最后,虽然所描述的解决方案听起来有问题,但在实际测量问题之前,我不会优化现有的解决方案。
最好将“常用”数据存储在存储器中;这是很好的逻辑。然而,“会话”意味着它存在于该会话的生命中,因此也就是该用户。其次,正如你所说,等待用户“会话”生活,这可能会消耗服务器端的宝贵资源。
您可能需要考虑的是“缓存”对象,因为它与“过期”具有相同的用途。
DataTable users = new DataTable();
if (Cache["users"] == null)
{
// users = getUsers(customer);
Cache.Add(“users”, users, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(0, 60, 0), System.Web.Caching.CacheItemPriority.Default, null);
}
else
{
sers = (DataTable)Cache["users"];
}
有许多方法来重新使用.NET存储 (1)的ViewState (2)高速缓存 (3)会议 (4)饼干
但我会去的“缓存“对象。
我的担心是缓存仍然会使用服务器的内存,并且在Web Farm的情况下,这个选项是否会脱颖而出? –
是的,但显然它取决于你在缓存中存储了多少数据。我们将它用于诸如客户名称,用户名等简单的事情,或者您可能会考虑类似MemCached(.NET版本和Linux版本 - 无论您更喜欢什么)。如果你的数据很大,其他选择是使用Redis,CouchBase或类似的。 –
如果你不能增加Web服务器上的内存,那么显而易见的答案就是不要将它存储在会话状态中,并且每次都从数据库获取它。
问题在于它会对数据库造成什么影响?你只是将问题从Web服务器移动到数据库服务器?
它是向外扩展的Web服务器更容易比它是扩大/缩小数据库(如果你正在使用类似SQL服务器往往比较便宜)
这取决于什么被存储在数据表。无论如何,我会使用ASP.NET Cache来存储这些数据表,原因如下。
缓存具有期满,这意味着可以在它的滑动或绝对期满定时值
缓存基于将自动被删除,如果该进程的内存“压力”是过高自动删除。
您可以具体到一个用户,或者全局性基于其关键
例如所有用户的缓存项:
// personalized cache item
string personalCacheKey = string.Format("MyDataTable_{0}", (int)Session["UserID"]);
DataTable myPersonalDataTable = (DataTable)Cache[personalCacheKey];
if (myPersonalDataTable == null)
{
myPersonalDataTable = database.dosomething();
Cache.Insert(personalCacheKey, myPersonalDataTable, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0)); // 30 minutes
}
// global (non user specific) cached item
string globalCacheKey = "MyDataTable";
DataTable globalDataTable = (DataTable)Cache[globalCacheKey];
if (globalDataTable == null)
{
globalDataTable = database.dosomething();
Cache.Insert(globalCacheKey, globalDataTable, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0)); // 30 minutes (again)
}
然而
,你现在有这个问题, ,是否基础数据得到更新,以及您的应用程序是否可以接受“旧”缓存数据。如果这是不可接受的,你将不得不强制从缓存中删除一个项目,有几个机制。
您可以设置一个SqlCacheDependency(我从来没有亲自使用过),或者您可以使用Cache.Remove(cachekey)
自己清除缓存对象。
这就是美丽的例子。但是我担心缓存仍然会使用服务器的内存,而在Web Farm的情况下,这个选项会成功吗? –
+1。缓存用于缓存,Session用于每用户数据(在使用内存中会话状态的情况下,应该准备好由于服务器重新启动/重新启动而使这些数据消失,...)。是的,缓存对于在WebFarm场景中缓存共享数据也可以很好地工作。 –
对于网络服务器场,有分布式缓存系统可以处理特定于他们的问题。 – Matthew
如果您的数据表的记录数量较少且不包含敏感数据,那么您也可以使用ViewState,但数据应该更小,因为此方法将序列化数据并将其存储在客户端,然后从数据库中获取数据客户端存储在服务器端。
这是一个很好的观点。在网络农场,我们肯定会遇到问题。但我们不打算迁入农场。这对我们来说是个好消息。 :)。会议有其他流行的选择吗? –
+1,特别是“测量,理解而不是优化”。 –
最简单也是最明显的选择是在这里用其他答案建议使用asp.net缓存。请记住,如果您无法接受缓存数据中的某些不一致,则在Web场中,asp.net缓存也可能会很笨拙。更重型的解决方案包括memcached之类的东西,或者redis以及其他类似技术。我怀疑你不需要一个沉重的解决方案,因为你的问题可能会很明显,你不需要问是否可能是一个问题。 – ScottS