ALBとELB、新しいやつ
、古いやつ
という 頭の悪い 使い分けしかしたことなかったので調べてみました。
そもそもロードバランサーとは?
ロード(負荷)
とバランサー(均衡をとる)
を合わせた言葉。
短期間の大量アクセス
、単一サーバーの障害
発生時も安定してサーバ稼働を可能にするための技術。
その他メリット
- ELBに搭載されているSSLアクセラレータで暗号を復号する事でサーバで復号しなくて良くなるので負荷が格段に減る
- SSLアクセラレータがあるので複数サーバのSSL証明書の1本化が可能
個人的学び
障害発生時にヘルスチェックが通らなくなったサーバを自動で切り離すのはAWS独自の機能ではない事。
ELBに暗号文を復号する専用のアクセラレータが搭載されている事。(音楽のDACみたいなものですね)
ALBとELBの違い
ALBはELBでできたことに加えて、様々な新機能が増えてます。
色々な差が、ありはしますが・・・
- ELBはロードバランサーに直接インスタンスを紐付け
- ALBはターゲットグループを用意し、それをロードバランサーに紐づける
- 料金はALBの方が10%安い
- パスベースルーティング:URLのパスに基いてルーティングが可能です。
- 複数ポートの登録:1つのインスタンスに複数ポートを登録することが可能です。
- コンテナアプリケーションのサポート:ECSはタスクスケジュールで未使用のポートを使用しターゲットグループに登録可能
- ターゲットグループでのヘルスチェック:CloudWatchで多くのメトリクスをサポートしています。
- アクセスログの情報追加:アクセスログに情報が追加され、圧縮形式で保存されます。
- パフォーマンス改善:パフォーマンスが向上しています。
- HTTP/2サポート:HTTP/2のリクエストを受けられるようになりました。
- WebSocketサポート:WebSocketのリクエストを受けられるようになりました。
- 削除保護:EC2と同様に削除保護ができるようになりました。
一部引用元:【新機能】新しいロードバランサー Application Load Balancer(ALB)が発表されました
見ても良く分からなかったのは、負荷分散層の違い。
ALB
はアプリケーション層のみ
対応、ELB
はトランスポート層とアプリケーション層
の両方での負荷分散を行える。
色々なサイトにこのように書いてあって何が違うのかと少し調べて図にしてみました。
皆さん大好きアプセトネデブでみる負荷分散の違い (OSI基本参照モデル)
ア:アプリケーション層 <- ALB & ELB
プ:プレゼンテーション層
セ:セッション層
ト:トランスポート層 <- ELB
ネ:ネットワーク層
デ:データリンク層
ブ:物理層
アプリケーション層
と トランスポート層
での負荷分散時のサーバ決定タイミングの違い
層による一番の違いは処理を行うサーバーを決定するタイミングが違うことでした。
処理サーバが決まるタイミングを以下の図にざっくり処理サーバが決まるタイミングをまとめてみました。
トランスポート層での負荷分散方法
トランスポート層では TCP/UDP
の情報までを元に処理を行うサーバーを決定します。
AWSではIPアドレス
とポート番号
を元にどのサーバに処理を任せるかを決定します。
最初のサーバへのアクセス、ハンドシェイクを確立する時にどのサーバが応答するかを決定しています。
【IPアドレスとポート番号での負荷分散の例】
123.456.789:25 => メールサーバへ
123.456.789:80 => アプリケーションサーバへ
アプリケーション層での負荷分散方法
アプリケーション層では HTTP
の情報を元に負荷分散します。
HTTPの情報の中にはURLも含まれているためURL別に負荷分散
を行うことができるようです。
具体的にはハンドシェイク確立後、データ要求処理時の最初のsyn送信のタイミングで処理を行うサーバが決まります。
【URLでの負荷分散例】
123.456.789/admin/users => 管理画面専用サーバへ
123.456.789/article/1 => 公開記事ページへ
余談:ラウンドロビンによる負荷分散
調べている中でnginx側でロードバランシングできるラウンドロビンという機能を見つけたので共有。
nginxにきた処理を他のサーバに振ることでをロードバランサーとして利用することができます。
ただしメンテナンス性が皆無なので実運用はあまりしたくないですね
設定はシンプルでした
http {
upstream example.com {
server app-prod1.example.com;
server app-prod2.example.com;
server app-prod3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://example.com;
}
}
}