Redis

Redis とは

Redis は、キーバリューストアなインメモリデータベースです。
Redis

Redis は、キャッシュやセッションストアなど、データベースとアプリケーションの間で一時的なデータ格納場所やデータブローカーとして活用されます。
また、ソート済みリストの保持など、データベースでは遅い処理を代行するために活用されています。

キーバリューとは、データをキーとバリューの形式で格納するデータ構造です。
様々な言語で同様のデータ構造が利用されており、C++ なら連想配列 (std::map)、Python なら辞書型 (dict)、Rust なら HashMap (std::collections::HashMap) として実装されています。
(数学だと、ただの写像です)
形式的には、バリューに対して一意な識別子 (キー) を対応させるデータ構造と説明されます。
例えば、以下のようになります。

*key *value
name kamojiro
age 27
hobby AtCoder
skill AtCoder

このように、key である name や age に対して、value が対応しています。
key が重複することや、key が存在するが対応する value が存在しないことは許されません。
しかし、value については重複しても問題ありません。

インメモリデータベースとは、メモリ (RAM) 上にデータを保存するデータベースのことです。
一般にデータベースは、ディスク (HDD や SSD) にデータを保存します。
有名どころだと、PostgreSQLMySQLApache Kafka などはディスクにデータを保存します。
今回のインメモリデータベースである Redis ではデータをメモリ上に保存します。
一般にディスクとのデータの交換よりもメモリとのデータの交換のほうが高速であるため、データの更新・読み取りを高速に行うことができます。

以下にコンポーネントごとのデータI/Oの目安が記載されています。
Numbers Every Programmer Should Know By Year

Redis の特徴

キーバリューストアやインメモリデータベースとしての特徴は以下のようなものがあります。

  • 読み書き操作が高速

キーバリューなインメモリストアとしては、memcached がよく比較されます。
memcached は Redis と比べてシンプルなものになっています。
Redis は様々なユースケースに対応できるように設計されいます。

  • 様々なデータ型
  • データの永続化
  • データの冗長化
  • 高可用性構成とスケーラビリティ

様々なデータ型

Redis では、以下のデータ型を利用できます。
Redis | AWS

データ型 *説明
Strings 最大 512MB のテキストまたはバイナリデータ
Lists 追加された順に並べられた文字列の集合
Sets 順序なしの文字列の集合で他の Set 型と交差、和集合、差集合演算を行うことができる
Sorted Sets 値ごとに並べられた Set
Hashes フィールドと値のリストを保存するデータ構造
Bitmaps ビットレベルの演算を実行できるデータタイプ
HyperLogLogs データセット内の一意の項目を推定する確率的データ構造

一部補足します。
String はバイナリデータを格納できるため、画像データなども格納できます。
Sorted Sets はデータを順序を保って保持できるため、高速なランキングボードを実現できます。
HyperLogLogs はユニークユーザー数の概算などに利用されますが、それ自体でも面白い話なので参考文献を記載しておきます。

HyperLogLog in Presto: Faster cardinality estimation - Facebook Engineering
http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf

簡単に説明すると、一意なユーザー情報から生成されるハッシュ値の連続した 0 の長さを元にユニークユーザー数を概算します。
例えば、ある長さのビット列の場合、先頭から 0 が3つ連続する確率は  \frac{1}{8} となります。
具体的に書き出すと、以下のようになります。

000
001
010
011
100
101
110
111

大雑把ですが、先頭から 0 が3つ連続するためには大体 8 つのビット列が必要なため、ユニークユーザー数はおよそ 8 と概算することができます。
これの精度を向上させたものが、HyperLogLog になります。

データの永続化

Redis のデータの永続化機構は、スナップショット形式の RDB と、ログ追記型の AOF があります。
RDB は一定時間(と一定の更新)ごとにデータをディスクに保存します。
AOF は書き込みごと(正確には、短時間ごと)に、実行コマンドをディスクに保存します。

RDB は AOF よりもデータ保存に必要なディスク容量が小さいです。
しかし、スナップショットとスナップショットの間のデータは保存していないため、障害時にデータが失われる可能性があります。
AOF は RDB よりも細かくディスクへのデータの保存を行うため、RDB と比べて障害時に失われるデータを少なくできます。

RDB は定期的なバックアップや大規模な障害に対応するために、AOF は一時的な障害からの復旧に利用されます。

データの冗長化

Redis では、マスターレプリカ形式のレプリケーションを利用できます。
マスターでデータの更新が行われ、変更がレプリカにも反映されます。
読み込みは、マスターとレプリカのどちらに対しても行うことができ、参照を負荷分散できます。
Redis のレプリケーションでは、データの同期は非同期となっているため、マスターとレプリカのデータが差異があることがあります。

高可用性構成とスケーラビリティ

Redis の高可用性構成には、Redis Sentinel と Redis Cluster があります。

Redis Sentinel は、レプリケーション構成とそれを監視する Redis Sentinel たちから構成されます。
マスターに障害が発生した場合に、レプリカをマスターに昇格させる(自動フェールオーバー)などを行います。

Redis Cluster は、データを分散して保持するマルチマスター構成です。
各マスターが別々に更新処理を行えるため、更新を負荷分散できます。
特に、大規模な Redis クラスターを構成したい場合に利用されます。
各マスターにレプリカを追加することもできます。