当您使用DynamoDB

时间:2016-03-14 21:17:34

标签: c# session amazon-web-services amazon-dynamodb

我有一个C#.NET应用程序,其会话状态由DynamoDB支持。但是,我注意到我期望的吞吐量更高。但是我在实际表中注意到所有内容都作为SessionItems存储在一个长字符串中。

但是,让我们说我在会话中存储多件事

Http.Context.Session["Object1"] = obj1;
Http.Context.Session["Object2"] = obj2;

obj1obj2是两个不同类的实例。

现在当我去读或写其中一个时,例如::

var obj1 = Http.Context.Session["Object1"];

是否正在读取DynamoDB表中SessionItems中存储的所有内容?这个解释可以解释桌面上更高的吞吐量,但似乎非常不必要。

1 个答案:

答案 0 :(得分:1)

理想情况下,ASP.NET会在每个请求(例如页面/控制器)上对用户会话中存储的对象的序列化集合执行单次读取和单次写入。如果您在请求中访问该集合中的多个项目,它将使用本地副本,而不必访问基础数据存储区。

但是,我认为你注意到的是ASP.NET的pessimistic locking model。当它尝试执行单个读取以检索用户的会话数据时,如果该用户的会话数据已经设置了锁定,它将不断重试检索它(每500毫秒)。

ASP.NET HTTP生命周期的细节取决于框架版本等,但一般概念是这样的:

  1. 在数据存储区中包含会话数据的行上设置独占锁定(如果无法获得排他锁,请等到它可以)
  2. 从此会话的数据存储行读取/反序列化集合
  3. 执行您的页面/控制器
  4. 将集合序列化/写回数据存储
  5. 删除独占锁
  6. 如果有多个HTTP请求访问用户的会话(例如页面上的Ajax),您会注意到由于排他锁而没有并发 - 如果为每个请求启用Session,它们将以串行方式执行。 (即使他们没有明确访问Session)。

    避免这种情况的一种方法是有意识地写入Session的位置,并在所有其他页面/控制器上指定SessionStateBehavior.ReadOnly。执行此操作时,ASP.NET不会设置独占锁(将使用GetItem而不是GetItemEx)。请参阅ASP.NET Session State Overview

    页:

    <% @Page EnableSessionState="ReadOnly" %>
    

    控制器:

    [SessionState(SessionStateBehavior.ReadOnly)]
    

    参考:

    希望这有帮助!

    此致

    罗斯