アプリを高速化するためにキャッシュについて考えてみる
そもそもなぜキャッシュが大事なのか
本当に恥ずかしい限りなのですが、今までキャッシュ・セッション・クッキーについてよくわかっていませんでした。(クッキーなんてiphone使っているだけでもよく出てくるのに...恥ずかしい)今回、AWSのEC2で運営しているサーバーの冗長化を考える際にどうしてもキャッシュなどについてしっかりした理解が必要だと感じました。そして、アルバイトをしている会社の社長の知人にとても詳しい方がいたので1日かけてサーバーの冗長化を教わりました。
キャッシュ (cache)とは
キャッシュとは、使用頻度の高いデータを高速な記憶装置に蓄えておくことにより、いちいち低速な装置から読み出す無駄を省いて高速化すること。また、その際に使われる高速な記憶装置や、複製されたデータそのもののこと。
引用: キャッシュとは|cache|キャッシング|caching − 意味 / 定義 / 解説 / 説明 : IT用語辞典
すごくまとめてしまうとアプリに関する"速さ"に影響します。キャッシュがあると、次回以降のアクセスに備えておくことにより次回アクセスした時に早くページを表示したりすることができます。リクエストされたコンテンツを保存し、再利用することによって高速化します。
私が開発で使っているrailsではキャッシュはファイルに書き込みそれを参照しています。そのためSQLなどがたくさん発行され、後述するRedis(No SQLデータベースの一種)にキャッシュを残すよりも速度が落ちてしまいます。さらに今回、教えていただいたサーバーの冗長化ではサーバーを二台設置してエンドユーザーにはどちらに接続していても、キャッシュやセッションが存在していなくてはならないためRedisを使いサーバーの外に置く必要がありました。
セッションとは
接続/ログインしてから、切断/ログオフするまでの、一連の操作や通信のこと。
例えばamazonでお買い物をする場合を考えます。
ログインする
欲しいものを検索する
カートに入れる
クレジット会計をする
完了
なるわけです。(ページの移動がもっと細かくあります。)
ですが、一回ログインしたらその後の操作はログイン情報は保持したまま操作したいですよね?欲しいものを検索して、リストが出てくるときに再びログイン画面が出てきたらもう買い物をやめたくなります。一回ログインしたら1~4までの操作はもちろんログインなしで操作したいわけです。そんなときに活躍してくれるのがセッションです!これによってログイン情報を記録してくれることによってユーザーは同一ユーザーとして操作ができるわけです。たまに見かける"セッションが切れました"という表記は長時間操作しないためにログイン情報がなくなりましたよということを指すわけです。
通常アプリではセッションを記録しておく場所があり、今回はこれまたRedisで管理することによってサーバー二台で運営しても矛盾が出ないことになります。
クッキーとは
キャッシュでは具体的にはwebページのコンテンツを保存しておくのですが、クッキーではユーザーの個人情報などを保存しておくものです。
ふたたびamazonで買い物をする場合を考えると、 以前にamazonで買い物をしたことがあるときにクレジット情報や住所などが自動で記入されていることがあったりしますよね!(もちろんログイン画面もそうなのですが)ログインボタンを押したらいきなり以下のようになっているのを見たことがあるはずです!
これはクッキーのおかげなんですね。クッキーを残すことによって、次回以降面倒な個人情報の入力をしなくて済むわけです。そんな便利なクッキーですが、なりすまし格好の餌食になることがあるので注意が必要です。
セッションハイジャック[編集] クッキーでセッション管理を行う場合、もし第三者がセッションIDを知ることができれば、そのIDを名乗ることで本来のユーザになりすますことができる。このような「なりすまし」行為をセッションハイジャックと呼ぶ。 例として、以下のような通信を行うシステムがあるとする。 トップページでユーザIDとパスワードの入力を求める。 認証に成功するとサーバはセッションIDを割り当て、クッキーとしてクライアントに通知する。 クライアントは以降の要求にクッキーとしてセッションIDを付加する。サーバは対応するセッション情報にアクセスし、どのユーザであるか識別する。 もし第三者がセッションIDを知ることができれば、そのセッションが有効な間だけとはいえ、1~2を飛ばして3から開始することができる。すなわち、パスワードを知らなくても「なりすまし」が可能となる。
クッキーでセッション管理をする際にはアプリの通信でHTTPSを使うべきなんですね。
最後に
いかがだったでしょうか?サーバーの冗長化については記事が長くなってしまったため、別記事で書きたいと思います。間違っていることを書いていたら是非、コメントをお願いします!!
シェルとシェルスクリプトの違いについて
今まで"シェル"や"カーネル"など特に気にせずにここまでコーディングやアプリ開発をしてきましたが、いい加減しっかりと学ぶ時が来たようです。なぜなら、現在aws ec2上のmysqlサーバーのデータをバックアップする際に毎日手動でmysqldumpコマンドを打ってバックアップを取るのは面倒であるからだ。できれば自動でバックアップをとり、特定の場所に(特定の時間に)保存しておいて欲しいといった気持ちに駆られてきた。色々調べるとどうやら"シェルスクリプトというものを書くといいよ"という記事をたくさん見かける。『”シェルスクリプト?”........。それって"シェル"と呼ばれるものですか?』なんて混乱していた私がネットで勉強したことを備忘録としてまとめる。
そもそもシェルとは何なのか?
普段私たちの使っているPCにはOSと呼ばれるものが入っていることはどんな人でも知っていると思う。OSは鉄の塊の箱であるPCが計算機をとして機能するための一種の人格のようなものである。私たちはそのOSという人格を持ったPCに命令することによって色々な機能を使うことができる。(ex. PCでwebサイトを見たり、アプリケーションを動かしたりなど)そしてPCを動かしてくれるOSの中にはカーネルという中心人物がいるのである。カーネルだけではOSはPCを動かすことができないが、とても需要な要素である。(サッカーで言う司令塔かな?) では私たち人はどんな方法でOS(カーネル)に命令をしているのだろか?もちろんだがOS(カーネル)に対して日本語などの言語を使って命令しても動くはずがない。日本語が通じないのであれば通訳がいれば良いのではないだろうか。そこで登場するのが"シェル"である。シェルとはカーネルに対して人が命令するための手段を提供してくれる存在であると言える。ここで具体例をあげたいところであるが、私が勉強の際にとてもお世話になったサイトがあるのでそちらを参考してもらいたい。
このサイトによると、
まぁ「シェル」って単語が出てきたら「人間の入力をコンピュータに伝えるプログラムなんだな~」と、お考えください。
引用: シェル (shell)とは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
なんとも簡単な説明であるが、とてもわかりやすい。私たちはカーネルと直接やりとりができないためシェルという存在が必要でカーネルとのやりとりを取り持ってくれるのである。次章ではシェルの具体的な処理について書いていきたいと思う。
シェルの機能とは
シェルの一番基本的な機能として、コマンドインタプリタの機能があります。これには、次の動作が含まれます。
ユーザにコマンド入力を促すためのプロンプト (prompt) を表示する。 キーボードから入力された文字列(コマンド)の解釈を行う。 コマンドとして入力された名前のプログラムを探し出して起動する。
引用: シェルの概念と機能
まさに先ほど述べた受付のお姉ちゃんのようなことをしていますね。そして、以下の文章も興味深いです。
ls コマンドや cp コマンドなどは、C言語で書かれコンパイルされたプログラムです。プロンプトで ls と打てば、ls というプログラムファイル(実体は /bin/ls )を検索して起動します。中には pwd コマンドや cd コマンドのように、独立したファイルでなくシェル内部に組み込まれたコマンド(シェルコマンド)もあります。それらはインタプリタの解釈の時点で組み込みのコマンドとして認識して対応する処理を行います。
引用: シェルの概念と機能
普段使い慣れていて気にしていなかったlsコマンドは実はC言語のプログラムでシェルが表示してくれたプロンプトにlsと打つとそのプログラムを探して実行してくれているわけです。なるほど、lsコマンドは一つのファイルのなのか!それではコマンドは全てがプログラムファイルなのかというとそれは違い、シェルの中に組み込まれているものも存在するようです。(これについてはもっと詳しくなってから追記したいと思います。)なんとなくわかってきました。次はシェルとシェルスクリプトの違いについて考えてみましょう!
だったらシェルスクリプトはなんなのさ?
シェルスクリプトがあるとなんで嬉しいのかをまずまとめてから考えるとわかりやすいかと思います。
EX. シェルスクリプトを書かない場合
コマンド実行時に,引数で指定した1つのファイルが読み込み可能な場合はその内容を表示し,ファイルが読み込み不可のときは終了させる場合
<%= link_to_if %>は使えるやつ
こんにちはタカヤです。 初めてのブログ投稿ですが、自己紹介は後々に譲るとして今回は便利なメッソドを見つけたので備忘録として残しておきたいと思います。
link_to_ifとは
例えばこんな時に使えます。
例: ログインしてるユーザーにだけ表示したいリンクがあるとき(ex. 記事編集、削除)
つまり、ログインしていないユーザーがアプリを閲覧したときに記事の編集や削除のリンクがあると意味もない見た目もイマイチです。そんなときはlink_to_ifを使って条件に一致したときのみリンクを生成するのがこのメソッドです。
使い方
<%= link_to_if(user_signed_in? && article.user_id == current_user.id, "編集", edit_article_path(article)) {}%> <%= link_to_if(user_signed_in? && article.user_id == current_user.id, "削除", article, method: :delete, data: { confirm: 'Are you sure?' }) {}%>
第一引数には条件を記述します。
今回の場合は、 user_signed_in? && article.user_id == current_user.id となっています。これはuser_signed_in?でユーザーがログインしていればtrueを返すdeviseというgemのヘルパーメソッドです。
そして、次のarticle.user_id == current_user.idはアソシエーションを用いて記述していますが、現在ログインユーザーと記事を書いたユーザーが一致しているときはtrueを返します。
最後にこの両方を&&で繋げて両方が成り立っているときにtrueを返すようになっています。
このようすればビューファイルに直接条件分岐を書かずに済みます。でも、個人的に思ったのはこれはよく使うのでヘルパーに切り出した方が綺麗で保守性が上がる感と思いました。