2021/11/7 aws-sessionstore-dynamodb
onk.icon
session を DynamoDB に保存したい
ElastiCache (for Redis) は固定費が掛かってしまう
Cookie Store よりもサーバ側でコントロールしやすい状態でありたい
AWS 公式
前に見た aws-sdk-rails から使われている aws-sdk-rails で試した方がオモテナシが効いているので楽そう
aws-sdk-rails
aws-sdk-rails には generator が付いている
code:sh
rails generate dynamo_db:session_store_migration <MigrationName>
code:rb
class CreateDynamoDbSessionsTable < ActiveRecord::Migration6.1 def up
Aws::SessionStore::DynamoDB::Table.create_table
end
def down
Aws::SessionStore::DynamoDB::Table.delete_table
end
end
rails db:migrate すると DynamoDB のテーブルができる
code:sh
aws dynamodb describe-table --region ap-northeast-1 --table-name sessions
code:json
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "session_id",
"AttributeType": "S"
}
],
"TableName": "sessions",
"KeySchema": [
{
"AttributeName": "session_id",
"KeyType": "HASH"
}
],
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/sessions",
...
}
}
config/initializers/session_store.rb で session_store を指定すると使えそう
dynamodb_store
config で指定するのは
いつもの感じかな
いつもの is
code:rb
{
key: "_xxx_session",
expire_after: (60 * 60 * 24 * 30) - 1,
httponly: true,
secure: Rails.env.production?,
}
Note that :secret_key is a mandatory configuration option that must be set.
aws-sdk-rails では、Rails.application.secret_key_base が使われる
aws-sdk-rails では、config/dynamo_db_session_store.yml や config/dynamo_db_session_store/RAILS_ENV.yml を勝手に読んでくれる
By default sessions do not expire.
DynamoDB には TTL があるので使ってくれてもヨサソウだけど……。
この辺か?
code:config/dynamo_db_session_store.yml
# Integer Maximum number of seconds earlier # from the current time that a session was created.
# By default this is 7 days.
#
# max_age: 604800
# Integer Maximum number of seconds # before the current time that the session was last accessed.
# By default this is 5 hours.
#
# max_stale: 18000
do not expire と書いていた割になんかデフォルト値がありそう
デフォルト値は無かった!丁寧にコメントアウトされている
code:lib/aws/session_store/dynamo_db/configuration.rb
# @option options Integer :max_age (nil) Maximum number of seconds earlier # from the current time that a session was created.
# @option options Integer :max_stale (nil) Maximum number of seconds # before current time that session was last accessed.
max_stale 付けておくとヨサソウ!
code:lib/aws/session_store/dynamo_db/locking/base.rb
# Update client with current time + max_stale.
def expire_at
max_stale = @config.max_stale || 0
{ value: (Time.now + max_stale).to_i, action: 'PUT' }
end
code:rb
# Attributes to update via client.
def attr_updts(env, session, add_attrs = {})
data = data_unchanged?(env, session) ? {} : data_attr(session)
{
attribute_updates: merge_all(updated_attr, data, add_attrs, expire_attr),
return_values: 'UPDATED_NEW'
}
end
# @return Hash Options for saving a new session in database. def save_new_opts(env, sid, session)
attribute_opts = attr_updts(env, session, created_attr)
merge_all(table_opts(sid), attribute_opts)
end
# @return Hash Options for saving an existing sesison in the database. def save_exists_opts(env, sid, session, options = {})
attribute_opts = merge_all(attr_updts(env, session, add_attr), expected)
merge_all(table_opts(sid), attribute_opts)
end
こういうのの max_stale っていくつにしておくんだろう
expire_after より長いよね?
こうしておこう
code:rb
expire_after: (60 * 60 * 24 * 30) - 1, # 1month
max_stale: (60 * 60 * 24 * 30 * 3), # 3month
情報まったく出てこない……!
他何か調べることあるかな?
lock 機構周りか
エイヤで移行するか
dynamodb-local と上手く付き合う方法は知っておきたい
どっちがよくある話かしら
endpoint を変えた dynamo_db_client を渡す
Aws.config で endpoint を変える
前者ほとんど使われてない気がする
dynamodb 以外の endpoint があるか、かな
s3, sqs はいかにもありそう
今 awslocal 存在知った
Locking Strategy
デフォルトでは Null
Pessimistic を選択できる
Pessimistic を選択したいのはどういうときか
同時に session に書き込んでレースコンディションが起きるのを排除したい?
クリティカルになりそうなロックは DB で排他制御しそう
session に何を入れるか。ログインセッション以外はだいたい吹っ飛んでもいいモノを入れてると思うなぁ
2窓使われて困ることは無かろう