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

RedisとGoで実装するリアルタイム通知 / Real-time notification developed by Redis and Go

RedisとGoで実装するリアルタイム通知 / Real-time notification developed by Redis and Go

hiroki.saito

January 18, 2019
Tweet

More Decks by hiroki.saito

Other Decks in Technology

Transcript

  1. RedisとGoで実装する
    リアルタイムPUSH

    View Slide

  2. View Slide

  3. 用語解説
    Radiotalk
    収録型の音声配信/聴アプリ
    番組
    ユーザーごとのラジオ番組
    トーク
    配信された音声
    クリップ
    お気に入り
    メッセージ
    Redisのメッセージ
    Notification
    FCMのメッセージ

    View Slide

  4. なにをつくったのか
    クリップしている番組に投稿があったら通知するシステム
    トーカー
    リスナー
    リスナー
    トークを投稿
    Notification

    View Slide

  5. なにを解決したかったのか
    ニアリアルタイム
    - 投稿後すぐに通知したい
    - 投稿後に対象ユーザーにできる限り同時に届けたい
    仕組みで事故を防止する
    - ☓ 気をつけて実行する ○ 仕組みで事故防止
    - 基本はDryRun
    - 重複送信/実行を防止する

    View Slide

  6. システム概要
    API Redis
    ワーカー
    Go
    CHAN
    NEL
    投稿

    View Slide

  7. なぜRedisなのか
    今回はストリーム処理が不要
    シンプルで高速なメッセージングキュー
    社内での実績がある
    PHPとGoに優秀なライブラリがある

    View Slide

  8. 超簡単!RedisのPublishとSubscribe
    Subscribe
    SUBSCRIBE {チャンネル名}
    subscription := client.Subscribe("TALK_POSTED_CHANNEL")
    Publish
    PUBLISH {チャンネル名} {メッセージ}
    $this->redis->publish($channel, $message);

    View Slide

  9. なぜGoなのか
    並列実行を簡単にできる
    FirebaseAdminSDKがある(もちろんCloudMessagingSDKも)

    View Slide

  10. Goによるワーカー
    1. メッセージの受信
    2. メッセージのパース
    3. メッセージからNotificationに必要な情報をDBから取得
    4. Notification内容を作成
    5. FCMでNotification送信

    View Slide

  11. Goでの構成
    Reciver Invoker
    Sender
    Repository

    View Slide

  12. 送信の並列処理
    go func(to string, title string, body string, data
    map[string]string) {
    workersChanel <- struct{}{}
    // この呼び出し先が実際にNotificationを送信する
    invoker.Sender.Send(to, title, body, data)
    <-workersChanel
    wg.Done()
    }(device.Token, title, body, data)

    View Slide

  13. 重複実行/送信を防ぐ工夫
    ワーカーはメッセージを受け取ったら問答無用で送信する
    ただし本番環境以外はDryRun
    ワーカーを1つであること => Subscribeが1であること
    Subscribeが1 => 重複実行ではない保証

    View Slide

  14. 実行パフォーマンス
    並列(秒) 直列(秒)
    100通 2.39 23.51
    1000通 23.16 231.40
    10000通 233.37 2308.81
    並列実行の最大数は 10に設定

    View Slide

  15. 今後の展望

    View Slide

  16. まとめ
    RedisとGoで実現するリアルタイム通知
    数千の規模であればワーカー1つでも実用性はある
    規模によりますが、このシンプルな構成は実装も楽でオススメ

    View Slide