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

AWS DynamoDB session table keeps growing, can't delete expired sessions

ASP.NET_SessionState table 一直在增长,已经达到 18GB,没有删除过期会话的迹象。

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

我们的系统 运行 很好,创建了会话,但最终用户并没有意识到这个问题。然而,table 一直在增长是没有意义的...... 我们已经三次检查 permissions/security,一切似乎都井然有序。我们使用 SDK 版本 3.1.0。还有什么需要检查的?

由于您的 table 超过 18 GB,这是相当大的(在这种情况下),所以在查看 DeleteExpiredSessions 的代码后它不起作用并不让我感到惊讶GitHub.

上的方法

代码如下:

    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(table 扫描)以识别所有过期记录。然后将这些添加到作为第二步执行的 DocumentBatchWrite 请求中。

由于您的 table 太大,因此 table 扫描步骤将需要非常非常长的时间才能完成,然后才能删除单个记录。基本上,上述算法对小 tables 的惰性垃圾收集很有用,但不能很好地扩展到大 tables.

我能说的最好的是,执行此操作实际上从未超过 table 扫描,您可能正在消耗 table.[=18= 的所有读取吞吐量]


一个可能的解决方案是 运行 自己对上述方法稍作修改。您可能希望在 do-while 循环中调用 DocumentBatchWrite,以便在 table 扫描结束之前开始删除记录。

看起来像:

    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);
    }

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