技術ブログ

(技術系中心)基本自分用備忘録なので、あくまで参考程度でお願いします。

アクセス負荷分散「Cloud Load Balancing」

アクセス負荷分散「Cloud Load Balancing」

現在の案件ではコンテナ管理にk8s(GKE)を利用しています。

Google Kubernetes Engine(GKE)には、一般公開するアプリケーション用に次の 2 種類の Cloud Load Balancing(HTTP(S)負荷分散用のレイヤー7ロードバランサ(GlobalLoadBalancer)) のサポートが組み込まれています。

k8sについて ↓ lhiroki1205.hatenablog.com

HTTP(S) 負荷分散用 GKE Ingress

Google Kubernetes Engine(GKE)では、GKE Ingress と呼ばれる、組み込みのマネージド Ingress コントローラを使用できます。このコントローラは、GKE で HTTP(S) ワークロードを処理する Google Cloud ロードバランサとして Ingress リソースを実装します。

ingressオブジェクトはクラスタ内で実行されるアプリケーションに HTTP(S) トラフィックをルーティングするルールを定義します。

その時にGKE Ingress コントローラによって Cloud HTTP(S) ロードバランサが作成され、Ingress および関連する Service の情報に従ってそれが構成されます。

つまり、アクセス負荷やCPU負荷が高い時に自動でPodを増やしてオートスケールするといったことが可能になるのです。

GlobalLoadBalancer利用方法について

GlobalLoadBalancerはk8sを利用しない場合でも利用することは可能です。

下記参照図のようにGAEの負荷を算出して、負荷が少ない方に自動ルーティングすることが可能になります。 f:id:lhiroki1205:20210418125501p:plain

参考

吉積礼敏. GCPの教科書

https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer

GCS(Cloud Storage)についてまとめ

GCS(Cloud Storage)についてまとめ

現在のジョインしている案件でリソース管理・管理にCloud Storageを利用しています。

GCS(Cloud Storage)の知見が少ないと感じたので、概要をまとめます。

GCS(Cloud Storage)とは

Cloud Storageとはオブジェクトストレージになります。

オブジェクトストレージとは、従来のようなファイル単位、ブロック単位ではなく「オブジェクト」という単位でデータを管理するストレージです。

個人的見解としては、画像保存やリソース保存にオブジェクトストレージを利用する企業が多いイメージです。

AWSのS3も有名なオブジェクトストレージになりますが、それのGCP版と考えても大枠間違ってないでしょう。

GCSの基本概念はAWSのS3とほぼ同じなので、下記の概念を参照にしてください。

lhiroki1205.hatenablog.com

GCS(Cloud Storage)用語解説

基本的にAWSのS3分かってればすぐに理解できると思います。

f:id:lhiroki1205:20210417195654p:plain 画像参考:GCPのストレージサービスについてまとめてみた

プロジェクト

GCSのデータはすべて、プロジェクトに属します。

パケット

バケットとは、データをGCSに格納するためのコンテナのことです。GCSに保存するデータは、すべてバケットに格納されます。

オブジェクト

バケットとは、データをGCSに格納するためのコンテナのことです。GCSに保存するデータは、すべてバケットに格納されます。

ストレージクラス

GCSのバケットは「MultiRegional」、「Regional」、「Nearline」、「Coldline」の4種類のストレージクラスが用意されております。

f:id:lhiroki1205:20210417195857p:plain

参考サイト

cloud.google.com

吉積礼敏. GCPの教科書

GCPのGKEについて

GCPのGKEについて

現在の案件では全環境(dev, staging, prod)のデプロイをGKEで行なっています。

ただGKEについての知識が乏しかったので、概要知識を記載する。

GKEとは

GKE(kubernetes engine)とはその名のとおりGoogleが開発したKubernetesというオープンソースのコンテナオーケストレーションツールのマネージドサービスです。

GKEイメージ図 f:id:lhiroki1205:20210413092735p:plain

1. ノードが複数集まったものをクラスタと呼ぶ
2. クラスタの中にサービスを定義する
3. サービスは複数のPod(Dockerコンテナ)によりサービス提供する
4. Podはクラスタ内でオートスケールが可能

lhiroki1205.hatenablog.com

GKEの特徴

GKEの特徴を記載します。

1. フルマネージド

クラスタをセットアップして、サービスアップしたらそのあとは全てGoogleでフルマネージドで運用されます。 インスタンスやネットワーク障害の場合でもインフラエンジニアが対処する必要は基本なく、安心してサービス提供することが可能です。

2. プライベートなContainer Registry

Contaner Registryを活用することで、プライベートなDockerイメージの保存とアクセスが容易に可能です。プライベートなので外部公開されるといった危険性もありません。

Contaner Registryとは?

A container registry is a repository, or collection of repositories, used to store container images for Kubernetes, DevOps, and container-based application development.

3. スケーラブル

GKEはPaaSでアプリケーションに対する要求に応じてサービスをスケールさせることが出来ます。

ロードバランサーも自動的に設定されるため、クラスのオートスケールと合わせることでアプリケーションを自動的にスケールすることも可能です。

4. Dockerのサポート

みんな大好きDockerフォーマットをサポートしている為、以降(利用開始や停止)が容易になります。

5. ロギング

チェックボックスをONにすると、Clod Looggingと連携が可能で、全てのログをCloud Loggingで管理できます。

料金体系について

KubernetesEngineは、1プロジェクトにつき5ノードまでは無料です(インスタンスの費用のみ)。6ノード以降でもクラスタ単位で0.15ドル/時間なので、月額にしても1,000円程度という金額です。

他のコンテナ管理サービスとの金額比較はこの動画見れば大枠理解できます。

www.youtube.com

参考

GCPの教科書

GCPのBigQueryについて

GCPのBigQueryについて

業務でGCPのBigQueryを利用する機会があったので、メモ残します。

BigQueryは、Google Cloud Platformで提供されるビッグデータ解析プラットフォームです。1PB(ペタバイト)あるいは10億行といった膨大なデータに対して、集計・分析処理を極めて高速に実行できます。処理はSQL風のクエリ言語で記述します。

BigQueryの特徴

めっちゃ早い

BigQueryの特徴はお驚くほど早くデータ取得できる点です。

例えば、100億レコードの場合、数十秒で解析結果を得ることが出来ます。

ちなみにこの高速処理を可能にしているのは、Googleの何千というサーバー群でクエリを並列処理している為です。

SQLの知識があれば誰でも利用できる。

ユーザーはSQLという使い慣れた言語によって、BigQuery上のビッグデータを解析することが可能になります。

管理不要なフルマネージドサービス

フルマネージドサービスなので、インフラ環境の運用、保守やデータベース管理の必要がありません。

基本概念

BigQueryを構成する抽象概念について説明します。

データセット

データセットは、テーブルの集合を所有するためのコンテナとなります。 RDBでいうところのテーブルスペースのような概念。

テーブル

テーブルは、構造化されたデータの集合です。 BigQueryはRDBと同様にスキーマを持ちます。

ビュー

ビューはSQLクエリによって定義することができる仮想テーブルです。

ジョブ

ジョブはクエリ実行、データ追加、テーブルのコピーなどの実行単位です。 ジョブは非同期で実行され、ユーザーは実行中のジョブステータスをポーリングによっていつでも確認できます。

図解

f:id:lhiroki1205:20210412160321p:plain

クエリ利用方法

qiita.com

参考

GCPの教科書

vue.jsグローバル登録とローカル登録の違いについて

vue.jsグローバル登録とローカル登録の違いについて

Vue.jsのコンポーネント設計にはグローバル登録とローカル登録の2種類があります。 その違いについてまとめます。

コンポーネントとは

1. ページを構成するUI部品
2. 再利用可能なVueインスタンス

コンポーネントを使う理由

1. 再利用ができる
2. メンテナンス性が高まる

一言で言うとコンポーネントとはHTMLとJavaScriptで作成された設計図のようなものになります。

グローバル登録

サンプルコード

Edit fiddle - JSFiddle - Code Playground

ローカル登録

特定のVueインスタンスは以下でしか利用しない、コンポーネントは特定のVueインスタンス配下でしか利用できないようにすることができる。

その時に利用するのがローカル登録。

(グローバル登録はどこからも参照できるというメリットの反面、影響範囲が大きすぎるので基本的にはローカル登録で影響範囲を局部的に収めることが推奨されています。)

サンプルコード Edit fiddle - JSFiddle - Code Playground

複雑なクエリの場合はO/Rマッパーではなく直接SQL書いた方が良いという話

複雑なクエリの場合はO/Rマッパーではなく直接SQL書いた方が良いという話

RailsのO/Rマッパーだけでは複雑な条件取得の場合に役不足のケースがあります。

その場合は直接SQLクエリを作成する方が早いケースがあります。

例)直近1週間で60分以上ゲームしたことがあるユーザーid一覧を取得せよ

この場合はどうすれば良いでしょうか?

0/Rマッパーでも取得はできそうですが、なんどもクエリ発行してDB問い合わせする実装になりそうな気がします。(複雑なので)

今回のケースは直接SQLを書いて、それをDB問い合わせすれば一度のクエリ問い合わせで済みそうです。

SQL

下記のようなSQLクエリを書けば、想定のデータを取得できると思われます。

SELECT user_id FROM
(
    SELECT COUNT(DISTINCT DATE_FORMAT(played_at, '%Y-%m-%d')) AS playing_count, user_id FROM game_rooms
    WHERE started_at BETWEEN now() - INTERVAL 7 DAY + INTERVAL 9 HOUR AND now() - INTERVAL 1 DAY + INTERVAL 9 HOUR
    AND play_time > 60
    GROUP BY user_id
) AS playing_count
WHERE playing_count >= 6;

サブクエリ

(
    SELECT COUNT(DISTINCT DATE_FORMAT(played_at, '%Y-%m-%d')) AS playing_count, user_id FROM game_rooms
    WHERE started_at BETWEEN now() - INTERVAL 7 DAY - INTERVAL 9 HOUR AND now() - INTERVAL 1 DAY - INTERVAL 9 HOUR
    AND play_time > 60
    GROUP BY user_id
) AS playing_count
SELECT COUNT(DISTINCT DATE_FORMAT(played_at, '%Y-%m-%d')) AS playing_count, user_id FROM game_rooms

game_roomsテーブルからselectしたい内容を記載します。

  1. プレイ回数(DISTINCTで同じ日にプレイした場合は重複削除する、countを利用するにはgroup_byが必須)
  2. ユーザーid(groupで利用するため)
WHERE started_at BETWEEN now() - INTERVAL 7 DAY + INTERVAL 9 HOUR AND now() - INTERVAL 1 DAY + INTERVAL 9 HOUR

直近1週間の絞り込みを行います。+ INTERVAL 9 HOURをしている理由はUTCタイムをTokyo/Asiaタイムに変換する為です。

AND play_time > 60

プレイ時間が60分以上のものに絞り込みを行います。

GROUP BY user_id

user_idでグルーピング化します。(GROUP BYで特定の列をキーにした合計値や平均値などが表示される)

AS playing_count

取得したデータに別名をつける(SELECT文を使ってデータを取得する時、カラム名に対して別名を付けることができます)

WHERE playing_count >= 6;

直近1週間で6日以上ゲームをしているものだけに絞り込む。

groupを利用した少し複雑な処理方法

groupを利用した少し複雑な処理方法

タイトルがうまく思いつかないので、よくわからないと思うのですが。

下記のようなケースを想定した場合の処理について説明します。(自分用備忘録です)

例)ユーザーがゲームをした回数を調べたい、日付毎に確認したい。

user_id = 1
 Game.where(user_id: user_id).group("date_format(DATE_ADD(played_at,INTERVAL 9 HOUR), '%Y/%m/%d')").count
=> {"2021/04/05"=>2}

上記の結果からユーザーidが1のユーザーは"2021/04/05"に2回ゲームをしたことが理解できます。

Game.where(user_id: user_id).

ユーザーidが1のレコードを絞り込みます。

Game.where(user_id: user_id).group("date_format(DATE_ADD(played_at,INTERVAL 9 HOUR), '%Y/%m/%d')")

保存されているplayed_atはMySQL標準のUTCタイムになっているのでDATE_ADD(played_at,INTERVAL 9 HOURで+9時間して日本時間に変更します。 さらにdate_formatで日時を整形します。("2021/04/05"みたいな感じに)

 Game.where(user_id: user_id).group("date_format(DATE_ADD(played_at,INTERVAL 9 HOUR), '%Y/%m/%d')").count

何日にどれくらいゲームしたかをカウントするためにcountメソッドを利用します。

まとめ

少し複雑なgropuメソッドの利用方法を説明しました。