Upgrade to Pro — share decks privately, control downloads, hide ads and more …

その Valkey 使いこなしていますか?

その Valkey 使いこなしていますか?

2026-10-17 Kaigi on Rails 2026
https://kaigionrails.org/2026/

Avatar for Takafumi ONAKA

Takafumi ONAKA PRO

October 17, 2026

More Decks by Takafumi ONAKA

Other Decks in Technology

Transcript

  1. About Me • Takafumi ONAKA a.k.a. id:onk • From Kyoto

    • 20 years with Rails • Hatena Co., Ltd. ◦ Chief Engineer 大仲 a.k.a. id:onk です。京都から来ました。Rails歴20年になります。株式会社は てなで働いています。 2
  2. Me and KoR • KoR 2020 ◦ 「Growing Sinatra」 Presented

    online • This time, it's Valkey • I keep giving talks unrelated to Rails :) KoR 2020では「育てるSinatra」でオンライン登壇しました。今回のテーマは Valkey。Railsと関係ない登壇が続いています 3
  3. What is Valkey • A fork of Redis created in

    March 2024 ◦ Linux Foundation Launches Open Source Valkey Community • In Response to Redis's License Change ◦ 2024-03 Redis Adopts Dual Source-Available Licensing ◦ 2025-05 Redis is open source again - <antirez> Valkeyは2024-03に作られたRedisのfork。Redisがライセンス変更をしたのを受け て発足しました。Redisはその後AGPLv3になってまたOSSに戻っています。 5
  4. The Name • A twist on "key-value" ◦ It used

    to say this in the GitHub repo description ◦ A new project to resume development on the formerly open-source Redis project. We're calling it Valkey, since it's a twist on the key-value datastore. Valkeyの名前の由来はKey-Value Storeの「Key-Value」を逆に。昔はGitHubリポ ジトリのdescriptionに書いてあった。探すと痕跡があります 6
  5. Which Should You Choose? • 20-33% cheaper on Amazon ElastiCache

    • Both continue to improve in performance ◦ Forked at version 7.2; now Redis 8.10/Valkey 9.1 RedisとValkeyのどっちを使うか。Elasticacheで明らかに安いのでValkeyを使って います。forkしたのがRedis 7.2で、その後それぞれ進化している。 7
  6. Rails and Redis/Valkey • They were closely connected in the

    late 2010s • Used as job queues for async processing ◦ Required by Resque and Sidekiq • Also used for session storage and caching ◦ Redis is already there, no need to add memcached ◦ redis-session-store, RedisCacheStore(Rails v5.2) 2010年代後半は特に親密で、非同期処理のResqueやSidekiqが要求するし、セッ ションストアやキャッシュにも使う。そこにもうRedisがあるので、memcachedは 追加しないって判断をしていた。Rails本体にも入りましたね。 8
  7. Rails and Redis/Valkey • So I imagine most of you

    have used it ◦ Sidekiq is the first choice for a job queue ◦ You may have used it for caching as well • But what about using it as part of the application itself? ◦ This is today's topic! なので、みんなRedisを使ったことはありそう?Sidekiqはジョブキューとして第一 選択肢だろうし、キャッシュにも利用したことはあるんじゃないか。でも「アプリ ケーションの一部として」だとどうだろう?これが今日の話! 9
  8. Valkey's Diverse Data Structures • String, Hash, List, Set, Sorted

    Set, Stream, Bitmap, etc. • Useful for caches, counters, queues, leaderboards, message delivery, and more • Provide commands for each data structure ◦ For Sorted Sets: ranking positions, score-range queries, etc. 多彩なデータ構造で、色々な使い道があります。各データ構造向けのコマンドもあ る。Sorted Setならランキング順位とかスコア範囲検索とか。 12
  9. Sorted Set • What kind of data type is it?

    ◦ Each element have a score ◦ Elements are always ordered by score ◦ Designed for rankings, so you can look up ranks Sorted Setはこんなデータ型!各要素にスコアを持たせられて、常にスコア順に並 んでいる。ランキングとして使うのを想定していて、順位も取れる。 14
  10. Sorted Set ZADD ranking 100 user1 ZADD ranking 250 user2

    ZADD ranking 180 user3 ZRANGE ranking 0 -1 REV #=> ["user2", "user3", "user1"] ZREVRANK ranking user1 #=> 2 # 3rd place (zero-based) 15
  11. Sorted Set • Retrieve data extremely quickly ◦ This is

    where a key-value store shines ◦ Built-in support for ranking operations • Perfect for common use cases in games ◦ Frequent rank lookups among a million users ◦ It used to be an essential component in social games 爆速で、KVSの本領発揮ですね。ランキングに必要な操作がデータ構造になってい るのが効いている。ゲームで頻出する「100万人の中でユーザーが何位かを頻繁に 取得する」に最適。ソシャゲ界では必須コンポーネントでした 16
  12. Sorted Set • ZINCRBY is useful ◦ ZINCRBY ranking 150

    user4 ◦ Just call ZINCRBY on each attack to build a total-damage leaderboard ◦ Works even if the key or member doesn't exist yet ZINCRBYが便利で、攻撃時に呼ぶだけで総ダメージランキングが完成する。キーも メンバーも無くてもインクリメントできるので、箱も作らずいきなり呼ぶだけ。他 にも閲覧時に+1するとアクセスランキングができるよ 17
  13. Period-Based Leaderboards • We want daily and weekly rankings too

    • We need separate keys for each period # Daily loaderboard for 2026-10-17 ZINCRBY daily:20261017 1 article-1 # Weekly leaderboard for the week of 2026-10-11 ZINCRBY weekly:20261011 1 article-1 期間ランキング。日次や週次も欲しいよね。期間ごとにキーを分けて実装すること になる。 19
  14. Period-Based Leaderboards • The problem with weekly leaderboards ◦ The

    leaderboard resets when the week changes • Weekly Leaderboard ≠ Last 7 Days • Fixed weekly keys cannot provide a leaderboard for the last seven days 週次ランキングなんだけど、月曜になった瞬間にリセットされる。週次ランキング は直近7日間ランキングではないのだよね。固定された週次キーでは「直近7日間」 ランキングが作れない。 20
  15. ZUNIONSTORE • Combines multiple Sorted Sets into a new one

    • Scores of shared members are summed ZUNIONSTOREといういいやつがあって、複数のSorted Setのスコアを加算して新 しいSorted Storeを作るコマンド。同じ要素が複数のキーに存在すると合算になる 22
  16. ZUNIONSTORE ZUNIONSTORE dest 7 daily:20261017 daily:20261016 daily:20261015 daily:20261014 daily:20261013 daily:20261012

    daily:20261011 • That's it! `dest` now holds a Sorted Set ranked by total views over 7 days • Easily retrieve the top 10 ◦ ZRANGE dest 0 9 REV これだけで7日間の合計ビュー数に並んだSorted Setがdestに作られる。ランキン グTOP10はZRANGEでシュッと取得 23
  17. ZUNIONSTORE • For "30 days", specify 30 keys ◦ I

    usually needed calendar-month rankings, so I've never used more than 30 keys 「30日間」って要件だったら30個並べます。私の用途だと月次は月次が欲しいって 言われることが多かったので、その辺りまでしか使ったことはない。 24
  18. Sorted Set and ZUNIONSTORE • A data type designed for

    rankings • Easy to increment scores with ZINCRBY • Any time window when retrieving results • So cooool! ランキングのためのデータ型で、ZINCRBYで簡単に加算できて、取得時に必要なウ インドウをその場で指定しているの、カッコ良すぎるでしょ! 26
  19. Recency-Weighted Leaderboards • Want to prioritize recent activity ◦ Don't

    want an article that went viral 7 days ago to stay at the top • Apply exponential decay to view counts ◦ ZUNIONSTORE actually has a WEIGHTS option ランキングはなるべく鮮度を反映させたい。1週間前にバズった記事がずっと1位な のはちょっとね。指数関数的に減衰するといいはずで、なんとZUNIONSTOREには WEIGHTSオプションがある 29
  20. 直近重視のランキング ZUNIONSTORE dest 7 daily:20261017 daily:20261016 ... WEIGHTS 1.0 0.9

    0.81 0.73 0.66 0.59 0.53 • No changes to how data is stored • Adjust aggregation when retrieving data これ各キーのデータの持ち方は何も変えてなくて、取得するときにいい感じに指定 しているんですよ。良くない? 30
  21. More Use Cases for WEIGHTS • Supports weighted scoring ◦

    e.g., views *1, likes *5 ZUNIONSTORE dest 2 daily:views:20261017 daily:likes:20261017 WEIGHTS 1.0 5.0 例えばPVは*1、いいねは*5みたいな重み付けとかね 32
  22. Sorted Set Summary • Sorted Sets are ordered by score

    ◦ Increment scores with ZINCRBY • ZUNIONSTORE combines keys to create leaderboards for any time window ◦ Especially useful for windows like "last 7 days" • WEIGHTS lets you assign different weights ここまでのまとめ。Sorted Setはスコア順に並べるデータ型で、ZINCRBYで加算で きる。ZUNIONSTOREでキーを合算すると任意期間のランキングになり、「直近7 日間」みたいなウインドウ固定時に便利。WEIGHTSは重み付けもできる。 34
  23. onk/weathercock class Article include Weathercock::Scorable end # Call Article#hit increments

    the following four keys article.hit(:views) # article:views:total # all-time(no TTL) # article:views:2026-10-17-15 # hourly (TTL: 3 days) # article:views:2026-10-17 # daily (TTL: 90 days) # article:views:2026-10 # monthly (TTL: 3 years) 36
  24. onk/weathercock # All-time ranking Article.top(:views, limit: 10) # => ["42",

    "7", "133", ...] # Top article IDs by views over the last 7 days Article.top(:views, days: 7, limit: 10) # Exponential time decay (recent hits weighted higher) Article.top(:views, days: 7, decay_factor: 0.9, limit: 10) 37
  25. onk/weathercock article.hit_count(:views) # all-time article.hit_count(:views, days: 7) # => 42

    Article.hit_counts(:views, ids: [1, 2, 3], days: 7) # => {"1" => 42, "2" => 15, "3" => 7} 38
  26. onk/weathercock • ZUNIONSTORE is so elegant, but I rarely see

    it used • I use it in production, and it works well for my use case ZUNIONSTOREはこんなにカッコイイのに、使われているところをほとんど見な い。weathercockはproductionで使っていて、自分のユースケースでは満足してい る。 39
  27. Valkey Search • Valkey Search is an official module ◦

    https://valkey.io/topics/search/ ◦ Supports vector search • Find semantically similar data ◦ Generate vectors using an embedding model ◦ Search by vector distance or similarity 公式モジュールにValkey Searchがあり、ベクトル検索ができます。ベクトル検索 は、意味が近いデータを検索できるってことです。Embeddingモデルを使ってベク トルを得ておいて、ベクトル同士の距離や類似度で検索する。 41
  28. Vector Search Use Cases • Semantic Search ◦ Find data

    by meaning, not just keywords • RAG ◦ Retrieve documents relevant to a question ◦ Pass the results to an LLM • Recommendations ◦ Recommend similar articles or articles users might like ベクトル検索のユースケースは、まずセマンティック検索。単語ではなく「意味」 が近いデータを検索する。RAGは質問に関連する文書を検索して結果をLLMに渡す ヤツ。レコメンドは類似記事や好きそうな記事を推薦する。 42
  29. Trying It Out • Used `text-multilingual-embedding-002` ◦ Converts text into

    768-dimensional vectors • Stored vectors in Valkey Search ◦ Created an HNSW index for posts • KNN search with `FT.SEARCH` というわけでやってみたッス。text-multilingual-embedding-002にテキストを渡 すと768次元のベクトルを返すので、それをHNSWインデックスを作成して投稿ご とにValkey Searchに保存、FT.SEARCHでKNN検索 43
  30. Trying It Out FT.CREATE post_vec_idx ON HASH PREFIX 1 post:

    SCHEMA vector VECTOR HNSW 6 TYPE FLOAT32 DIM 768 DISTANCE_METRIC COSINE FT.SEARCH post_vec_idx *=>[KNN 10 @vector $q AS dist] PARAMS 2 q #{raw_vec} RETURN 1 dist DIALECT 2 44
  31. Works Pretty Well • Threads about "Kyoto" and "souvenirs" appear

    as similar results 「京都」「お土産」に似たスレがちゃんと類似スレとして抽出できている 45
  32. Works Pretty Well • Also useful for suggesting where to

    post ◦ Using this slide's full text as input 投稿先の推薦にも使っていて、このスライド全文を渡したら、投稿先は「プログラ ミング」パークがいいよと推薦された。 46
  33. Practical Tips • Long texts lose detail when embedded ◦

    Split into chunks and embed each separately • Too many old posts get recommended ◦ Retrieve more candidates and rerank in the application 幾つか工夫するともっと良くて、長文をベクトル化すると特徴が薄れるので、チャ ンク分割してチャンクごとにベクトル化するといいとか、古い投稿が推薦されすぎ るので、検索時は多めにとってアプリケーション側でソートとか。 47
  34. v.s. Redis • RedisSearch has been around ◦ Valkey Search

    aims for compatibility, but is a separate implementation • Redis 8 also introduced Vector Sets ◦ A new data structure for vectors ◦ Add with VADD, search with VSIM Redisには以前からRedis Searchがあり、Valkey SearchはRedis Searchとの互換性 を目指して開発している(が、内部実装は別)。更にRedis 8ではVector Setが追加 された。これはベクトルを直接扱える新しいデータ構造。 48
  35. Timelines • Social networks need timelines • Push vs. Pull

    timelines ◦ Push: Deliver posts to each user's feed ◦ Pull: Fetch and merge posts on demand • Hybrid approaches are also common ◦ Push is costly for users with millions of followers SNSを作るとタイムラインが必要になる。Push型Pull型があり、Push型は個人ごと の箱に配信、Pull型は閲覧時に投稿を集めてマージ。実際にはハイブリッド型も多 いのだけれど。極端にフォロワーが多い有名人の書き込みで破滅するので。 50
  36. Timelines • Build push-based timelines with Redis ◦ Even the

    official Redis docs have an example ◦ https://redis.io/docs/latest/develop/clients/pa tterns/twitter-clone/ • I used Sorted Sets ◦ Use timestamps as scores in per-user keys ◦ Posts stay in order despite delays, without duplicates Redisの公式ドキュメントにもPush型タイムラインの実装例がある。私は今回は Sorted Setで実装した。投稿時刻をスコアにして、個人ごとのキーに保存する。配 信が遅延しても時系列に並ぶし、重複しない 51
  37. Pub/Sub • Used by Action Cable's Redis adapter ◦ Rails

    8 defaults to DB polling with Solid Cable Pub/SubはAction CableのRedis adapterが使う。Rails 8だとSolid Cacheがデフォ ルトですね。これはDBをポーリングします。 52
  38. Geospatial • Haven't used it in prod, but worth a

    look • Valkey supports geospatial data ◦ Commands like GEOADD, GEOSEARCH, etc. • Implemented using Sorted Sets ◦ Uses Geohash (私はproductionでは使ってないんだけど)位置情報も面白い。Valkeyには位置情 報のコマンド群があり、これは内部的にはGeohashとSorted Setを使って実装され ている 53
  39. Geospatial • Geohash ◦ Encodes lat/lon into a bit sequence

    ◦ Shibuya Sta.: xn76fgr, Tokyo Sta.: xn76urx ▪ 7-character Geohashes give ~150m grid resolution ▪ Shared prefixes indicate shared grid regions • Store Geohashes as integers in Sorted Sets ◦ So Smaaart! Geohashは緯度・経度をビット列で表す手法。渋谷駅はxn76fgr、東京駅は xn76urx。7文字は150m四方のグリッドを特定できる程度の精度で、同じ接頭辞を 持つなら同じグリッドにある。これを整数化してSorted Setに入れる。あたまいい 54
  40. For Example, PostgreSQL • Leaderboards and timelines ◦ Reasonably achievable

    with proper indexes • Semantic Search -> pgvector • Geospatial -> PostGIS • Pub/Sub -> LISTEN/NOTIFY? ランキング、タイムラインはINDEXを貼っておけばまぁまぁ実現できるし、セマン ティクス検索はpgvector、位置情報はPostGIS、Pub/SubはLISTEN/NOTIFYで実 現できそう? 56
  41. Why Separate It into Valkey? • Separate system responsibilities ◦

    These are often additional features, not core functionality ◦ Leaderboards, search, geospatial • Distribute the load ◦ Frequent reads have less impact on OLTP workloads ◦ Scale independently それでもValkeyに分離すると便利で、システム境界を切り離せる。ランキングや検 索、位置情報なんかは追加機能っぽいよね。また、高頻度参照がメイン機能に影響 しないように負荷分散したい。分けると独立してスケーリングできる 57
  42. Making the Most of Valkey • What Valkey offers ◦

    Diverse data structures ◦ Fast operations tailored to each data structure ◦ Atomic execution of complex data operations ▪ Not covered today, but you can also write Lua scripts! • Why use Valkey? ◦ Easier to separate load and responsibilities from the primary data store Valkeyを使いこなすって話をした。Valkeyは多彩なデータ構造と高速なコマンドを備 えていて、アトミックな操作にしやすい。今回説明してないけどLua Scriptを書け る。そしてValkeyを活用するとメインのデータストアから負荷や責務を分離できる 59
  43. Valkey Is More Than Just a Fast Cache. It's a

    Data Processing Platform. Valkeyは単なる高速なキャッシュではなく、データ処理基盤である 60