[KairosDB inner workings; how does it store data in Cassandra?](https://yengas.github.io/kairosdb-inner-workings/)
記事によると[[KairosDB]]の[[Cassandra]]上の旧スキーマ(prior to v1.2.0)は次のようになる。
- string_index: KairosDB UIのドロップダウンメニューから参照されるのみ
- data_points: メトリック名とバケット開始時刻,バイナリデータの3カラム
- row_key_index: 特定のメトリック/タグに対してdata_pointsテーブルで利用可能なバケットを追跡する
- insertフロー
1. 書き込むデータがどのバケットにいるか計算 (timestamp - (timestamp % row_width)) [https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L287](https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L287)
2. row_keyを作成。メトリック名とバケット開始時刻との結合。[https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L289](https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L289)
3. row_key_indexにメトリック名とrow_keyを書く。row_keyはキャッシュされる。[https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L298](https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L298)
4. バケット開始時刻とrow_timeからoffsetを計算して、data_pointsに書き込む。
- readフロー
1. row_key_indexに問い合わせ [https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L425](https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L425)
2. data_pointsに問い合わせ [https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L582](https://github.com/kairosdb/kairosdb/blob/9469daa937056d84de121ff112a93947e44f960e/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L582)
次にCQLを利用した新しいCassandraのスキーマ
- row_key_time_index: メトリック名と時間範囲で問い合わせ、バケットを特定する
- row_keys_index: row_keyを保持するのに利用。mapによるtagsカラムをもつ。
- insertフロー: 旧スキーマとほぼ同じ。
1. バケットが計算される
2. row_keyが計算される
3. 対応するエントリがrow_key_timeとrow_keysに作成されていることを確認
1. [https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L54](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L54)
2. [https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L65](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L65)
4. data_pointsに挿入される
1. [https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L116](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CQLBatch.java#L116)
5. メトリック名のみがstring_indexに挿入される
- Readフロー
1. data_pointsバケットを探すために、row_key_time_indexにメトリック名と時間範囲を問い合わせる。[https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L780](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L780)
2. 複数のクエリがrow_keysから作成される [https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L788](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L788)
3. これらのクエリをメモリ上でフィルタ [https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L823](https://github.com/kairosdb/kairosdb/blob/842eb20d258377b3bea156919b6275dfb85f4f04/src/main/java/org/kairosdb/datastore/cassandra/CassandraDatastore.java#L823)
data_pointsのrowの範囲が3週間決め打ちなら、epoch time 0から3週間ずつ固定の範囲を作成しておいて、クエリに含まれる時間範囲からどのrowに保存されているかを静的に決定できそう。なぜrow_key_time_indexをわざわざ用意するのかと思ったけど、3週間が大きすぎるのでそれをさらに小さいバケットに分割しているということかな。
## Redis Clusterのスケールインに失敗