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 上,其记录在扫描时被删除。
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 上,其记录在扫描时被删除。