『ポケコロ』サーバーでどのようにRedisを活用していのか

こんにちは。『ポケコロ』のサーバー開発を担当しているHです。
今度はredisについての説明と、『ポケコロ』でどのように使っているかについてお話したいと思います。

私は入社する前に、リレーショナルデータベースは使う機会が多くて慣れていましたが、NoSQL、特にredisのようなキーバリューストア型データベースは初めて使うことになりました。
最初はなれなかったので適応に苦労しましたが、適応後はかなり手に合って楽に使っています。

redisとは

redisは、Remote Dictionary Serverの略で、”キー値”構造の非定型データを保存・管理するためのオープンソース基盤の非リレーショナルデータベース管理システムです。

すべてのデータをメモリに読み込んで処理するメモリ基盤のDBMSとなっており、明示的に削除・Expire を設定しなければデータは削除されない、つまり永久的に保持されるといった特徴があります。

また、性能はサーバによって異なりますが、1秒当たりにrequestを2万~10万回処理します。

まとめると、redisは

  • データリポジトリとして入力・出力が最も速いメモリを採用
  • 単純な構造のデータモデルであるKey-Value方式による速い速度
  • キャッシュ·データストアに有利
  • 様々なAPIをサポート

という特徴を持っており、NoSQLの中で注目されています。

『ポケコロ』でredisをどう利用しているのか

現在、『ポケコロ』サーバーではmariaDBとmongoDBを主に使っていますが、redisもいくつかのところで活用しています。

redisを主に使う場合は大きく分けて2つあります。

1. ランキング情報保存(すごろく、猫イベントなど)

『ポケコロ』の様々なイベントではランキングシステムが採用されています。

ランキングはリアルタイムで変動しているため、リスト型データ入力と削除がMySQLに比べて10倍ほど早いredisの方が適切です。

ランキングを集計するときに適切なデータ型にzSetというものがあります。

zSetはredisから提供しているデータ型のうち、SETに似ていながらも異なる値自体の重複を許可せずに並べるデータ型です。

例)すごろくの全体ランキング表示

// ----- 全期間のランキング
String rankingKey = "SUGOROKU_EVENT_TOTAL_RANKING_KEY_" + eventid;
redisTemplate.opsForZSet().incrementScore(rankingKey, userid, delta);
redisTemplate.expire(rankingKey, 60, TimeUnit.DAYS);

redisに全体ランキング情報を保存して、表示したい順位だけ取った後表示します。

2.通信エラー防止のためのロック


サーバ通信は様々な例外状況によりエラーが発生することが多いです。

例えばクライアントから前回のリクエスト処理が終わる前に、もう一度リクエストを送った場合に問題が発生する可能性があります。
上記の問題を防ぎたい場合にもredisを活用することができます。
例)

public void buyLock(String suffixKey, String lockVal, int timeoutSecs) {
    String lockKey = "TRADE_BUY_LOCK_KEY_" + suffixKey;    
        Boolean absent = redisTemplate.opsForValue().setIfAbsent(lockKey, lockVal, timeoutSecs, TimeUnit.SECONDS);
    if (!absent) {
        throw new Exception("ロックされています!");
    }
}

上記のように処理している間にロック設定を入れることで、短時間に2回以上処理されるエラーを防止できます。

まとめ

今回は『ポケコロ』でredis をどう利用しているのかを簡単にご紹介しました。
キー値データベースを一度も使ったことのない方が初めて挑戦するときにこの記事が参考になると幸いです。

 


 

ココネでは一緒に働く仲間を募集中です。

ご興味のある方は、ぜひこちらの採用特設サイトをご覧ください。

https://www.cocone.co.jp/recruit/contents/

Category

Tag