The first release candidate of Redis 4.0 is out

Salvatore Sanfilippo

Redis 4.0初のリリース候補が公開

原文は Salvatore Sanfilippo により に公開されました。 このブログを購読する

まだ安定版ではないが、間もなくそうなる予定で、僕らユーザーにとってRedisをもっと便利にする機能がずらりと揃っている。ついにRedis 4.0 Release Candidate 1が登場した。3.4ではなく4.0と名乗るだけの度胸がある。個人的にセマンティックバージョニングにはこだわりがない。むしろバージョン番号やその跳ね上がりで、新バージョンが何なのかを伝えたいと思っている。今回で言えば、4.0は「これはヤバい」という意味だ。

Redis 4.0には、本来ならとっくにあってもよかった機能がたくさん詰まっている。別の世界なら、一人の開発者が北斗の拳のように10人に分身して一斉にコーディングできるのだろうが。どんなに新しいVimのショートカットを覚えようとしても、分身の技はキーバインドにはないのだ。

ともあれ、4.0でようやくその多くを形にできた。以下が主な新機能のリストだ。詳細や参考情報とあわせて紹介しよう。

1. モジュール

おそらくすでにご存知の通り、Redis 4.0にはモジュールシステムが導入された。RDB/AOFで永続化される新しいデータ型の実装や、ノンブロッキングコマンドの作成など、かなり高度なことができる。ポイントは、これらすべてがコアとは完全に分離された高水準な抽象APIを通じて行われるということで、作成したモジュールは今後のRedisのリリースでも動き続けるということだ。モジュールを使って私はNeural Redisを書いた。Redis内部で学習可能なニューラルネットワーク型だし、ほかにも多くの人がとても面白いものを作っている。Rustで実装されたレート制限コマンド、Redis上に構築されたグラフDB、セカンダリインデックス、時系列モジュール、全文検索など枚挙にいとまがないが、これはまだ始まりに過ぎないという気がしている。

これは、Redisがコアを最小とは言わないまでも、少なくとも大多数のユーザーにとって有用な、かなり汎用的なものに絞ったまま、新しい領域へ成長していくことを可能にするだけではない。多くのタスクで、ネットワークサーバーを一から書き直す手間を回避できる可能性も秘めている。たとえ作りたいものがRedisやデータベース、キャッシュなど、Redisと呼ばれるものとは関係がなくてもだ。つまり、プロトコルや既存のクライアントなど、Redisの「インフラ」を利用するためにモジュールを書けばいい。だから私はこれに手応えを感じている。コアにプレッシャーはなく、もっとクレイジーなことをしたいユーザーには自由がある。

2. レプリケーション バージョン2

これは運用の観点から本番環境で非常に役立つはずだ。かつて僕らは「PSYNC」と呼ばれるものを導入した。マスターとスレーブ間の接続が切れても、中断したところから続きを再開できるようにする新しいマスター・スレーブプロトコルだ。それ以前は、マスターとスレーブ間のレプリケーションリンクが一度でも切れるたびに完全同期が必要だった。マスター側でRDBファイルを生成し、転送し、スレーブ側でロードする。仕組みはご存知の通りだ。だからPSYNCは本当に大きな改善だった。だが、それだけでは足りなかった……

PSYNCはフェイルオーバーが起きたときには十分ではなかった。スレーブがマスターに昇格した場合、旧マスターとレプリケーションしていたスレーブたちは、新たに昇格したスレーブに接続してPSYNCすることができず、完全な再同期が必要だった。これはあまり良くないし、Redis Clusterにとっても好ましくない。ただ、これを修正するにはレプリケーションプロトコルの変更が必要だった。というのも、インスタンス間に共通のレプリケーション履歴さえあれば、どんなトポロジー変更の後でも部分再同期が機能することを確実にしたかったからだ。

まず必要だった変更の一つは「チェインしたレプリケーション」の動作についてだ。つまり、スレーブのスレーブのスレーブ……といった構成はどう動くのか。例えば、Aがマスターで、次のような構成があるとする。

A —> B —> C —> D

AはBのマスターだが、BはCのマスターといった具合だ。Redis 4.0以前に起きていたのは、BがAからレプリケーションプロトコルを受信するというものだった。レプリケーションプロトコルは通常、書き込みコマンドのストリームだ。BはCにとってのマスターとして、内部的にAがやっていたことをそのまま行っていた。つまり、書き込みがあるたびにCに渡すための適切なレプリケーションプロトコルを改めて生成していた、という具合だ。

ところが今では、BはAから受け取ったものをそのまま逐語的にCへプロキシし、CもDに対して同じことをする。すべてのサブスレーブが同一のバイトストリームを受け取るようになったことで、特定の履歴に「タグ」を付け、そのタグとオフセットを使って、共通部分があれば常に続きを再開しようと試みることができる。

マスター自身も、スレーブに変わった際に新しいマスターとPSYNCできるようになった。そしてスレーブは、「クリーンな」再起動の後でも、RDBファイル内に保存されたレプリケーションのタグとオフセットの情報を使って、通常はマスターとPSYNCできる。

詳細はうまく動作させるためにこれよりずっと複雑だが、要するに、可能な限り完全な再同期で悩まされないようにということだ。そしてPSYNC v2はどうやらそれをうまくやってくれる。この機能に興味があれば、ぜひ試して感想を聞かせてほしい。

3. キャッシュの削除ポリシーの改善

この件については数か月前に記事をまるまる一本書いた。http://antirez.com/news/109。だからここでは要約だけにしておこう。今ではLFU(Least Frequently Used)が使えるようになり、他のすべてのポリシーもより堅牢で高速かつ正確な実装に切り替わった。キャッシュ用途にとっては大きなニュースだ。このあたりが気になるなら、詳細が詰まった本編の記事を読んでみてほしい。

4. ノンブロッキングなDELとFLUSHALL/FLUSHDB

コードネームは「オブジェクトの遅延解放」だが、素晴らしい機能に対して少々地味な名前だ。UNLINKという新しいコマンドが追加された。これはデータベース内のキーの参照だけを削除し、実際のメモリ解放は別スレッドで行う。だから、巨大なキーに対してDELの代わりにUNLINKを使えば、サーバーがブロックされることはない。さらに、FLUSHALLやFLUSHDBのASYNCオプションを使えば、DB全体やインスタンス内のすべてのデータを同様に非同期で削除できる。新しいSWAPDBコマンドと組み合わせると、FLUSHDB ASYNCはなかなか面白い使い方ができる。例えば、DB 1に新しいバージョンのデータを投入しておき、SWAPDB 0 1で中身を入れ替え、古いデータが残った方のDBをFLUSHDB ASYNCで非同期に消去し、また新しいバージョンを作って繰り返すといったことが可能だ。これが今可能になったのは、DB全体のフラッシュがもはやブロックしなくなったからだ。

UNLINKがDELのデフォルトになっていないのには理由がある。いろいろ知っているが、ここでは話せない(**)。

5. RDB-AOF混合の永続化フォーマット

オプションで、有効にすれば、AOFの書き換え時にAOFファイルの先頭にRDBファイルを付加する形で実行されるようになる。生成もロードもより高速だ。これは特定の環境では非常に有用だが、AOFファイルの透過性は下がるため、今のところはオプション扱いだ。この機能は長いこと議論されてきて、ようやく「入り」した。

6. 新しいMEMORYコマンド

これは大好きだ。かつてLATENCY DOCTORを導入したとき、メーリングリストの「Redisが遅い」という苦情がごく少数に激減したのと同じくらい気に入っている。今度はメモリ問題についても同じものができた。

127.0.0.1:6379> MEMORY DOCTOR
Hi Sam, this instance is empty or is using very little memory, my issues detector can't be used in these conditions. Please, leave for your mission on Earth and fill it with some data. The new Sam and I will be back to our programming as soon as I finished rebooting.

映画の権利者からはSFのセリフから着想を得たとして訴えられるかもしれないが、まあいい。刑務所に入ったらオレンジを差し入れてほしい。

MEMORYはそれ以上のこともたくさんできる。

127.0.0.1:6379> MEMORY HELP
1) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
2) "MEMORY STATS                         - Show memory usage details"
3) "MEMORY PURGE                         - Ask the allocator to release memory"
4) "MEMORY MALLOC-STATS                  - Show allocator internal stats"

USAGEサブコマンドによるメモリ使用量のレポートは非常に役立つだろうし、STATSが提供する詳細な情報も同様だ。

今のところこれらはまったく文書化されていないので、何が何だか自分で探って楽しんでほしい。

7. Redis ClusterがNAT/Dockerに対応

ただこれは悪いニュースでもある。ノード間の通信に使う「Cluster bus」のバイナリプロトコルが変わったため、4.0にアップグレードするにはRedis Clusterを一斉に再起動する必要があるからだ。このNAT/Docker対応にうまく乗せられてしまった、申し訳ない。後方互換にしようと試みたが、まったく不自然なことをせずに――いや、不自然なことをしても――簡単に、あるいはどんな方法でも実現する方法はなかった。

この機能はサンプルのredis.confファイルで説明されている。私が他の機能に比べてこの機能にあまり興奮していないことが伝わるだろう?

まあ……これで大体以上だ。これらが主な変更点だ。リリースノートをもっと読みたいならこちら:https://raw.githubusercontent.com/antirez/redis/4.0/00-RELEASENOTES

安定版になるまでのETAはいつも通り未定だ。2〜4週間ごとに新しいRCをリリースする予定だ。バグの深刻度も報告頻度も十分に落ち着いてきたら、それがRedis 4.0-finalのときだ。ただ、更新すべきドキュメントも山ほどあるので、やることはたくさんある。

このリリースに貢献してくれたすべての人に感謝したい。多くの人が大きな形で貢献してくれた。上記のリリースノートにはすべてのコミットのリストがあるので、コミッターの名前を確認できる。

RedisコミュニティとRedis Labsに、これらすべてを可能にしてくれたことに感謝するが、とりわけ、日々の問題解決にRedisをうまく活用して物事を成し遂げてくれているすべての開発者に感謝したい。コーディングを楽しむこと以外で、これこそがすべての核心なのだから。

P.s. 新しいコードを最も早く入手するには、GitHubから'4.0'ブランチを取得してほしい。リポジトリはいつも通りantirez/redisだ。

** UNLINKがDELのデフォルトの挙動になっていない理由の詳細については、https://news.ycombinator.com/item?id=13091370を参照。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント