将 DynamoDB 会话处理程序与 AWS SDK for PHP 版本 3 结合使用 - AWS SDK for PHP

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

将 DynamoDB 会话处理程序与 AWS SDK for PHP 版本 3 结合使用

DynamoDB 会话处理程序是一个适用于 PHP 的自定义会话处理程序,让开发人员能够将 Amazon DynamoDB 用作会话存储。使用 DynamoDB 进行会话存储可将会话移离本地文件系统并将其移入共享位置,从而可减少在分布式 Web 应用程序中进行会话处理时出现的问题。DynamoDB 速度快、可扩展且易于部署,还能够自动处理数据复制。

DynamoDB 会话处理程序使用 session_set_save_handler() 函数将 DynamoDB 操作挂接到 PHP 的本机会话函数中,以允许简易替代。其中包括对会话锁定和垃圾回收等功能的支持,这些功能是 PHP 的默认会话处理程序的一部分。

有关 DynamoDB 服务的更多信息,请参阅 Amazon DynamoDB 主页

基本用法

步骤 1:注册处理程序

首先,实例化并注册会话处理程序。

use Aws\DynamoDb\SessionHandler; $dynamoDb = new Aws\DynamoDb\DynamoDbClient([ 'region'=>'us-east-1' // Since version 3.277.10 of the SDK, ]); // the 'version' parameter defaults to 'latest'. $sessionHandler = SessionHandler::fromClient($dynamoDb, [ 'table_name' => 'sessions' ]); $sessionHandler->register();

第 2 步。创建用于存储会话的表

在实际使用会话处理程序之前,您需要创建一个用于存储会话的表。通过使用适用于 Amazon DynamoDB 的 AWS 控制台或使用 AWS SDK for PHP,您可以提前完成此操作。

在创建此表时,请使用“id”作为主键的名称。此外,建议使用“expires”属性设置“生存时间”属性以便从会话自动垃圾回收功能中受益。

步骤 3 像平常一样使用 PHP 会话

一旦注册会话处理程序并且已存在表,您便可以像通常使用 PHP 的默认会话处理程序那样使用 $_SESSION 超级全局变量向会话读写内容。DynamoDB 会话处理程序会封装并提取与 DynamoDB 的交互,让您可以轻松地使用 PHP 的本机会话函数和接口。

// Start the session session_start(); // Alter the session data $_SESSION['user.name'] = 'jeremy'; $_SESSION['user.role'] = 'admin'; // Close the session (optional, but recommended) session_write_close();

配置

您可以使用以下选项配置会话处理程序的行为。所有选项都是可选的,但务必要了解默认值为何值。

table_name

存储会话的 DynamoDB 表的名称。默认值为 'sessions'

hash_key

DynamoDB 会话表中哈希键的名称。默认值为 'id'

data_attribute

DynamoDB 会话表中的属性名称,该会话表中存储了会话数据。默认值为 'data'

data_attribute_type

DynamoDB 会话表中属性的类型,该会话表中存储了会话数据。此项默认为 'string',不过可以选择设置为 'binary'

session_lifetime

非活动会话在被垃圾回收之前的生命周期。如果未提供,将使用的实际生命周期值为 ini_get('session.gc_maxlifetime')

session_lifetime_attribute

DynamoDB 会话表中属性的名称,该会话表中存储了会话过期时间。默认值为 'expires'

consistent_read

会话处理程序是否应对 GetItem 操作使用一致性读取。默认为 true

locking

是否使用会话锁定。默认为 false

batch_config

用于在垃圾回收期间进行批量删除的配置。这些选项将直接传入 DynamoDB WriteRequestBatch 对象中。通过 SessionHandler::garbageCollect() 手动触发垃圾回收。

max_lock_wait_time

会话处理程序在放弃之前应等待获取锁定的最长时间(以秒为单位)。默认值为 10 且只用于会话锁定。

min_lock_retry_microtime

会话处理程序在两次获取锁定的尝试之间应等待的最短时间(以微秒为单位)。默认值为 10000 且只用于会话锁定。

max_lock_retry_microtime

会话处理程序在两次获取锁定的尝试之间应等待的最长时间(以微秒为单位)。默认值为 50000 且只用于会话锁定。

要配置会话处理程序,请在实例化处理程序时指定配置选项。以下代码是已指定所有配置选项的示例。

$sessionHandler = SessionHandler::fromClient($dynamoDb, [ 'table_name' => 'sessions', 'hash_key' => 'id', 'data_attribute' => 'data', 'data_attribute_type' => 'string', 'session_lifetime' => 3600, 'session_lifetime_attribute' => 'expires', 'consistent_read' => true, 'locking' => false, 'batch_config' => [], 'max_lock_wait_time' => 10, 'min_lock_retry_microtime' => 5000, 'max_lock_retry_microtime' => 50000, ]);

定价

除了数据存储和数据传输费用外,与使用 DynamoDB 相关的成本是根据表的预置的吞吐量容量来计算的(请参阅 Amazon DynamoDB 定价详细信息)。吞吐量用写入容量和读取容量单位来测量。Amazon DynamoDB 主页显示以下内容:

一个读取容量单位表示对大小为 4 KB 的项目每秒执行一次强一致性读取(或每秒执行两次最终一致性读取)。一个写入容量单位表示对大小为 1 KB 的项目每秒执行一次写入。

最后,吞吐量和会话表所需的成本将与您的预期流量和会话大小关联。下表说明了针对每个会话函数,对 DynamoDB 表执行的读取和写入操作量。

通过 session_start() 读取

  • 1 次读取操作(如果 consistent_readfalse,则仅为 0.5 次读取操作)。

  • (条件性)如果已过期,则为用于删除会话的 1 次写入操作。

通过 session_start() 读取(使用会话锁定)

  • 至少 1 次写入 操作。

  • (条件性)获取会话锁定时每次尝试的附加写入操作。基于配置的锁定等待时间和重试选项。

  • (条件性)如果已过期,则为用于删除会话的 1 次写入操作。

通过 session_write_close() 写入

  • 1 次写入操作。

通过 session_destroy() 删除

  • 1 次写入操作。

垃圾回收

  • 表中每 4 KB 数据 0.5 次读取操作,用于扫描过期的会话。

  • 每个过期项目 1 次写入操作,用于删除该项目。

会话锁定

DynamoDB 会话处理程序支持保守的会话锁定,以模拟 PHP 的默认会话处理程序的行为。默认情况下,DynamoDB 会话处理程序会关闭此功能,因为它会成为性能瓶颈并增加成本,尤其是在应用程序使用 Ajax 请求或 iframe 来访问会话时。在启用该功能之前请认真考虑您的应用程序是否需要会话锁定。

要启用会话锁定,请在实例化 'locking' 时将 true 选项设置为 SessionHandler

$sessionHandler = SessionHandler::fromClient($dynamoDb, [ 'table_name' => 'sessions', 'locking' => true, ]);

垃圾回收

在您的 DynamoDB 表中使用属性“expires”设置 TTL 属性。这将自动对您的会话进行垃圾回收,从而无需自行对其进行垃圾回收。

或者,DynamoDB 会话处理程序通过使用一系列 ScanBatchWriteItem 操作来支持会话垃圾回收。考虑到 Scan 操作的工作原理,为了找到所有过期会话并将其删除,垃圾回收过程可能需要大量预配置的吞吐量。

因此,我们不支持自动垃圾回收。更好的做法是将垃圾回收安排在非高峰时段进行,此时,突发吞吐量不会中断应用程序的剩余部分。例如,您可以有一个夜间 cron 作业触发器脚本,用于运行垃圾回收。此脚本需要执行类似如下的内容。

$sessionHandler = SessionHandler::fromClient($dynamoDb, [ 'table_name' => 'sessions', 'batch_config' => [ 'batch_size' => 25, 'before' => function ($command) { echo "About to delete a batch of expired sessions.\n"; } ] ]); $sessionHandler->garbageCollect();

您还可以在 'before' 内使用 'batch_config' 选项,以便在垃圾回收流程所执行的 BatchWriteItem 操作之间引入延迟。这将增加完成垃圾回收所需的时间,但可以帮助您分散 DynamoDB 会话处理程序发出的请求,从而帮助您在垃圾回收期间接近预置的吞吐能力或保持在该容量内。

$sessionHandler = SessionHandler::fromClient($dynamoDb, [ 'table_name' => 'sessions', 'batch_config' => [ 'before' => function ($command) { $command['@http']['delay'] = 5000; } ] ]); $sessionHandler->garbageCollect();

最佳实践

  1. 在与您的应用程序服务器接近或与之在相同区域的 AWS 区域中创建会话表。这可以确保您的应用程序与 DynamoDB 数据库之间的延迟最低。

  2. 认真选择您的会话表的预配的吞吐能力。考虑您的应用程序的预期流量和会话的预期大小。或者对您的表使用“按需”读/写容量模式。

  3. 通过 AWS 管理控制台或使用 Amazon CloudWatch 来监控您已使用的吞吐量,并根据需要调整吞吐量设置,以满足应用程序的需求。

  4. 使会话尽量小(最好小于 1 KB)。小型会话执行起来性能更好,需要的预置的吞吐能力更少。

  5. 除非您的应用程序需要,否则请勿使用会话锁定。

  6. 不使用 PHP 的内置会话垃圾回收触发器,而通过 cron 作业或其他计划机制将您的垃圾回收安排在非高峰时段运行。使用 'batch_config' 选项对您有利。

所需的 IAM 权限

要使用 DynamoDB SessionHhandler,您的已配置凭证必须有权使用您在上一步中创建的 DynamoDB 表。下面的 IAM policy 包含您需要的最低权限。要使用此策略,请将资源值替换为您之前创建的表的 Amazon 资源名称 (ARN)。有关创建和附加 IAM 策略的详细信息,请参阅 IAM 用户指南中的管理 IAM 策略

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:GetItem", "dynamodb:UpdateItem", "dynamodb:DeleteItem", "dynamodb:Scan", "dynamodb:BatchWriteItem" ], "Effect": "Allow", "Resource": "arn:aws:dynamodb:<region>:<account-id>:table/<table-name>" } ] }