Salesforceから始めた人向け Heroku Redis ガイド

こんにちは！ この記事は Heroku Redis についての記事になります。

Redis に関するナレッジはこれまで様々語られてきており、
この記事の位置づけとしては**「Salesforceデベロッパが Heroku Redisを知らねばならない時に見ておくと良いよガイド」**を目指しています。

僕も細かい挙動はDevCenterを見ながら動かして、なのですが、まず概要や全体観を知るためのメモとしてご覧いただければと思います。

## Redis?

https://redis.io/

* KVS。永続化もできるインメモリデータベースと言われることもある
* KVSとしてはmemcachedと似ているけれど、データ型があるところと、非同期でディスクにもデータを書き出してくれるので再起動してもデータが揮発しないところ（≒永続化）が機能面の大きな違い

### Redis には5つの型がある

用途に応じたデータ型が用意されている

* String型
* Hash型
* List型
* Set型
* SortedSet型

どのデータ型を使うか気になったら、この記事がわかりやすい
[Redisについて各データ型と想定用途をまとめてみた](https://marunouchi-tech.i-studio.co.jp/3366/)

1つのプロジェクトで全部使うことはなかなかないですね...

## Heroku Redis?

* [Heroku Redis](https://elements.heroku.com/addons/heroku-redis) はHerokuが運用管理してくれる DaaS (Database as a Service)の Add-on
* Herokuのダッシュボードからある程度データが見れて便利

![medium.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616950/16f5f440-4185-8cab-695a-fadc595ca959.png)

## どういう時に使う？

### ■ HerokuでWebアプリ作ったときのセッション管理

* アプリケーションコンテナである **Dynoは24時間+αで自動で再起動する** ので、保持したいデータは必然PostgresなりRedisなりで抱えてあげる必要がある

### ■ 大量データを捌くためのKafkaとの併用、あるいはPostgresの前段として

このケースは少なめ

* Redis + Kafka
  * 先日 Salesforce による Slack の買収の話が持ち上がりましたが、Slackのバックエンド（ジョブキュー）も KafkaとRedisで構成されていたと思います。大量データをHerokuで面倒見なきゃいけないケースのときは、どちらかと言うと Heroku Kafkaメインで組むことが多いかなという印象
* Redis + Postgres
  * 大量の照会処理が入るケースで、Postgresの前段に起きつつPostgresのFDWで繋ぐパターン。いわゆる [Heroku Data Links](https://devcenter.heroku.com/ja/articles/heroku-data-links)の出番ですが、redis_fdw（Redis連携）は [今日時点で、DevCenterでは非推奨](https://devcenter.heroku.com/ja/articles/heroku-data-links#linking-heroku-redis-to-heroku-postgres) となっているみたいです

### ■ リアルタイムランキングやソート済みリストの利用

SortedSet型を使うとランキングやソート済みリストを作るのに便利です

* 競争要素のあるゲームでランキングを表現したり
    * [今更Redisのsorted set を知ってリアルタイムランキングの実装が超楽だった件](https://qiita.com/niisan-tokyo/items/170ef3ac47ee39cfb46c)

* CRM界隈だとこういうケースが考えられるかもしれない
  * 「直近10ユーザが最後に見た記事」
  * 「指定した緯度経度の近所にあるお店の口コミを表示」

特に後者のようなコミュニティサイトの要件の場合、ライセンス費用や制約によって SalesforceのExperience Cloud（Community Cloud）とHerokuのどちらを使うかがソリューションの1つになることがあるのですが、Herokuを使うならばおそらく上記のようなケースでRedisが活用するかな、と思います

## Heroku Redisの概要をよく知りたい

[Partner Base Camp / Heroku](https://jppartner.force.com/basecamp/s/article/Heroku)
![スクリーンショット 2020-12-16 12.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616950/d4cdba21-09c6-ccd1-c9c5-a738366308f2.png)

* Salesforce公式 Partner Base Campで永野さんがまとめてくれているまとめから「Heroku Redis 概要」資料を参照しよう
* ここは本当に良コンテンツの山

あとはざっとよくまとまった記事としてはuskさんのこの記事
[Heroku Redisについてまとめてみた](https://qiita.com/usk/items/f240b781cf0fdbeacdf9)

書かれている中で、運用面では

1. メンテナンスウインドウ
2. メモリ容量オーバー時の挙動

この2つを特に抑えておけばいいかなと思います

## メンテナンスウインドウ

メンテナンスウインドウとは、時間をこちらで指定することのできるパッチ適用のこと
[Heroku Redis のメンテナンスウィンドウ](https://devcenter.heroku.com/ja/articles/heroku-redis-maintenance)

Postgres と Redis は設定をしておくと予期せぬタイミングでのメンテナンスが生じるリスクが減るので設定しておくと良いです

[Heroku Redis / Heroku Postgres メンテンナンスの仕組み](https://qiita.com/mikakane/items/35e8022c7d1100da16d4)

ピンと来た人もいるかもしれませんが AWS のメンテナンスウインドウのこととほぼ同じ（HerokuはAWSをバックエンドで利用していて、Postgres/RedisもEC2の上に載っているはず）

ただし基本的にHerokuのメンテナンスウインドウの指定はコマンドライン
（AWSならSystems Managerからコンソールで行けるけど...）

Heroku CLI経由で

```heroku redis:maintenance --window="Sunday 14:30"```

とすればOK

なお、メンテナンスウインドウは予期された定常的なメンテナンスの場合の時間帯指定の話なので、突如発生する予期せぬメンテナンスの場合はその場で障害対応が必要です

### Eviction Policy (メモリ容量オーバー時の挙動)

こっちは注意が必要。

* メモリ容量オーバー時の挙動とは、指定したHeroku Redisインスタンス上のメモリの容量が迎えたときの挙動の話
* Heroku の初期設定/デフォルトだと ```noeviction``` 。つまりメモリ容量溢れ時に何もしない状態。つまりメモリ容量でエラーが起きて動かないケースがあるということ。システム全体がコケることに繋がる

参考：本間さんの [Heroku Redis は初期設定で利用してはならない](https://www.bokukoko.info/entry/2015/09/05/Heroku_Redis_%E3%81%AF%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%AF%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84)

僕も実際こうなってしまったケースは無いのですが、こればっかりは気づいてからの対処がとても面倒なので、先に知っておくしかないですよね。。

### Heroku Redis の Maxmemory Policy / キャッシュアルゴリズム一覧

[maxmemory-policy一覧](https://devcenter.heroku.com/ja/articles/heroku-redis#maxmemory-policy)

```​
​noeviction​ - メモリ制限に到達したときにエラーを返します。
​allkeys-lru​ - 最後に使われてから最も長い時間が経過したキーを最初に削除します。
​volatile-lru​ - 有効期限が設定されている、最後に使われてから最も長い時間が経過したキーを最初に削除します。
​allkeys-random​ - ランダムキーを追い出します。
​volatile-random​ - ランダムキーを追い出しますが、有効期限が設定されているものに限られます。
​volatile-ttl​ - 有効期限が設定されていて TTL が短いキーのみ追い出します。
​volatile-lfu​ - 有効期限が設定されているキーの中から概算 LFU を使用して追い出します。
​allkeys-lfu​ - 概算 LFU を使用していずれかのキーを追い出します。
```

アプリでの用途次第だけど volatile-lru を指定しておくのが定石かと

### Maxmemory policy のチェックポイント

1. Maxmemory Policyを変更しておこう（Herokuのデフォルトが変わらない限り）
2. そもそもだけどキーのTTLは設定しよう
3. 本番稼働時にリリース作業漏れしやすいのでどの環境でも設定済みかは必ず確認しよう

（Heroku Enterprise であれば最初に全App、全Addonを入れておくのもありなのですが、結局実装中にもろもろ設定を調整するので、結局最後は人の目が必要）

## プランの考え方

どのプランにするかで見るのはここ

* [Heroku Redis](https://elements.heroku.com/addons/heroku-redis)
* [パフォーマンス特性](https://devcenter.heroku.com/ja/articles/heroku-redis-technical-characterization)

Premium-0かPremium-1 で済んでしまうことが多い
体感、非PS環境におけるProductionの7割はPremium-0で何とかなってるイメージ
（Heroku Redisは結構低めのPlanからそこそこの性能が用意されている）

ただし本番PrivateSpacesの場合Add-on消費はまあまあいってしまうので
↓のDynoの例のように最初にDevStarterPackの使いみちやアップセルなど想定しておくと良い

[Partner Community - Heroku案件を手掛けるときに知っておきたいこと](https://partners.salesforce.com/0693A000006ohUK)
（過去登壇資料）

柔軟にプラン変更できるのもHerokuの強みだけど、セオリーとか考え方のベースはあった方が良い

## Heroku Postgres と Heroku Redis

* 2大DataService公式Addonと言えるけど前者はRDBMS、後者はKVS。用途が異なるのでそれぞれ違いを捉えておく
* なお SFプロジェクトで、Heroku Connect周りでよく話題に上がるのは Postgresの方

## Namespace？

* 強いて言えばたまに namespace を使うことがあるかも
  単に値を保存するだけじゃなくて namespaceをキーに付与することで、これはマイページ用、これはEC用という分類に使えたり、Staging環境や調査環境などでnamespaceを分けて、ちょっと込み入った使い方ができたり

ただし1つのRedisインスタンスに複数環境、複数プロジェクトのデータが保管されるのは
[The Twelve factor App](https://12factor.net/ja/)に照らすとあんまりよくないかもしれない

## Heroku をもっと学ぶには

### 1. DevCenter

まずは手を動かして、というのもあるけど Dev Centerがゆりかごから墓場まで
https://devcenter.heroku.com/

![スクリーンショット 2020-12-16 12.57.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616950/9ea78307-14ef-a167-3e73-20889d4bbe28.png)

最近DevCenterが日本語対応のアナウンスがありました。
対応しているページは日本語へ切り替えることができ、Google/DeepL両先生のお力を借りずとも読みやすくなっています
（日本語対応の件、本当にお疲れさまでした。）

### 2. HerokuのAdvent Calendar
今年は密を避けた形になってしまっているけど毎年良記事がたくさんデプロイされているので、追ってみるだけでも良いかも知れない

https://qiita.com/advent-calendar/2020/heroku
https://qiita.com/advent-calendar/2019/heroku
https://qiita.com/advent-calendar/2018/heroku
https://qiita.com/advent-calendar/2017/heroku
https://qiita.com/advent-calendar/2016/heroku
https://qiita.com/advent-calendar/2015/heroku

### 3. Partner Base Camp

https://jppartner.force.com/basecamp/s/article/Heroku

本当に良いサイト

### 4. ユーザグループのSlack

https://twitter.com/kimihom/status/972449537271873537

ちなみにHeroku ユーザーの Slack グループがあります。
newsとか全体的に濃い話はこちらで

## 最後に

普段そこまでニーズ出てこなくても必要になったら急に調べないといけないので、
そのときはこの記事から各ナレッジやHerokuアーキテクト/デベロッパの皆さんの元へ飛んでいただければ幸いです。

それでは