Skip Navigation
Show nav
Dev Center
  • Get Started
  • ドキュメント
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • ドキュメント
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Heroku Blog

    Find out what's new with Heroku on our blog.

    Visit Blog
  • Log inorSign up
View categories

Categories

  • Heroku のアーキテクチャ
    • Dyno (アプリコンテナ)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • スタック (オペレーティングシステムイメージ)
    • ネットワーキングと DNS
    • プラットフォームポリシー
    • プラットフォームの原則
  • Developer Tools
    • コマンドライン
    • Heroku VS Code Extension
  • デプロイ
    • Git を使用したデプロイ
    • Docker によるデプロイ
    • デプロイ統合
  • 継続的デリバリーとインテグレーション
    • 継続的統合
  • 言語サポート
    • Node.js
      • Working with Node.js
      • Node.js Behavior in Heroku
      • Troubleshooting Node.js Apps
    • Ruby
      • Rails のサポート
      • Bundler の使用
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Python でのバックグランドジョブ
      • Python Behavior in Heroku
      • Django の使用
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Maven の使用
      • Spring Boot の使用
      • Troubleshooting Java Apps
    • PHP
      • PHP Behavior in Heroku
      • Working with PHP
    • Go
      • Go の依存関係管理
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • データベースとデータ管理
    • Heroku Postgres
      • Postgres の基礎
      • Postgres スターターガイド
      • Postgres のパフォーマンス
      • Postgres のデータ転送と保持
      • Postgres の可用性
      • Postgres の特別なトピック
      • Migrating to Heroku Postgres
    • Heroku Data For Redis
    • Apache Kafka on Heroku
    • その他のデータストア
  • AI
    • Working with AI
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • AI Models
      • Inference Essentials
    • Vector Database
    • Model Context Protocol
  • モニタリングとメトリクス
    • ログ記録
  • アプリのパフォーマンス
  • アドオン
    • すべてのアドオン
  • 共同作業
  • セキュリティ
    • アプリのセキュリティ
    • ID と認証
      • シングルサインオン (SSO)
    • Private Space
      • インフラストラクチャネットワーキング
    • コンプライアンス
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Team
    • Heroku Connect (Salesforce 同期)
      • Heroku Connect の管理
      • Heroku Connect のリファレンス
      • Heroku Connect のトラブルシューティング
  • パターンとベストプラクティス
  • Heroku の拡張
    • Platform API
    • アプリの Webhook
    • Heroku Labs
    • アドオンのビルド
      • アドオン開発のタスク
      • アドオン API
      • アドオンのガイドラインと要件
    • CLI プラグインのビルド
    • 開発ビルドパック
    • Dev Center
  • アカウントと請求
  • トラブルシューティングとサポート
  • Salesforce とのインテグレーション
  • アプリのパフォーマンス
  • Memcache を最大限に活用する

This article was contributed by The MemCachier Add-on

MemCachier manages and scales clusters of memcache servers so you can focus on your app. Tell us how much memory you need and get started for free instantly. Add capacity later as you need it.

follow @MemCachier on Twitter

Memcache を最大限に活用する

日本語 — Switch to English

最終更新日 2020年06月12日(金)

Table of Contents

  • 前提条件
  • テスト環境
  • 対話型シェル
  • キャッシュの期限切れ
  • キャッシュのクリア
  • 軽量カウンター
  • リスト管理
  • スレッドセーフセット
  • リファレンス

ほとんどの本番 Web サイトで頼りになるスケーリングソリューションであるにもかかわらず、Memcache が、その潜在能力を十分に発揮できる使われ方をしていない場面はよくあります。ほとんどの開発者は get​、set​、delete​ 操作のことしか理解していません。しかし Memcache には、より広範な一連の操作が用意されており、それらは開発者が、より高度なアプリを、より少ないコードで、パフォーマンスも向上させた上で構築するために役立ちます。

この記事では、一連の現実的なユースケースを通じて、さらに役立つ高度な Memcache 操作の概要を示し、アプリの実装とパフォーマンスにそれらの操作が及ぼす影響を示します。

前提条件

この記事は、次のものが用意されていることを前提としています。

  • Heroku アカウント。無料ですぐにサインアップできます
  • Heroku CLI​ がインストールされていること。
  • Memcache の基本的な知識があること。

テスト環境

次の Rails アプリを Heroku にデプロイすることから始めます。 ​ソースコード​または [Heroku にデプロイ] ボタン

これにより、MemCachier アドオン とシンプルなコマンドラインを備えたサンドボックス環境が用意され、高度な Memcache 操作を自分自身で実行できるようになります。 説明を読むだけでなく実際にコマンドを入力してみると、コマンドの構文や機能の理解が深まります。

テストアプリのコピーが、ご使用の Heroku アカウントにデプロイされました。 新しいアプリの URL をメモしてください。これは http://serene-mesa-2821.herokuapp.com/​ のような形式で、serene-mesa-2821​ は Heroku 上のアプリケーションの名前です。この名前は、対話型シェルを確立するために必要です。

対話型シェル

ターミナルから heroku run console​ を実行し、アプリ名を指定して、Heroku で実行されているアプリのインスタンスに接続します。Memcache クライアントライブラリをロードし、基本的な set​ および get​ コマンドを実行して設定を確認します。

$ heroku run console -a app-name
irb> cache = Dalli::Client.new
irb> cache.set("foo", "bar")
=> true
irb> cache.get("foo")
=> "bar"

この例では、対話型 Ruby シェルと Dalli クライアントを使用して Memcache をロードし、Memcache と対話しています。これは単に例示目的であり、 どの言語の Memcache ドライバーも同様のコマンドが サポートされます。

このガイドではこれ以降、このシェルが実行され、クライアントライブラリがロードされていることを前提に説明を進めます。

キャッシュの期限切れ

Memcache を使用するときの最大の課題は、キャッシュが古くなるのを回避しつつ、記述するコードのクリーンさを保つことです。ほとんどの開発者は、データを Memcache に保存し、変更があったときにデータを削除または更新します。この戦略は、アプリケーション全体が Memcache 関連のコードだらけになって早々に破綻する可能性があります。Rails では Sweepers​ によって この問題を解決できますが、他の言語やフレームワークには同様の代替策がありません。

コードの複雑さを回避するシンプルな戦略の 1 つは、有効期限を付けて Memcache にデータを書き込むことです。有効期限のあるデータは、期限が来ると自動的に期限切れになります。ほとんどのアプリケーションで、静的アセット、ヘッダー、フッター、ブログ投稿などの頻繁に変更されないコンテンツには、時間ベースのキャッシュ有効期限が効果的です。

サンドボックスシェルで、次のコマンドを実行して、10 秒後に期限切れになる値を設定します。

有効期限を “0” に設定すると、値は期限切れになりません。

irb> cache.set("expires", "bar", ttl=10.seconds)
irb> cache.get("expires")
=> "bar"
.. wait 10 seconds ..
irb> cache.get("expires")
=> nil

特定のコンテンツを明示的に期限切れにするためにアクションが不要であることがわかります。ttl​ 値で指定された時間の経過後は、キーを get​ しても nil の結果が返されるだけです。

秒数で指定された有効期限が 30 日以上に相当する場合、 Memcache では、指定された秒数を Unix エポック日付に変換することによって、 有効期限を絶対的な日付として扱います。40 日を秒数で指定すると、 有効期限が 1970 年の日時に設定されて予測不能な結果を 発生させるため注意してください。

キャッシュのクリア

新しいキャッシュコードを記述する過程で、開発者がキャッシング戦略を何回となく変更することはよくあります。キャッシュ戦略の拙速な変更により、ダーティキャッシュが生成されてデバッグが困難になります。開発中にキャッシュ戦略を変更するたびに、flush​ コマンドを Memcache に発行して、すべての値のキャッシュをクリアするようにしてください。

サンドボックスコンソールで、次のコマンドを実行してフラッシュをテストします。

irb> cache.set("foo", "bar")
irb> cache.get("foo")
=> "bar"
irb> cache.flush
irb> cache.get("foo")
=> nil

flush​ は本番環境へのデプロイ時にも使用できます。ただし、アプリケーションがキャッシュフラッシュに対応できない場合があるので注意してください。キャッシュを多用する高トラフィックのアプリケーションでは、本番環境で flush​ を 発行しないか、キャッシングなしでも処理できる程度にトラフィックが少ないときにのみ発行することをお勧めします。

MemCachier Heroku アドオンには、開発者の代わりにフラッシュコマンドを発行できる Web ダッシュボードがあります。MemCachier ダッシュボードにアクセスするには、 Heroku ダッシュボードからアドオンをクリックするか、CLI から heroku addons:open memcachier を実行します。

軽量カウンター

Memcache に保存される軽量のカウンターは、アプリで特定のイベントが発生する頻度を、アプリのパフォーマンスを低下させずに追跡するために役立ちます。カウンターはデバッグ、プロファイリング、使用状況追跡に使用できます。

たとえば、サードパーティの API に依存するアプリでは、サードパーティの API が利用不能になったり、正しくないデータを返したりする頻度を把握することが必要な場合があります。Memcache カウンターは、ページのロード時間にほとんど影響せず、データベースの負荷を増やすこともないため、理想的なソリューションです。

サンドボックスコンソールで、次のコマンドを実行して incr​ (インクリメント) と decr​ (デクリメント) をテストします。

irb> cache.incr("my_counter", 1, nil, 0)
irb> cache.get("my_counter")
=> "0"
irb> cache.incr("my_counter")
irb> cache.get("my_counter")
=> "1"
irb> cache.incr("my_counter", amt=5)
irb> cache.get("my_counter")
=> "6"
irb> cache.decr("my_counter")
irb> cache.get("my_counter")
=> "5"

incr​ および decr​ は、get​ と set​ による手動での変更よりも優先して使用してください。incr​ および decr​ はスレッドセーフであり、必要な TCP ラウンドトリップも少なくなるからです。incr​ の引数の説明は、Dalli のドキュメント​を参照してください。

リスト管理

Memcache に保存される単純なリストは、正規化されていない関係の管理に役立つことがあります。たとえば、e コマース Web サイトで、最近の購入の小さなテーブルを保存したい場合があります。シリアル化されたリストを Memcache に保持し、新しい購入が行われたときにリストを再計算する代わりに、append​ と prepend​ を使用して非正規化データを保存し、データベースクエリを回避することができます。

従来の set​ 操作を使用して顧客の最近の購入のリストを更新する代わりに、次のようにします。

cache.set("user_1_recent_purchases", Purchases.recent)

prepend​ は新しいデータにしか使用できませんが、効果は同じです。

cache.prepend("user_1_recent_purchases", product.name + "||")

このアプローチにより、Memcache のフットプリントが削減され、ユーザーの最近の購入をすべて取得するデータベースクエリが回避されます。

サンドボックスコンソールで、次のコマンドを実行して append​ と prepend​ をテストします。

ttl=0​ はキーの有効期限がないことを示します。:raw => true​ は、 値が raw バイトとして保存されることを指定します。これは、append​ と prepend​ を使用するために必要です。

irb> cache.set("my_list", "foo", ttl=0, options={:raw => true})
irb> cache.get("my_list")
=> "foo"
irb> cache.prepend("my_list", "bar||")
irb> cache.get("my_list")
=> "bar||foo"
irb> cache.append("my_list", "||baz")
irb> cache.get("my_list")
=> "bar||foo||baz"

この例では、任意の区切り文字 (||) を使用しています。区切り文字は、 リスト項目に区切り文字列が含まれることがないよう、リスト内の 各項目の期待される値に基づいて選択する必要があります。 さらに、アプリケーションによっては、固定長文字列の実装のほうが適している 場合があります。

append​ と prepend​ はスレッドセーフなため、get​ と set​ による手動での変更よりも優先して append​ と prepend​ を使用してください。

Memcache でサポートされる値の最大サイズは 1 MB です。値のサイズの 許容上限を超える可能性があるリストを作成しないよう注意して ください。Dalli などの一部のクライアントでは圧縮がサポートされています。Dalli では、 Dalli に接続するときに :compress​ オプションを true​ に設定します。

スレッドセーフセット

Memcache に保存される単純な JSON ハッシュは、頻繁にアクセスされる設定の管理に役立ちます。たとえば Web サイトで、どの機能が現在有効になっているかや、どの AB テストが実行中であるかを追跡することが必要な場合があります。多くの場合、都合の良いことに、これらの設定は JSON ハッシュにまとめて保存されます。

ハッシュは順序付けがされないため、append​ と prepend​ は JSON ハッシュには使用しません。また、JSON ハッシュに対する 2 つの変更を同時に行うと片方の変更が失われる場合があるため、set​ は危険です。

cas​ 演算子を使用した比較とスワップでは、元の値を新しい値と比較し、古い値が別のライターによって変更されていない場合にのみ値を入れ替えます。言い換えれば、cas​ はスレッドセーフな set​ です。

サンドボックスコンソールで、次のコマンドを実行して cas​ をテストします。

この例の cache.cas​ では、Ruby Memcache クライアントとして 選択した Dalli の要求どおり、ブロックを期待します。他のクライアントでもこのアプローチが 通用するとは限りません。

irb> cache.set("my_json", "{}")
irb> cache.get("my_json")
=> "{}"
irb> cache.cas("my_json") { {key: "val"}.to_json }
irb> cache.get("my_json")
=> "{\"key\":\"val\"}"

Memcache プロトコルは、cas​ 操作を直接実装するわけではありません。 代わりに、バージョン番号付きの set​ をサポートします。この場合の set​ は、 Memcache に保存されているキーのバージョンとバージョン番号が一致する 場合にのみ実行されます。プロトコルで直接 cas​ を実装する代わりに バージョンを使用することで、古くからの ABA 問題に対処します。

クライアントによっては、バージョンを set​ に渡して cas​ を手動で実装することが必要な場合があります。

リファレンス

次に示すのは、この記事で扱った Memcache の各操作のクイックリファレンスです。API はクライアントおよび言語ごとに異なるため、API の詳細は示していません。

​操作 ​説明
​有効期限付きで設定 ​秒単位の有効期限付きでキーと値を設定します。有効期限が切れたキーはキャッシュから削除されます。30 日までの有効期限は現在時刻からの時間として解釈される一方、30 日以上の有効期限は Unix の絶対日付として解釈されます。
​フラッシュ ​すべてのデータをキャッシュから削除します。本番環境でのこのコマンドの使用には注意が必要です。空のキャッシュがデータベースに負荷をかけすぎると、本番環境アプリでダウンタイムが発生する場合があります。
​インクリメント ​指定された数だけ整数値をインクリメントします。スレッドセーフ。
​デクリメント ​指定された数だけ整数値をデクリメントします。スレッドセーフ。
​アペンド ​値の末尾に追加します。一部のクライアントでは、元の値が raw バイトとして保存されている必要があります。スレッドセーフ。
​プリペンド ​値の先頭に追加します。一部のクライアントでは、元の値が raw バイトとして保存されている必要があります。スレッドセーフ。
​CAS (またはバージョン付きの設定) ​値が別のプロセスによって変更されていないことを条件に、新しい値を設定します。スレッドセーフ。

関連カテゴリー

  • アプリのパフォーマンス
定期的なジョブとカスタムクロックプロセス Worker dyno、バックグラウンドジョブ、キューイング

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices