はじめに
Geodeをキャッシュサーバーとして利用した場合、キャッシュデータをいかに消していくか、鮮度を保つかという問題になるとおもいます。
今回はどのようにデータを消していくかについて書いていきます。
LRU設定を利用する
一番簡単な方法は、Regionを作成する段階でLRU仕様にしてしまうことです。
gfsh>create region --name=lruregion --type=PARTITION_HEAP_LRU
Regionのショートカットを利用した場合は、デフォルトでlru-heap-percentageが設定されます。
特に追加設定をしていない場合は、ヒープの割合が80%を超えるとデータの退避が始まります。割合を変更したい場合は、server起動時に指定することになります。
gfsh>start server --name=server1 --locators=xxx01 --eviction-heap-percentage=90
また、cash.xmlを利用する場合は、resource-managerで設定することができます。
LRUの検証
実際に試してみましょう。
gfsh>put --key="key1" --value="value1" --region=lruregion
gfsh>get --key="key1" --region=lruregion
Result : true
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Value : value1
データを1件投入した段階では下記のようになっています。
gfsh>show metrics --member=xxx02.yahoo.co.jp --categories=member,region
Member Metrics
Category | Metric | Value
-------- | ---------------------------- | -----------
member | upTime | 1686
| cpuUsage | 2
| currentHeapSize | 72
| maximumHeapSize | 494
region | totalRegionCount | 8
| listOfRegions | lruregion
| rootRegions | /lruregion
| totalRegionEntryCount | 1
| totalBucketCount | 1
| totalPrimaryBucketCount | 1
データを連続して投入していきます。プログラムは割愛します。
あふれる寸前まで来ました。
gfsh>show metrics --member=xxx02.yahoo.co.jp --categories=member
Member Metrics
Category | Metric | Value
-------- | ---------------------------- | -----------
member | upTime | 2006
| cpuUsage | 16
| currentHeapSize | 394
| maximumHeapSize | 494
その後続けるとLRUが働き初期に投入したデータが消えたことを確認できました。
gfsh>get --key="key1" --region=lruregion
Result : false
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Value : <NULL>
gfsh>show metrics --member=xxx02.yahoo.co.jp --categories=member
Member Metrics
Category | Metric | Value
-------- | ---------------------------- | -----------
member | upTime | 2884
| cpuUsage | 1
| currentHeapSize | 131
| maximumHeapSize | 494
気になる点としては、かなりメモリが開放され、同時期に投入したデータがすべて消えてしまいました。これは、テストデータの投入時期がほぼ同じことによるものなのか、仕様なのかまでは検証できていません。
有効期限の設定
キャッシュデータの鮮度を高めるために、有効期限を設けたくなることがあります。
その場合は、Region毎にexpirationを設定することができます。
key毎に一定期間で有効期限を設定
key毎に一定時間で有効期限を設定する場合はentry-time-to-live-expiration
を利用します。設定の単位は秒となります。enable-statistics=true
はexpirationを利用するうえでは必須です。
gfsh>create region --name=ettlregion --entry-time-to-live-expiration=30 --enable-statistics=true --type=REPLICATE
gfsh>put --key=key1 --value=value1 --region=ettlregion
Result : true
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Old Value : <NULL>
# 15秒後にput
gfsh>put --key=key2 --value=value2 --region=ettlregion
Result : true
Key Class : java.lang.String
Key : key2
Value Class : java.lang.String
Old Value : <NULL>
# key1をputしてから30秒後get 消えている
gfsh>get --key=key1 --region=ettlregion
Result : false
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Value : <NULL>
# 同じくkey1をputしてから30秒後 key2は残っている
gfsh>get --key=key2 --region=ettlregion
Result : true
Key Class : java.lang.String
Key : key2
Value Class : java.lang.String
Value : value2
putしてからの時間で有効期限を迎えたことがわかります
keyの最終アクセスからの期間で有効期限を設定
利用頻度の高いデータは有効期限を伸ばしたいケースでは、entry-idle-time-expiration
を使用します。
gfsh>create region --name=eitregion --entry-idle-time-expiration=30 --enable-statistics=true --type=REPLICATE
gfsh>put --key=key1 --value=value1 --region=eitregion
Result : true
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Old Value : <NULL>
# key1と同時にput
gfsh>put --key=key2 --value=value2 --region=eitregion
Result : true
Key Class : java.lang.String
Key : key2
Value Class : java.lang.String
Old Value : <NULL>
# putから15秒後にget
gfsh>get --key=key1 --region=eitregion
Result : true
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Value : value1
# putから30秒後にget key2は消えている
gfsh>get --key=key2 --region=eitregion
Result : false
Key Class : java.lang.String
Key : key2
Value Class : java.lang.String
Value : <NULL>
# putから30秒後にget 15秒前にgetしたkey1は残っている
gfsh>get --key=key1 --region=eitregion
Result : true
Key Class : java.lang.String
Key : key1
Value Class : java.lang.String
Value : value1
Region毎に有効期限を設定を設定する
keyごとではなく、Region単位で設定したい場合は、egion-idle-time-expiration
とregion-time-to-live-expiration
を使用してください。検証したところどちらを使っても、最後にputした時間を基準に有効期限が対象のregion内のデータにかかります。getしても有効期限は伸びませんでした。
有効期限をむかえたデータについて
有効期限をむえた場合のデータがどうなるかは、expiration-action
を設定で決まります。デフォルトではinvalidateが指定されますが、この場合は無効になるだけで、実際にはデータは残っているようです。
destroyを使用しないとメモリがあかないことは検証で確認しています。
まとめ
データのライフサイクル方針や、メモリの節約など、有効期限が必要になる場面は色々ありますので有効に使えると良いですね。