The first release candidate of Redis 4.0 is out

Salvatore Sanfilippo

Redis 4.0初のリリース候補が登場

まだ安定版ではないが、もうすぐそうなる。そしてRedisを僕らユーザーにとってさらに便利にする機能が長いリストになって詰まっている。ついにRedis 4.0 Release Candidate 1が登場した。3.4ではなく、あえて4.0を名乗るだけの大胆さだ。僕にとってセマンティックバージョニングなんてどうでもいい。大事なのは、バージョン番号やその跳ね方で、新バージョンが何なのかを伝えることだ。今回、4.0が意味するのは「これはヤバい」ということだ。

Redis 4.0には、本来ならとっくにあってもおかしくない機能がたくさん詰まっている。もし1人の開発者が『北斗の拳』のケンシロウのように10人に分身して一斉にコードを書ける別世界があったなら、とっくに実現していたはずのものだ。でも、どんなにvimの新しいショートカットを覚えようとしても、分身の技だけはコマンド一覧に出てこない。

ともあれ、4.0でようやくその多くを形にできた。ここでは主なものをいくつか、詳細やさらに学べるリンクとともに紹介しよう。

1. モジュール

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

これによって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. キャッシュの追い出し改善

この件については数か月前に記事を丸ごと1本書いた:http://antirez.com/news/109。だからここでは要約だけにしよう。新たにLFU(Last Frequently Used)が加わり、他のすべてのポリシーも、より堅牢で高速かつ高精度な実装へ切り替わった。キャッシュ用途にとっては大きなニュースだ。興味があれば、詳しい情報が詰まった本記事を読んでみてほしい。

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

コードネームは「lazy freeing of objects」だが、イケてる機能の割にはパッとしない名前だ。新コマンドUNLINKは、データベース内のキーへの参照だけを削除し、実際のメモリ解放は別スレッドで行う。だから巨大なキーに対してDELの代わりにUNLINKを使えば、サーバーはブロックされない。さらにFLUSHALLやFLUSHDBのASYNCオプションを使えば、DB全体やインスタンス内の全データに対しても同じことが可能だ。2つのRedisデータベースの中身を入れ替える新コマンド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」ブランチをfetchすることだ。リポジトリはいつも通りantirez/redisにある。

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

原文は Salvatore Sanfilippo により に公開されました。

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