[[Xtsdb]]のデータ階層化方式で,系列のカーディナリティが高いときに,系列の長さが規定量に届く前に[[notes/system-engineering/Redis]]のメモリ使用量が頭打ちになることがある。こういうときどうするかなあ。Redisのmaxmemoryあたりのメモリ使用率をgoroutineで定期的に監視して、閾値を超えたらSCANでキーをなめて、レコードサイズが大きいものを削除していくとかだろうか。レコードサイズが大きいキーをどうやって知るか。ランダムなカーソルでSCANしてえたサンプルレコード群に対して、現在のメモリ使用率のパーセンタイル値をフラッシュするレコードサイズの閾値とするとかかなあ。そのあと閾値をもとに改めて全レコードをSCANして、閾値を超えているキーを削除していく。SCANする間にメモリ使用率を参照しつづけて、メモリ使用率が増加しつづけるようであれば、goroutineを増やして削除スピードをあげる。メモリ使用率を一定に保つための制御にPID制御器とかが使えそう。 あるいは現在のメモリ使用率とキーの個数をもとに、系列単位の上限バイト数を動的に変更し続けるとか。 XtsdbのなぜかRedis上のデータを削除できていない問題に取り組んだ。 どうもRedisのPub/Subが安定していないようにみえる。TTL以外に XtsdbのTTL値がまれにおかしな値になってRedisに怒られる。 ```go package main import ( "fmt" "hash/fnv" "math" ) func getMetricID(metricName string) uint64 { h := fnv.New64a() h.Write([]byte(metricName)) return h.Sum64() } func main() { var eseconds float64 = 1800.0 name := "cpu.usage_user;{hostname=host_0;}region=ap-northeast-1;datacenter=ap-northeast-1a;rack=72;os=Ubuntu16.10;arch=x86;team=CHI;service=10;service_version=0;service_environment=test; " id := getMetricID(name) ttlf := eseconds + math.Mod(math.Float64frombits(id), eseconds) fmt.Println(math.Float64bits(ttlf)) } ``` [https://play.golang.org/p/4Kru5M-knap](https://play.golang.org/p/4Kru5M-knap)