AWS DynamoDB会话表不断增长,无法删除过期的会话

时间:2015-10-11 07:51:29

标签: asp.net-mvc session-state aws-sdk

ASP.NET_SessionState表一直在增长,已经是18GB,而不是删除过期会话的迹象。

我们尝试执行DynamoDBSessionStateStore.DeleteExpiredSessions,但似乎没有效果。

我们的系统运行正常,会话已创建,最终用户不知道该问题。然而,桌子一直在增长是没有意义的...... 我们有三重检查权限/安全性,一切似乎都是有序的。我们使用SDK 3.1.0版。还有什么需要检查的?

1 个答案:

答案 0 :(得分:0)

如果您的表超过18 GB,这是非常大的(在此上下文中),在查看GitHub上DeleteExpiredSessions方法的代码后,这并不令我感到惊讶。

以下是代码:

    public static void DeleteExpiredSessions(IAmazonDynamoDB dbClient, string tableName)
    {
        LogInfo("DeleteExpiredSessions");
        Table table = Table.LoadTable(dbClient, tableName, DynamoDBEntryConversion.V1);


        ScanFilter filter = new ScanFilter();
        filter.AddCondition(ATTRIBUTE_EXPIRES, ScanOperator.LessThan, DateTime.Now);

        ScanOperationConfig config = new ScanOperationConfig();
        config.AttributesToGet = new List<string> { ATTRIBUTE_SESSION_ID };
        config.Select = SelectValues.SpecificAttributes;
        config.Filter = filter;

        DocumentBatchWrite batchWrite = table.CreateBatchWrite();
        Search search = table.Scan(config);

        do
        {
            List<Document> page = search.GetNextSet();
            foreach (var document in page)
            {
                batchWrite.AddItemToDelete(document);
            }
        } while (!search.IsDone);

        batchWrite.Execute();
    }

上述算法分两部分执行。首先,它使用过滤器执行Search(表扫描),用于识别所有过期记录。然后将这些添加到作为第二步执行的DocumentBatchWrite请求中。

由于您的表太大,因此在删除单个记录之前,表扫描步骤将花费很长时间才能完成。基本上,上述算法对于小型表上的惰性垃圾收集很有用,但对于大型表不能很好地扩展。

我能说的最好的是,执行此操作实际上从未超过表扫描,并且您可能正在消耗表的所有读取吞吐量。

您可能的解决方案是自行运行上述方法的略微修改版本。您可能希望调用do-while循环内的DocumentBatchWrite,以便在表扫描结束之前开始删除记录。

这看起来像是:

    public static void DeleteExpiredSessions(IAmazonDynamoDB dbClient, string tableName)
    {
        LogInfo("DeleteExpiredSessions");
        Table table = Table.LoadTable(dbClient, tableName, DynamoDBEntryConversion.V1);


        ScanFilter filter = new ScanFilter();
        filter.AddCondition(ATTRIBUTE_EXPIRES, ScanOperator.LessThan, DateTime.Now);

        ScanOperationConfig config = new ScanOperationConfig();
        config.AttributesToGet = new List<string> { ATTRIBUTE_SESSION_ID };
        config.Select = SelectValues.SpecificAttributes;
        config.Filter = filter;

        Search search = table.Scan(config);

        do
        {
            // Perform a batch delete for each page returned
            DocumentBatchWrite batchWrite = table.CreateBatchWrite();
            List<Document> page = search.GetNextSet();
            foreach (var document in page)
            {
                batchWrite.AddItemToDelete(document);
            }
            batchWrite.Execute();
        } while (!search.IsDone);
    }

注意:我没有测试过上面的代码,但它只是对开源代码的一个简单修改,因此它应该可以正常工作,但是需要进行测试以确保分页在表格上正确工作正在扫描的记录正在删除。