RedisのArray型:長い開発の短い物語
原文は Salvatore Sanfilippo により に公開されました。 このブログを購読する
Redisの新しいArrayデータ型に取り組み始めたのは、1月の最初の数日のことでした。PRがリポジトリにマージされたのはつい最近のことで、このコードは4か月かけて熟成されたことになります。実装はどちらかといえばパートタイムで進めました(どちらかといえば、というのは、実際には何週間もフルタイムでやっていたからです。キーボードから離れるのが難しいこともあるのです)、LLM以前でも、この実装自体は4か月あれば自分でもできたでしょう。変わったのは、同じ期間でそれ以上のことができたということです。これは、その出来事の短い物語です。
最初の1か月は、仕様書を書くことだけに費やしました。新しいデータ型の存在理由、C言語の構造体、採用したスパース表現、リングバッファやARINSERTにおける配列カーソルの正確なセマンティクスについてです。何日もかけて長い仕様書を手で書き始め、最初はOpusとペアを組み、やがてGPT 5.3がリリースされると設計と開発のすべてをCodexに切り替えました。それ以来、システムプログラミングのタスクではGPT 5.xだけを使っています。AIのおかげで仕様は大きく進化しました。フィードバックの往復、どの設計が最善か、どこで妥協すべきか、何が過剰設計で何がそうでないかといった知的な議論を重ねながら。
2か月目からは、自動プログラミング(お好みで自動コーディングと呼んでください)で実装を始め、生成されたコードを常にレビューしました。すると、選んだ間接参照のレベルが間違っていることに気づきました。どうしても ARSET myarray 293842948324 foo のように実行しても、巨大なメモリ確保なしに正しく動くようにしたかったのです。当初用意していたdirectory + slices(スパースとデンス)の2階層では不十分でした。AIという支えがあったので妥協はせず、もう一歩踏み込むことにしました。特定の条件に達すると、データ構造は内部で形を変え、スライス化されたデンスなdirectoryを束ねるスーパーディレクトリとなり、そこから実際の配列スライス(デフォルトで1スライスあたり4096要素)を指すようになります。この設計により、求めていた内部的な「実質的に配列である」という表現と、目指していたメモリ特性を保ちつつ、ARSCANやARPOPでは範囲の広さではなく存在する要素数に比例した時間で既存の配列を走査できるようになりました。
次は、すべてのコードを一行一行読み込む段階でした。すべては動いていましたし、この型はやはりAIのおかげで大規模なテストも備えていましたが、表面的に動くことが最適であることを意味するわけではありません。望ましくない小さな非効率や設計ミスをいくつも見つけたので、多くのモジュールを手作業とAI支援で書き直すプロセスを始めました。この段階が終わると、3か月目に入り、さまざまな方法で実装にストレステストをかけるようになりました。次第に、これは本当に堅牢で、有用で、よく設計されているという確信が持てるようになりました。
そして……それが起こりました。データ構造が使いやすいかどうか、さまざまなユースケースをモデル化しているうちに、markdownファイルをRedisのarrayに入れ始めたのです。ファイルはこのデータ型に非常によく合うからです。その頃、別の目的でエージェントを使った作業をしていたこともあり、必要としていたskillsのmarkdownファイルを一元化したナレッジベースが作れることに気づきました。そこで自分の必要性から、ARGREPを実装することにしたのです。ただ、正規表現も欲しかった。どのライブラリを選ぶべきか?
最終的に選んだのはTREでした(Ville Laurikari氏に感謝します!)。Redisで正規表現を扱うなら、時間的にも空間的にも病的なパターンが存在しないことを確信できる必要があるからです。ただTREは、foo|bar|zap のマッチングという、極めて有用な特定のケースで非常に非効率でした。そこでGPTの助けを借りて最適化し、潜在的なセキュリティ上の問題をいくつか修正し、テストを拡充しました。これですべての準備が整いました。
そこから得た最大の気づきは何だったかお分かりでしょうか。高品質なシステムプログラミングでは、依然として自分自身が深く関与し続けなければならないということです。ただ、AIがあったことで、そうでなければ避けていたであろう複雑さのレベルにまで踏み込むことができました。AIは2つのことに対するセーフティネットになってくれました。非常に疲れる大規模なタスク(後から追加してテストした32 bit対応のような)と、複雑なアルゴリズムに明らかなバグがないことを保証するために必要な仮想的な労働力です。最初の巨大な仕様書を書いたことが、その後の作業を成功に導く鍵でした。sparsearray.cやt_array.cのすべての行をレビューし、うまくはまっていない部分を修正していくうえでも同様に鍵となったのです。
ユースケースについてはここではあえて触れません。PR自体に詳細を記したメッセージで文書化するようにしたからです。
https://github.com/redis/redis/pull/15162
なのでここで同じことを繰り返してもあまり意味がありません。ただ一つ言えるのは、数値インデックスがセマンティクスの一部となるデータ型を、Redisが持つべき時がついに来たと心から信じているということです。
ArrayのPRが soon に受け入れられ、この新しい型が開くユースケースの恩恵を皆で受けられることを願っています。もちろん、フィードバックは歓迎します。ありがとうございました。
記事をランダムに読む
コメント
ログインしてコメントする