[Redis]Redisで作る更新通知
facebookの地球(?)のアイコンを押した時に表示されるようなものをイメージ。
自分の投稿に対して、いいねがついたことを通知する。
※コード書くのがめんどうだったので、redisのコマンドで記述してあります。
前提条件・要件
- 元となるデータ(投稿、ユーザ、いいね)はRDBに管理されている
- 新着件数、新着一覧を表示できる(ソート順は更新日時の降順)
- 保持できる上限件数を99件とする(Redisのデータ容量を見積もることが可能)
- 1つの投稿に対して、複数人のアクションをまとめて表示できる(○○さん他X人に・・・のような)
登録処理
- user_id = 123の、
article_id = 234に、
user_id = 345が
2013/01/01 00:00:00(1356966000)にいいねを押したとき
→まず、既に存在しているかを確認する
HGET like:values:123 234
→emptyが返ってくるので、JSON文字列("{\"user_ids\":[345]}")を作成し、下記を実行
ZADD like:keys:123 1356966000 234 HSET like:values:123 234 "{\"user_ids\":[345]}" ZADD like:new:123 1356966000 234
- 同じ投稿に、
user_id = 456が、
2013/01/01 00:00:20(1356966020)にいいねを押したとき
→まず、存在確認
HGET like:values:123 234
→さっきのJSONが返却されるので、パースし、今回のuser_id(456)を追加する。
→そして、下記のコマンドを実行
ZADD like:keys:123 1356966020 234 HSET like:values:123 234 "{\"user_ids\":[345,456]}" ZADD like:new:123 1356966020 234
同じユーザの、
article_id = 235に、
user_id = 345が
2013/01/01 00:00:40(1356966040)にいいねを押したとき
→まず、存在確認
HGET like:values:123 235
→emptyが返ってくるので、JSON文字列("{\"user_ids\":[345]}")を作成し、下記を実行
ZADD like:keys:123 1356966040 235 HSET like:values:123 235 "{\"user_ids\":[345]}" ZADD like:new:123 1356966040 235
参照処理
- 新着の件数を取得する(user_id=123)
ZCARD like:new:123
- 更新通知を10件表示する(user_id=123)
→まず、キー一覧を取得する
ZREVRANGE like:keys:123 0 9
→取得できたキー(235, 234)について、値を取得する
HGET like:values:123 235 HGET like:values:123 234
→RDBより、投稿・ユーザの情報を取得する
SELECT * FROM article WHERE id = 235; SELECT * FROM user WHERE id = 456; などなど
- 新着更新通知を10件表示する(user_id=123)
→取得するキーが keys -> new を変えて、更新通知を10件表示するを実行する。
追記が必要なこと
- 上限件数を越えようとした場合
ざっくり書くと、下記のような感じ。
-
- 100件目以降のkeysを取得(WITHSCORES)
- そのkeyで、valuesを削除する
- keysの100件目のscore以下のnewを、ZREMRANGEBYSCOREを利用して削除する
- トランザクション処理がない
multi -> exec を利用するべきかと。
書いた後気づいた
公式にtwitter cloneのcase studyがあった。
こっちを見たほうがいいんじゃなかろうか。
http://redis.io/topics/twitter-clone