見出し画像

アップローダーサービス enshared のバックエンド側の実装 〜 Part2 〜

みなさん、こんにちは!めもりー(@m3m0r7) です。
今回は私が運営している enshared (https://ensha.red/) のお話です。

以前 enshared のバックエンドの実装について Qiita に書きました。
紆余曲折あり Qiita のアカウントを削除し、作り直したため当該の記事は消えてしまいましたが、ユーザーの方からもっと詳しく知りたいというお声をいただいたので記事にさせていただきました。

enshared とは?

enshared とは次世代アップローダーを謳ういわゆるアップローダーサービスです。

私が BASE 株式会社に在籍していたころに作ったサービスの一つです。
特に拘ったのは UX と少ないリソース下でいかに効率的に回すかといったところです。

前者においてはユーザーを待たせないようにアップロードの進捗がわかる画面を用意したり、アップロードしたファイルがどういったファイルであるのかを視覚的にわかりやすくしたり ZIP ファイルの中身を予め表示することでどういったファイルが入っているのかを安心感という意味でも提供していたり E2EE を標準搭載していたり、組織ごとのファイル共有を提供しています。

画像4

今回は後者をメインにお話します。

バックエンド側の仕組み

バックエンド側については当該の記事にも書いた気がする(記憶があいまい)んですが Laravel というフレームワークを使っており、概ね下記のようなインフラ構成になっています。

画像1

何の変哲もないよくありがちな構成になっているかなと思います。

ただ、個人での運営であれば特に企業のように潤沢な資産があるわけではないので、転送量に関しては気を使っている箇所です。

インフラでいわゆるクラウドサービスを選定していないのはそういった理由で ConoHa かさくらの VPS が選択肢として上がっていましたが、リリースや設計当時、さくらの VPS の東京リージョンが枯渇していたという事情もあり、かつハムスター監視システムで使用した実績から ConoHa を今回選定しています。いずれも転送量における料金は AWS S3 のような従量課金ではなく、固定のため想定以上にコストを抑えた運営ができています。

現状、クラウドストレージの月額利用料、サーバー費用も併せて月 5,000 円もいかないレベルです。

enshared における Redis の役割

enshared で特に Redis はサービスの中核を担っていると言っても過言ではありません。

Redis でユーザー個々におけるアップロードされているファイルなどの情報を一時的に格納する場所として使用しているためです。

下図のように Redis は Cloud Storage との通信を極力減らす役割を担っています。

画像2

(MySQL についてはただひたすら保存するだけなので、スペースの都合上今回登場させてません)

enshared はアップロード処理開始と同時に即時にレスポンスを返し、クライアント側にアップロード完了後の画面の URL 削除キーを提供できるような仕組みが備わっています。

この仕組を提供するためにアップロード処理開始時に予めアップロード完了後の想定しうる情報を Redis に一定時間有効になるように書き込んでいます。

この情報をもって、ユーザー側は予め情報を得た上で別ページに遷移することが可能になりそのページで特段待つ必要がなくなるわけです。

アップロード処理が別プロセスで動いている間 Redis とアップロードの状況を同期します。アップロード完了時にはアップロード完了のフラグが立ち、この時点でデータベースへ保存されます。

一方でクライアント側からはアップロードが成功したかどうかを定期的に Laravel を仲介し Redis へ問合せ、アップロードが完了しているかどうかを確認します。これで現状のアップロードの進捗を知ることができるようになっています。

画像3

今回のフロー図には書いていないですが、実際にはログインセッションの取り扱いなども Redis に保存するようにしています。

したがって enshared で Redis は 2 つの顔を持つことになります。

1) アップロード情報を取りまとめるためのもの
2) ログインセッションを扱うためのもの

PHP と Redis 

PHP では Redis を使う際に predis か phpredis どちらを導入するか意思決定する必要がありますが enshared ではパフォーマンス面からみて phpredis を導入しています。

igbinary と呼ばれる PHP の serializer を変更するための拡張を入れると Redis のデータそのものを圧縮して保管してくれるんですが、導入を忘れてしまいました(*ノω・*)テヘ

ちなみに phpredis vs predis の記事を見る通り、パフォーマンスは歴然です。

該当の記事から Conclusion を抜粋すると

PhpRedis is faster about x6 times. Using igbinary serializer reduces stored data size about 3x times. If Redis installed on separate machines, reducing network traffic is a very significant speedup.

と書かれており、ようは PhpRedis は predis と比べて 6 倍速いかつ、 igbinary を使うと 3 倍もデータ量を減らすが可能であるということです。

predis が PHP で書かれているのに対して phpredis は redis そのものを PHP で扱えるようにしたラッパーに過ぎないので、そりゃぁ速いという話です。

PHP の拡張機能を入れられるような環境であれば断然 phpredis のほうが良いです。 Laravel においてはどちらを使っても Facade を使うことになるので、速い方を選択することに越したことはありません。

PHP と reCAPTCHA

enshared は不正アップロードを防ぐ仕組みの一つとしてユーザーの行動に対して reCaptcha v3 を使用しています。

enshared では reCaptcha 処理を必要とする行動に対して Laravel の Middleware を作っており、そこを通すようにしています。

画像5

reCAPTCHA は私の今までの経験から共通化したほうがいいです。
一箇所でしか使わないだろうと想定してハードコードすると痛い目を見ます。見ました。

enshared の現在と今後

本当は外部向けに API の実装とかしたり、機能の追加をしたりしたいんですがそんな余暇もなく、私の BASE 退職の時期や無職退職の時期、どうぶつたちのマネージメントを行わないといけなかったり、などなど紆余曲折、七転八倒、青椒肉絲などもあり、放置していました。申し訳ありません。

あと、Google Adsense が通らないのでどうしようかなと思っています。

画像6


ということで Part2 は以上です🐱


この記事が気に入ったらサポートをしてみませんか?