【入門編】 Ziplist最適化設定 – Redis

こんにちは! Redisのメモリ管理、そしてインメモリデータベースとしての極限のパフォーマンスを支える深淵へようこそ。今日は、Redisが誇る隠れた名機能、「Ziplist(ジップリスト)」と、その境界線を決める設定値についてお話ししよう。

「Redisは速い」というのは、君もすでに知っているはずだ。しかし、データをただ詰め込むだけでは、すぐにメモリがパンクしてしまう。数百万、数千万という膨大なキーを扱う現場では、「いかにメモリを節約しつつ、スピードを落とさないか」がエンジニアの腕の見せ所になる。

今回は、その極意である `hash-max-ziplist-entries` や `hash-max-ziplist-value` といった設定値を、初心者にもスッと腑に落ちるように紐解いていくよ。ここをクリアすれば、君もRedisのメモリ構造を操るワンランク上のエンジニアだ。しっかりついてきてほしい。

—

1. Redisのデータ構造は「変身する」?!

まず、Redisの面白い特徴から話そう。
Redisの「ハッシュ(Hash)」や「リスト(List)」といったデータ型は、実は状況に応じて姿形をガラリと変える。

これを日常に例えてみよう。
君が「道具箱」を持っているとする。中身がほんの数個の小さなネジやドライバーだけなら、わざわざ大きな工具箱を使うかい?ポケットや小さなピルケースにまとめて入れたほうが、持ち運びも軽くて場所を取らないよね。
しかし、工具が100個に増え、電動ドリルや大きなハンマーが入ってきたらどうだろう。小さなピルケースでは収まらないし、取り出すのも一苦労だ。だから、頑丈で整理された大きな本格的な工具箱に持ち替えるはずだ。

Redisもこれと全く同じことをしている。

  • データが小さくて少ないとき(ピルケース): メモリを極限まで圧縮して節約する、コンパクトな特別構造(これが Ziplist だ!)を使う。
  • データが大きく、または多くなったとき(本格的な工具箱): 検索や追加が圧倒的に速い、本格的な辞書のような構造(ハッシュテーブルやスキップリスト)に自動で「変身(昇格)」する。

—

2. Ziplist(ジップリスト)って一体なんだ?

通常のRedisのデータは、それぞれが独立したメモリの領域を陣取っている。これだと、小さなデータがたくさんあるときに、データの管理情報(オーバーヘッド)だけでメモリが無駄食いされてしまうんだ。

そこで登場するのが Ziplist(圧縮リスト)。
これは、複数のデータを「切れ目のない一本のパンのようにつなげて」メモリ上にギュッと連続して配置する仕組みだ。

  • メリット: ポインター(矢印)をあちこちに向ける必要がないため、メモリの無駄が一切ない。CPUのキャッシュ効率も爆上がりする。
  • デメリット: 途中のデータを書き換えたり追加したりするときに、パン全体を少しずらしたり作り直したりする必要があるため、データが大きすぎると逆に遅くなる。

つまり、Ziplistは「小さいうちは最強だが、大きくなると息切れする」という性質を持っているんだ。

—

3. 変身のタイミングを決める「ボーダーライン」

「じゃあ、いつピルケースから本格的な工具箱に持ち替えるの?」という疑問が湧くよね。
その境界線を決めているのが、今回主役となる設定値たちだ。

Redisの設定ファイル(`redis.conf`)を覗くと、こんな項目が並んでいる。

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

怖がらなくていい。一つずつ、優しく分解して見ていこう。

① `hash-max-ziplist-entries` (エントリ数の上限)

  • 意味: 「ハッシュの中に、要素がいくつまでならZiplistを使っていいか」の限界数。
  • デフォルト: `512`
  • 解説: 要素の数が512個以下なら、まだピルケース(Ziplist)でいようぜ、という意味だ。これを超えて513個目の要素が入ろうものなら、Redisは一瞬で本格的なハッシュテーブルへと変身する。

② `hash-max-ziplist-value` (文字数の上限)

  • 意味: 「ハッシュの中にある一つの値が、何バイト(文字)までならZiplistに許容するか」の限界サイズ。
  • デフォルト: `64` (バイト)
  • 解説: たとえ要素数が10個と少なくても、中身の文字数が「64バイト(だいたい半角英字64文字)」を超えるような巨大な文章だったらどうだろう? 大きなデータが混ざるとZiplist全体の効率が落ちるため、このルールに引っかかった瞬間、Redisは変身を決断する。

—

4. 実務でどうチューニングすべきか?

「じゃあ、設定をめちゃくちゃ大きくして、何でもかんでもZiplistに押し込めばメモリ節約になって最強じゃん!」
……と思ったそこの君、鋭いけれど、それは危険な罠だ。

エンジニアとしての極意を授けよう。
Ziplistはメモリを節約する代わりに、CPUに少しだけ負荷をかける(データをいじるときに全体を再配置するコストがかかる)。

  • メモリを極限までケチりたい場合(IoTデバイスや、参照がメインで書き換えが少ないシステム):

この値を少し大きめに設定し、Ziplistで粘る領域を広げる。

  • スピードや同時書き込みの軽快さを最優先したい場合(超高速なカウンターや、ひっきりなしに更新が入るセッションストア):

値を小さめにし、早めに本格的な構造へ変身させることで、CPUの負担を逃がす。

基本的には、デフォルト値(Entries: 512, Value: 64)は世界中の天才たちが絶妙なバランスで導き出した黄金比なので、特別な理由がない限り、むやみにいじる必要はない。ただ、扱うデータが「やたらと文字数の長いハッシュばかり」だとか「要素数が数千個あるのにメモリが常にカツカツ」という現場に出くわしたとき、この設定を思い出すだけで、ボトルネックを華麗に解決できるようになるはずだ。

—

まとめ

ここをクリアすれば、Redisの基本はバッチリマスターできたと言っていい!

1. Redisはデータの規模や大きさによって内部構造を自動で変身させる。
2. Ziplistはメモリを極限まで圧縮するコンパクトな構造だが、大きくなりすぎると逆に苦手になる。
3. `hash-max-ziplist-entries` と `hash-max-ziplist-value` は、その「変身のタイミング」を決める重要な舵取り役である。

メモリとスピードのトレードオフをコントロールできるようになると、インフラを触るのが何倍にも楽しくなる。日々の開発で「お、いま裏側でZiplistからハッシュテーブルに変身したな」なんて想像できるようになったら、君やり手のエキスパートの仲間入りだ。

さあ、次のRedisの深淵へ、共に出発しよう!

コメント

タイトルとURLをコピーしました