fluid_27’s blog

勉強した内容をアウトプットするためのブログ

Push型とPull型の違い

SAAに向けて勉強していて、その過程で「LambdaのPush型では・・・」みたいな表現があり、PushとPullとの違いが気になったので、調べてみました。

 

 

一般的な意味でのPushとPullの違い

営業やマーケティングでもPushやPull型というのは使われるらしく、そういった一般的な意味合いでは

 

Push型

使う人が何もしなくてもこっちから勝手に何かをするやり方

 

Pull型

使う人からのアクションがあって、はじめてこちらも動き出すやり方

 

という風に使い分けされているみたいです。

 

ですが、冒頭の例で出てきたLambdaでのPushとPullの違いでいうと

LambdaのPush型

  • AWSサービスや独自アプリケーションから、AWS Lambda へイベント通知して、コードを実行する

  • コード実行の順序は保証されない

 

LambdaのPull型

  • イベントをストリームに流し、AWS Lambda はストリームからイベントを取り出し、コードを実行する
  • 一度ストリームに入れることによって、イベントの順序を保つことができる

 

といった違いになるみたいです。

 

参考サイト

https://wa3.i-3-i.info/diff152pushpull.html

https://cloudpack.media/9304

Elasticache の Memcached と Redisの違いって何よ?

SAAに向けてAWS勉強していて表題のような疑問を抱いたので、調べてみました。

 

 

そもそもElasticacheとは?

完全マネージド型のインメモリデータストアです。

Amazon ElastiCacheを使用すると、インメモリデータストアをシームレスにセットアップ、実行、スケーリングができ、データをノードのメモリに保存するのでかなり高速に処理できます。

 

ほうほう。。えっと、ノードって何でしたっけ??

 

ノードとは

ElastiCacheでは最小の構成単位を「ノード」と呼びます。EC2で言うところのインスタンスに相当するものです。

 

ちなみに、、

クラスターとは

ノードを組み合わせた集合体をクラスターと呼びます。ノードに直接接続してしまうと、もしそのノードに問題が発生した場合には新しいノードのアドレス(エンドポイント)をアプリケーション側で書き換えなくてはなりませんし、サービスの成長と共に負荷が上がってくるとノードの台数を増やして負荷やメモリ(キャッシュ)を分散したりといった要件も出てきます。クラスター構成を組んでおいて、常にアプリケーションはエンドポイントを見ておくようにすればノードの増減によってアプリケーションに変更を行う必要がありません。よって、運用を行う上でこのクラスター機能という観点は非常に大事になってくるのです。

 

なるほど。

ということで、

Elasticacheとは「フルマネージド型でスケーラブルなインメモリデータストア」ということですな。

 

 で、そのElasticacheにはエンジンが下記の2種類存在する。

 

それぞれ特徴としてはザックリいうと

  • Amazon ElastiCache for Memcachedシンプルな処理向け」
  • Amazon ElastiCache for Redisは「高度なデータ構造、消えたら困るデータ処理向け」

という違いがあるみたいっす。

 

より詳しく見ていくと

Memcached

Memcachedクラスターは単純にノードを追加したり減らしたりして負荷を分散することができる。

この仕組みは自動検出と呼ばれる機能に依存している。クライアントアプリケーション側で定期的にノードの状態をチェックし、その情報を元にノードにアクセスしにいっている。

 

Redis

Redisにはいくつか種類があるらしく、

  • クラスターモードを有効にするか無効にするか
  • シャードを有効にするか無効にするか

選択できるとのこと。

だが、Memcachedとの大きな違いはクラスターのエンドポイントを持っていること。

Memcachedはノードの状態をポーリングしてノードにアクセスしにいく形なのに対し、Redisの場合はクラスターがエンドポイントを持っており、アプリケーション側でポーリングする必要がない。 

 

クラスターモードを有効にする

スケールアウト・インが可能になる。

 

シャードを有効にする

また、シャードを有効にすると、レプリケーションが可能になり、1つのプライマリノードに最大5つまでのレプリカノードを登録することができる。

常にデータのバックアップをレプリカノードで取っておいて、もしプライマリノードで故障が発生した場合にはレプリカノードが昇格してプライマリノードになることができる。そして新たなレプリカノードが追加され、これにより障害に対して可用性を担保している。 

 

 といった違いがあるみたいっす。

 

まとめ

正直、初学者の自分としては全て理解できているとは言い難いですが、

今の時点では

ElastiCacheは「フルマネージド型なインメモリデータストア」であり、

Memcachedを選択すると、「あくまでシンプルにノードの増減で処理負荷を分散させる」。

Redisを選択すると、「スケーラブルに加えて耐障害性が上がる」。

 

という風に理解してます。

初学者なので、認識に誤りがあるかもしれません。

その際は都度更新していこうと思います。

 

参考サイト

https://aws.amazon.com/jp/elasticache/memcached/

https://dev.classmethod.jp/articles/which-choice-redis-memcached/

https://dev.classmethod.jp/articles/elasticache-is-very-good-lets-review/

https://www.skyarch.net/column/amazon-eelasticache/

プロキシって何?となったので調べてみた

プログラミング初学者です。

AWSのSAA模擬試験で

 

EC2プロキシはインスタンスをバックエンドするコンテンツ管理に利用していますが、現状ではアプリケーションは適切に拡張できない可能性があり・・・

という問題があり、「ええっと、プロキシって何だっけ?」となったので調べてみました。

 

 

プロキシとは

プロキシとは「代理」の意味である。インターネット関連で用いられる場合は、特に内部ネットワークからインターネット接続を行う際、高速なアクセスや安全な通信などを確保するための中継サーバ「プロキシサーバ」を指す。 

                                  wikipedia

 

ということらしいです。

ちなみに「プロキシサーバ」には「WEBプロキシ」、「SMTPプロキシ」、「FTPプロキシ」、「HTTPプロキシ」など、プロトコルごとにさまざまな種類のプロキシが存在するみたいです。 

 

今回はSAAの模擬試験でおそらく指してあるであろう「WEBプロキシ」に焦点を当てます。

 

WEBプロキシサーバの種類

WEBプロキシサーバにもさらに種類があるらしく

  • フォワードプロキシ
  • キャッシュサーバ
  • 透過型プロキシ
  • リバースプロキシ

 の4つがあるそう。

一般的にWEBプロキシサーバと言われているのは「フォワードプロキシ」とのことで、クライアントとサーバの間に設置し「社内ネットワークー公開ネットワーク間」の通信の代理や中継を行うものだそうです。

 

WEBプロキシサーバの機能

主な機能として

  •  通信の中継
  • 一時的な情報(キャッシュ)の保存
  • WEBページのフィルタリング

の3つあり、

「通信の中継」はクライアントとwebサーバの間を中継することでセキュリティをより強固にできる。

「一時的な情報の保存」はキャッシュを保存しておくことで、通信をより高速化することができる。

「WEBページのフィルタリング」はホワイトリストブラックリストなどを用いて特定の通信の相手を制限することができる。

という効果があります。

 

つまり、プロキシって何のために使うの?

というと、

  • webサイトの表示高速化ができる
  • セキュリティ面をより強固にし、サイバー攻撃を制御できる
  • 代理サーバなので、IPアドレスやホスト名などを直接さらさず、匿名性を確保できる

 

というメリットを享受するため利用する。

ということかと思います。

違ったら、すいません。 

 

参考サイト

プロキシ - Wikipedia

https://www.amiya.co.jp/column/web_proxy_20200911.html

 

以上。

scsiとiscasi

AWSのSAA試験に向けて勉強しているプログラミング初学者です。

 

模擬テストの問題で

あるソリューションアーキテクトは、iSCSIバイスを利用して安価にストレージエリアネットワークを構築しようとしています。・・・

 

という文が出てきました。

iscsiって??

となったので、調べてみました。

 

あくまでSAA試験に向けて調べただけなので、深堀りしてません。

 

 

iscsi

iscsi (Internet Small Computer System Interface) とは、SCSIプロトコルTCP/IP上で使用する規格である。ファイバーチャネルよりも安価にストレージエリアネットワーク を構築出来る。

                                  wikipedia

 

なるほど。。

で、scsiって??

 

scsi

Small Computer System Interface、略してSCSI は、主に周辺機器とコンピュータなどのハードウェア間のデータのやりとりを行うインタフェース規格の一つである。SCSIを使用可能にするインタフェース装置をSCSIインタフェースと呼ぶ。ANSIによって規格化されている。 

                                  wikipedia

 

んーと、、つまり「インターフェース規格」ってことらしい。

 

ちなみに scsiは「スカジー」と読むらしく、scsi は「マウスやキーボードやプリンタとPCとを接続するための規格」ということみたいです。

 

では、戻ってiscsiとは「ネットワーク上(TCP/IP)で周辺機器と接続するための規格」ということみたいです。「アイスカジー」と読むみたいです。

 

iscsiが使われるようになった経緯については、

それまで使われていたDAS(Direct Attached Storage)と呼ばれる「サーバーとストレージが1対1の関係」からSANと呼ばれる「サーバーとストレージが N対1の関係」に移り変わり、それを実現するための光ケーブルを利用したFibre Channelという転送方式から、より安価で運用が楽なiscsiに移り変わっていった、、、

 

という事情があるみたいですが、決して深堀りしません。

気になった方は調べてみてください。

そして、教えてください。

 

以上です。

 

参考にしたサイト

https://www.fujitsu.com/jp/products/computing/storage/lib-f/tech/interface/iscsi/

https://milestone-of-se.nesuke.com/sv-basic/architecture/iscsi-summary/

https://wa3.i-3-i.info/word12371.html

https://wa3.i-3-i.info/word12368.html

scopeを使って、絞り込み検索機能を実装してみた

raiils の初学者です。

scopeについてよく分かってなかったのですが、絞り込み検索機能を実装するにあたって、「scope使えば実装できるかも」となって、実際に使ってみたので、まとめたいと思います。

 

 

 scopeを使うことになった経緯

そもそも今までは絞り込み検索機能はwhereを使ってDBからデータを絞って取り出せばいいや。と考えていました。

ただ、絞り込む要素がいくつかあったとして、そのうちのどれかをユーザーが選択しなかった場合の処理。

 

ようは下の写真のように

f:id:fluid_27:20210602184352p:plain

 

「開始日付」、「終了日付」、「開始時刻」、「終了時刻」、「方面」、「駅」

と絞り込み要素が複数存在した場合の絞り込み型として

@posts = Post.where('date => ?', params[:post][:start_date]).where('date =< ?', params[:post][:end_date]).where('date => ?', [:post][:start_time])・・・

といった感じでwhereをつなげてしまうと、

「今回は 開始日付と 終了日付 だけで絞り込みたい」のような一部だけの絞り込みというのが出来ず、どの項目も必ず選択することになってしまいます。

 

以前、同じような状況に陥った際に

if params[:post][:start_date]

 ・・・

 

というように、if文で分岐させて、if文の中にwhereを使った絞り込み処理をしていたのですが、今回のように項目が多いとif文がめちゃ長くなってしまいます。

 

そこでググってみると、scopeを使って絞り込み検索機能を実装出来そうだったのでscopeを使ってみました。

 

そもそもscopeって?

「なんかmodelにvalidation設定する際に使ったことあったけど、結局何?」 となったのですが、ようは

scopeを使えば、where、joins、includesなどの複数クエリをまとめて、1つのメソッドとして定義できる

 ということみたいです。(違ったらごめんなさい)

 

scopeを使うと良いこと

scope1つに1つにif文をつけられるので、 paramsに値が入ってない場合は(ユーザーが全項目を選択してなくても)

「全選択」扱いにすることができました。

以下が実際に書いたコードです。

 

実際に書いたコード

Post.rb

# 検索の際の期間絞り込み

scope :s_duration, ->(start_date) { where("date >= ?", start_date) if start_date.present? }

scope :e_duration, ->(end_date) { where("date <= ?", end_date) if end_date.present? }

 

# 検索の際の時間絞り込み scope :s_time, ->(start_time) { where("time >= ?", start_time) if start_time.present? }

scope :e_time, ->(end_time) { where("time >= ?", end_time) if end_time.present? }

 

# 検索の際の方面と駅の絞り込み scope :direction, ->(direction) { where("direction = ?", direction) if direction.present? }

scope :station, ->(station) { where("station_id = ?", station) if station.present? }

 

post.controller.rb

def posts_search

  s_time = params[:post][:start_time]

  e_time = params[:post][:end_time]

  s_date = params[:post][:start_date]

  e_date = params[:post][:end_date]

  direction = params[:post][:direction]

  station = params[:post][:station]

  @posts = Post.s_duration(s_date).e_duration(e_date).s_time(s_time).e_time(e_time).direction(direction).station(station)

end

 

本当はもっと短く書けるのかもしれませんが、今回はこれで良しとしました。

詳しくはrailsのサイトに載っています。

 

 参考サイト

https://qiita.com/ozin/items/24d1b220a002004a6351

https://railsguides.jp/active_record_validations.html

 

gem 'kaminari' を使ってページネーションを実現

作っているアプリにページネーション機能を追加してみました。

 

ページネーションとは、表示する件数が多い時に、ページで区切って、ページごとに表示させていくやつですね。

ページ下とかにページ遷移のボタンが出てくるアレです。

f:id:fluid_27:20210602002432p:plain

 

実装方法

railsに関しては簡単で gem 'kaminari' を使えばサクッと実装できるみたいです。

 

1. gem 'kaminari' の追加

Gemfile に 

gem 'kaminari'

を追加して、

$ bundle install

 

2. controller側にpage(params[:page])追加

controllerのページネーションを実現したいアクションのところで

def

  index @users = User.all.page(params[:page]).per(10)

end 

というように記述。

page(params[:page])とすることで他ページに遷移するボタンを勝手に作成してくれます。

その後のper(10)は 「10件ごとに1ページ」で区切っていく。という意味。

なので、そこの数字を変えることでページあたりの件数を変えられます。

 

3. view側に <%= pagenate %>追加

viewのページネーションを表示させたい場所に下記のような形で記述を追加。

<%= paginate @users %>

 

4. cssを整える

$ rails g kaminari:views default

 とかすると、kaminari用にviewが作成され、そこのcssを編集することで見た目を整えられる。

bootstrapを使っている場合は

$ rails g kaminari:views bootstrap4

とかで作成すると、bootstrapがそのまま使えるみたい。

 

その他・参考サイト

あとは、他ページに遷移する表示を「次へ」のように日本語化させたりもできるみたいです。

いつもお世話になっている初学者の味方 ・Pikawakaに載っていたので、その辺りは参考にするといいかも思います。

【Rails】 kaminariの使い方をマスターしよう! | Pikawaka - ピカ1わかりやすいプログラミング用語サイト

 

N+1問題が発生していたので、解決してみた

ハッカソンで共同開発しているアプリで、いわゆる「N+1 問題」が発生していた。

ログを見ているとめちゃめちゃDBにアクセスしている。。

 

 

実際にN+1問題がでていたコード

Posts.controller.rb

  @posts = Post.all

 

index.html.erb

<% @posts.each do |post| %>

  <ul>

    <li>ポストID:<%= post.id%> </li>

    <li>投稿者:<%= link_to "#{post.user.name}", show_user_path(post.user)%></li>

    <li>日付:<%= post.date%>曜日:<%= post.day_of_week %></li>

    <li>時刻:<%= post.time %>時</li>

    <li>方面:<%= post.direction%></li>

    <li>駅:<%= post.station.station_name%></li>

    <li>混雑具合:<%= post.congestion_level%></li>

    <li>コメント:<%= post.comment%></li>

    <%= button_to '投稿削除', delete_post_path(post.id), data: {confirm: '本当に投稿を削除しますか?'}, method: :delete, class: "btn btn-warning" %>

  </ul>

<% end %>

 

UserとPostとStationテーブルがあり、関係は

 

 User.rb

  has_many :posts

 

Post.rb

  belongs_to :user

  belongs_to :station

 

となっている。

 

 

原因

コントローラーで Post.all である @posts をviewに渡して、それをeach文で回しながら、それぞれ関連づいている

  • post.user
  • post.station

などを表示させる仕組みだったが、それらの関連づいたデータを表示させる際に、一回一回DBにデータをとりに行っていた為に、DBへのアクセス回数が増え、いわゆる N+1問題が発生していた。

 

解決法

ググったらすぐに出てきた。

controllerで

Post.allでなく

Post.all.includes(:user, :station)

とするとPostに関連づいた User, Postも取得してくれて post.user などを表示させる際に一々DBにアクセスしなくなる。 

 

上記のincludes(:user, :station)は

関連づいているモデルとの関係が 1:N なのか 1: N : 1なのか、とかで書き方変わるみたい。

詳しくは下記サイトにありました。

https://qiita.com/hirotakasasaki/items/e0be0b3fd7b0eb350327

 

 

countでも発生していた

思ったよりも簡単なコード記述で解決できるんだな。

と思っていたらログを見ると、まだちょっとアクセスする回数が多い。。

よくよく見ると、ユーザーの投稿回数を表示させる

user.post.count

でやっぱり都度、DBにアクセスしている。

これもググったらすぐに出てきた。

結論からいうと、

user.post.count

 とすればいいだけだった。

 

参考サイト

https://qiita.com/awakia/items/60467b95f92bee9a469a

 

プログラミング初心者の自分にとって、「N+1問題っていうのがあるみたいだけど、そのうち調べてみよ」くらいに思っていたが、調べてみると、割と簡単な記述で回避できるんだなぁ。と思った。

includes以外にもN+1問題を解消する方法があるみたいなので、また更新しようと思います。