2024/08 CTOへの日報まとめ

日報




2024-8-1

Route53のルーティングポリシーのうち、シンプル以外のポリシーについて知ることができました

加重ルーティングポリシー

  • このポリシーでは、指定した割合に従ってトラフィックを複数のリソースに分散させることができる。各レコードには「重み」(例えば、70:30の割合など)を設定できる
  • 用途:負荷分散やA/Bテスト、複数の環境へのトラフィック分散に使用される

レイテンシールーティングポリシー

  • このポリシーでは、ユーザーのリクエストに対して最も低いレイテンシーを提供できるリソースにトラフィックを送る
  • 用途:グローバルに分散したユーザーに対して、最も高速な応答を提供するために使用される

位置情報ルーティングポリシー

  • このポリシーでは、ユーザーの地理的な位置に基づいてトラフィックをルーティングする。特定の地域のユーザーを特定のリソースにルーティングすることができる
  • 用途:地域ごとのコンテンツ提供や、特定地域向けのサービス最適化に使用される

フェイルオーバールーティングポリシー

  • このポリシーでは、プライマリリソースが利用不可能な場合にバックアップリソースにトラフィックを自動的に切り替える
  • 用途:高可用性と災害復旧を実現するために使用される

基本的にはシンプルルーティングを使用することが多いかと思いますが、例えば、東京リージョンと大阪リージョンの2つにインフラを構築し、可用性を高めている場合、位置情報ルーティングポリシーを用いることで、東京に近いユーザーからのトラフィックは東京リージョンのELBにルーティングし、大阪に近いユーザーからのトラフィックは大阪リージョンのELBにルーティングするなどで、最適化が図れることを知りました

2024-8-2 ①

RDSのサブネットグループ、パラメータグループ、オプショングループについて知ることができました

サブネットグループ

  • 概要:サブネットグループとは、RDSインスタンスが配置されるVPC内のサブネットの集合
  • 役割:RDSインスタンスをどのサブネット内に配置するかを指定するために使用される。高可用性を確保するために、複数AZのサブネットを含めることが一般的
  • 設定:RDSインスタンスを作成する際に、特定のサブネットグループを選択する。選択したサブネットグループに登録された複数のサブネットの中から、AWSが自動で決定したサブネットにRDSインスタンスが配置される

パラメータグループ

  • 概要:パラメータグループは、RDSインスタンスの設定パラメータの集合
  • 役割:RDSインスタンスの設定を行う。例えば、メモリ使用量、キャッシュサイズ、タイムアウト設定などをカスタマイズできる
  • 設定:パラメータグループを作成し、特定のパラメータを変更する。その後、そのパラメータグループをRDSインスタンス毎に適用する。各RDSインスタンスは、1つのパラメータグループしか持てない

オプショングループ

  • 概要:オプショングループは、RDSインスタンスに追加機能を提供するためのオプションの集合
  • 役割:RDSインスタンスに追加機能を追加するために使用される
  • 設定:オプショングループを作成し、必要なオプションを追加する。その後、オプショングループをRDSインスタンス毎に適用する。各RDSインスタンスは、1つのオプショングループしか持てない。

MySQLのRDSインスタンスにおいて、オプショングループを使用することで追加できる一般的な機能やオプションの例

MARIADB_AUDIT_PLUGIN

  • 概要:MariaDB Audit Pluginを使用して、データベースの監査ログを有効にする
  • 用途:セキュリティおよびコンプライアンスのための詳細な監査ログを記録する場合に使用される

MEMCACHED

  • 概要:Memcachedのサポートを追加する
  • 用途:データキャッシングを利用してアプリケーションのパフォーマンスを向上させるために使用する

TDE(Transparent Data Encryption)

  • 概要:データベースの暗号化を提供する
  • 用途:保存データのセキュリティを強化し、コンプライアンス要件を満たすために使用される

これらのグループを適切に設定することで、RDSインスタンスのネットワーク構成、設定、追加機能を最適化することができる

2024-8-2 ②

現在の文字エンコーディングを確認するPHP関数であるmb_detect_encodingについて知ることができました

$original_string = “文字列”;
$encoding = mb_detect_encoding($original_string);
\Log::error($encoding); // UTF-8

2024-8-6 ①

S3において、オブジェクト毎にアクセス制御できることを知りました。バケット毎にアクセス制御できることは認識していましたが、オブジェクト毎にできることは知らなかったです。

2024-8-6 ②

URLを指定して、指定したURLからファイルをダウンロードするコマンドである「wgetコマンド」について、様々なオプションを知ることができました。

基本的な使い方
wget http://example.com/file.txt

色々なオプションを知りましたが、実際に利用する可能性があるかなと感じたオプションは2つだけだったので、それだけ共有します

1、-O :ダウンロードしたファイルを指定した名前で保存する
wget -O myfile.txt http://example.com/file.txt

2、ダウンロードするURLのリストが記載されたファイルを指定して、一括ダウンロード
wget -i urllist.txt

(urllist.txt の記載例)
http://example.com/file1.txt
http://example.com/file2.jpg
http://example.com/file3.pdf
http://example.com/file4.zip

2024-8-7 ①

AWS CloudFrontにおけるリージョンキャッシュ(セカンダリキャッシュ)について知ることができました。

  • リージョンキャッシュ(またはセカンダリキャッシュ)とは、AWS CloudFrontのキャッシュメカニズムにおいて重要な役割を果たしている

概要

  • リージョンキャッシュとは、エッジロケーションとオリジンの間の中間キャッシュレイヤー
  • これにより、エッジロケーションでキャッシュミスが発生した場合に、オリジンサーバーへのリクエストを減少させることができる

キャッシュメカニズム

  • ユーザーがコンテンツをリクエストすると、最初にエッジロケーションのキャッシュサーバーがそのコンテンツを探す
  • エッジロケーションでキャッシュミスが発生した場合、そのリクエストはリージョンキャッシュに転送される
  • リージョンキャッシュにコンテンツが存在すれば、それをエッジロケーションに返し、ユーザーに提供する
  • リージョンキャッシュにもコンテンツが存在しない場合に初めて、オリジンサーバーにリクエストが送られ、コンテンツを取得する

利点

  • キャッシュヒット率の向上:リージョンキャッシュにより、エッジロケーションのキャッシュミスが発生しても、高い確率でコンテンツがリージョンキャッシュに存在するため、キャッシュヒット率が向上する
  • オリジンサーバーへの負荷軽減:リージョンキャッシュがオリジンサーバーへのリクエストを代理することで、オリジンサーバーへの負荷を大幅に減少させる
  • パフォーマンスの向上:リージョンキャッシュを利用することで、ユーザーに対するコンテンツ提供の遅延を減少させることができる

配置と管理

  • リージョンキャッシュは、エッジロケーションよりも少数のロケーションに配置されているが、戦略的に選ばれた場所に設置されている
  • AWSはこれらのキャッシュレイヤーを自動的に管理し、最適なパフォーマンスを提供するように設計されている

これまでは「リクエストしたコンテンツがエッジロケーションでキャッシュされているか確認して、キャッシュされていなければオリジンサーバーからデータを取得する」という認識ですが、実は間にリージョンキャッシュというキャッシュの機構が存在していて、二段階でキャッシュの機構が用意されていることを知ることができました。

2024-8-7 ②

下記の記事を読み、JSにおいて知らない書き方が沢山あるなと感じました。下記記事は、Qiitaのトレンドで1位になっていました。
https://qiita.com/Sicut_study/items/6b4b40e03ec8dbe517c3

2024-8-8

ELBには、自動でスケールアウトする機能が備わっていることを知りました。これにより、開発者が明示的にELBを冗長化せずとも、トラフィックの増加を自動で検知し、適切なタイミングで自動でスケールアウトするとのことです。確かに言われてみれば、いくらバックエンドにあるEC2インスタンス等を冗長化しても、ELBがSPOFになっていては仕方ないといいますか、せっかく後ろにあるリソースを冗長化して可用性を高めても、手前が死んでは意味がないので、ELBにそのような自動スケールアウト機能がデフォルトで備わっていても、おかしくはないと思いました。ELB自体の可用性についてあまり考えたことがなく、気になり調べてみたらそのようなデフォルト機能が備わっていることを知りました。

2024-8-13 ①

Amazon API Gatewayとは何か知ることができました。

今まではAPIと何かを繋ぐパイプのようなイメージでしたが、正しい(詳細な)イメージとしては「バックエンドにAPIを構えるLBのようなもの」であることを知りました。つまり、APIと通信したいサービスは、API Gatewayをエンドポイントにリクエスト送信することで、API Gatewayが「適切に設定されたルーティング」に従って、バックエンドにある適切なAPIにリクエストをルーティングすることで、結果APIにリクエストが届き処理が行われる、という全体的な流れを知ることができました。

2024-8-13 ②

stashに一時保存する際に、これまでは git stash push -u -m “適当なスタッシュメッセージ” としていましたが、適当なスタッシュメッセージを考えて書くのが面倒でした。しかし、git stash -uコマンドを実行すれば、自動作成されたスタッシュメッセージを元にスタッシュ保存できることを知りました。今後は後者のコマンドを使っていきたいと思います

2024-8-14 ①

正規表現における「キャプチャリンググループ」について知ることができました

・正規表現における「キャプチャリンググループ」とは、括弧()で囲まれた部分のパターンのこと

$search_strings = “{job_history}{pc_email}”;
$search_strings_array = [];
preg_match_all(‘/{(\w+?)}/’, $search_strings, $search_strings_array);
var_dump($search_strings_array);

// var_dumpの出力
array(2) {
[0]=>array(2) {
[0]=>string(13) “{job_history}”
[1]=>string(10) “{pc_email}”
}
[1]=>array(2) {
[0]=>string(11) “job_history”
[1]=>string(8) “pc_email”
}
}

PHPのpreg_match_all関数は、デフォルトで戻り値(配列)の1番目の要素として、キャプチャリンググループのすべてのマッチを含む配列を返すようですが、それがどういうことか理解することができました

2024-8-14 ②

git addで変更のあるファイルをステージングに上げる際に、特定ディレクトリ以下のファイルのみ上げる方法を知ることができました。
git add dir1/

2024-8-16 ①

マイクロサービスアーキテクチャのDB設計について知ることができました。

マイクロサービスアーキテクチャに関して、これまでは「アプリケーションコードだけをAPIとして外部に切り出して、小さなサービス(API)を複数作り、それらの集合で1つの大きなサービスを構築する設計手法」だと認識していて、その理解に相違はありませんでしたが、DBに関しては全てのサービス(API)で共通のDBを利用する(DBはAPI毎に分離しない)と認識していました。しかし、これは誤った理解だったみたく、マイクロサービスアーキテクチャではアプリケーションコードと同じく、DBに関してもAPI毎に分離するとのことでした。これにより、API間の結合が疎になり、独立したデプロイが可能になるなどの恩恵があることを知りました。

2024-8-16 ②

自己結合のクエリをはじめて使いました。今後も機会あれば使っていきたいと思います

SELECT a.id, b.id AS duplicate_id
FROM employees a
JOIN employees b ON a.email = b.email AND a.id != b.id;

2024-8-19

RedisでTTL(Time To Live)を設定する方法を知ることができました。

  • Redisに保存するデータには、保存期間(TTL)を設定することが可能
  • アクセストークンのように有効期限があるデータに対して、TTLを設定することで、指定した期間が経過した後、自動的にRedis上からデータが削除されるように設定可能

RedisでTTLを設定する方法

1、EXPIREコマンド:既に保存されているキーに対して、TTLを設定する方法
> EXPIRE key seconds

例:キー access_token:12345 に対して、60秒のTTLを設定する場合
> EXPIRE access_token:12345 60

2、SETコマンドで直接TTLを設定:SETコマンドを使ってデータを保存するときに、TTLを同時に設定することもできる
> SET key value EX seconds

例:access_token:12345 というキーに対して値を保存し、60秒後に自動削除する場合
> SET access_token:12345 “token_value” EX 60

利点

  • 自動管理:TTLを設定することで、手動でのクリーンアップが不要になり、メモリの効率的な利用が可能
  • データの有効性保証:有効期限が過ぎたトークンが自動的に削除されるため、不正なアクセスのリスクを減らすことができる

RedisのTTL機能は、アクセストークンのように有効期限があるデータを扱う場合に非常に有効。この機能を活用することで、セキュリティとパフォーマンスを両立できる。

2024-8-20

Redisを用いて「API1のアクセストークン」と「API2のアクセストークン」を、両者ともにキーとして同じ情報を用いて保存したい場合に、キーの重複を避ける方法を知ることができました。

Redisでは、データベースや名前空間(キーのプレフィックス)を使って、キーの重複を避けることができる

1、データベースを分ける
Redisには、デフォルトで16個のデータベース(0〜15)が用意されている。各データベースは独立しており、キーの重複を避けるために異なるデータベースを使用できる

データベースの選択
SELECTコマンドを使って、使用するデータベースを選択できる。例えば、API1とAPI2で別々のデータベースを使いたい場合、次のように設定する。

API1:データベース0を使用
SELECT 0
SET user_id “access_token_API1”

API2:データベース1を使用
SELECT 1
SET user_id “access_token_API2”

この方法で、同じキー名(user_id)を使っても、別々のデータベースで管理されるため、衝突を避けることができる

2、名前空間(キーのプレフィックス)を使う

データベースを分けずに、キー名にプレフィックスを付けることで、名前空間のように扱うことができる。これにより、同じデータベース内で異なるAPIのデータを整理できる

プレフィックスの使用例
API1:api1:user_idとして保存
SET api1:user_id “access_token_API1”

API2:api2:user_idとして保存
SET api2:user_id “access_token_API2”

この方法は、同じデータベース内に異なる保存領域を作るのと似た効果があり、キーの衝突を防ぎつつ、データを整理できる

どちらの方法が良いか

  • データベースを分ける方法:それぞれのAPIが独立してデータを管理したい場合に便利。ただし、Redisのデータベースは固定数(デフォルトで16個)しかないため、大規模なシステムでは限界がある
  • 名前空間を使う方法:より柔軟で、複数のAPIや機能にわたってデータを整理したい場合に適している。キーのプレフィックスは自由に設定でき、組み合わせも無限

ニーズに応じて、どちらかの方法を選ぶべき

2024-8-21

webサーバーにnginxを用いた場合に、PHPスクリプトを実行する方法について知ることができました

  • nginxを使用する場合、php-fpmを利用することが、PHPスクリプトを実行するための最も一般的で効率的な方法
  • nginx自体はPHPのコードを直接実行する機能を持っていないため、PHPの実行を行うには外部のプロセスマネージャーが必要になる
  • その中で、php-fpmは特にnginxとの連携において広く推奨されている選択肢

理由(PHP-FPMの利点)

1. パフォーマンス

  • PHP-FPMはFastCGIの実装で、持続的なプロセスプールを提供する
  • これにより、リクエストごとに新しいPHPプロセスを生成するオーバーヘッドが削減され、応答速度が向上する

2. 高度なプロセス管理

  • PHP-FPMはプロセスの起動、監視、終了を効率的に管理し、サーバーの負荷に応じてプロセス数を調整することができる

3. セキュリティと安定性

  • 異なるリクエストを異なるユーザー権限で実行することが可能で、セキュリティリスクを低減できる

他のオプション

  • Nginxを使用する場合、他にもPHPスクリプトを実行する方法は存在するが、それらは一般的ではなく、設定が複雑または非効率的であることが多い
  • 例えば、CGIベースの方法や他のプロセスマネージャーを使用することも技術的には可能だが、これらはPHP-FPMほど効率的ではない

Nginxと組み合わせてPHPを実行する場合、PHP-FPMは事実上の標準となっている。そのため、Nginxを使用する際には、PHP-FPMを利用することが推奨される。これにより、パフォーマンス、セキュリティ、スケーラビリティが向上し、ウェブアプリケーションの運用がより効率的になる。

2024-8-22

自身のPC(以降、ホスト)の特定ディレクトリに、特定のフレームワークをインストールしたい場合に、ホストに直接インストールするのではなく、dockerで一時的なコンテナを立ち上げて、それを用いてホスト側にセットアップする方法について知ることができました。

例:ホストのsrcディレクトリにLaravelをインストールしたい場合

1、以下のようなDocker Composeファイルを用意
(docker-compose.yml)
services:
app:
image: composer:latest
volumes:
– ./src:/var/www/html
working_dir: /var/www/html
command: composer create-project –prefer-dist laravel/laravel .

2、docker-compose run app コマンドを実行
上記の設定を使用し、docker-compose run app コマンドを実行することで、コンテナ内でComposerが実行され、ホストのsrcディレクトリにLaravelプロジェクトがインストールされる

これにより、ホストへのPHPやComposerのインストールを避けることができ、ホスト環境のクリーンさを維持できる

2024-8-23 ①

昨日の日報では、dockerを用いてローカルPCにLaravelをインストールする方法についてアウトプットしたと思います。そこで「では将来、Laravelのバージョンアップが必要になった際には、同じようにdockerを用いてバージョンアップできるのか」について気になったので、方法を調べてみました。結論、できるようでした。

1、一時的なコンテナを起動
docker-compose run app のようにして、一時的なコンテナを起動する。このコンテナで、ホストのLaravelコードが置かれているディレクトリをマウントする

2、バージョンアップのためのコマンドを実行
コンテナ内で composer require laravel/framework:^新しいバージョン などのコマンドを実行して、Laravelのバージョンアップを行う

3、ホスト側に変更が反映
コンテナ内の変更は、マウントされているホストのLaravelコードが置かれているディレクトリに即時反映される。これにより、ホスト側でバージョンアップ後のコードが保持される

dockerを用いてインストールを行ったとしても、以降の運用で不便な部分はなさそうで、「これは有用な方法を知れたな」と思いました

2024-8-23 ②

Apacheのバージョンアップにより発生した不具合に関して、PCでは発生しなかったが、SPからの操作(LINEでエントリー)では発生したことを踏まえて、ユーザーエージェントの違いにより不具合発生有無が変わるケースもあるのだなと勉強になりました

2024-8-26 ①

MySQLでデータベースのデフォルト照合順序(collation)を確認するためのコマンドについて知ることができました

(コマンド)
SHOW CREATE DATABASE database_name;

(出力)
Database   Create Database
my_database CREATE DATABASE `my_database` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

これより、デフォルトの文字セットがutf8mb4で、照合順序がutf8mb4_unicode_ciであることがわかる

2024-8-26 ②

プライベートで開発している際に、下記の問題に遭遇しました
https://okuyan-techdiary.com/mysql-dbeaver-error/

改めて、バージョンアップによる副作用は、エンジニアをやっている限り一生向き合っていかないといけないなあと感じました

2024-8-28

ApacheとNginxの設定ファイルの違いについて知ることができました。

Apache

  • Apacheは、httpd.confやその他の設定ファイル(apache2.conf, sites-available/ディレクトリ内のファイルなど)を利用して設定を管理する
  • Apacheの特徴的な点は、ディレクトリレベルで設定を分散させることができる.htaccessファイルの使用
  • これにより、特定のディレクトリに特有の設定を行うことができる
  • 例えば、認証を要求するディレクトリやリダイレクトを設定するディレクトリに、それぞれ異なる.htaccessファイルを設置することが可能
  • .htaccessファイルは非常に強力で柔軟性があるが、パフォーマンスに影響を与えることがある
  • なぜなら、Apacheはリクエストごとに.htaccessファイルを読み込み、解析する必要があるから

Nginx

  • 一方、Nginxは設定を一元管理するアプローチを採用している
  • すべての設定はnginx.confファイルやその他の統合された設定ファイル(例えばconf.d/ ディレクトリ内のファイル)に記述される
  • Nginxは.htaccessファイルをサポートしていないため、ディレクトリレベルでの細かな設定変更が必要な場合には、中央の設定ファイルを編集する必要がある
  • Nginxの設定ファイルは「ブロック」または「コンテキスト」と呼ばれるセクションで構成されており、これにより特定の機能や設定群をグループ化できる

Nginxの主なブロックには以下のものがある

  • events:接続処理に関連する基本設定を管理する
  • http:HTTPサーバーに関する設定を行う
  • server:個々のサーバーインスタンス(例えば異なるポートやサーバー名でリッスンする設定)を定義する
  • location:特定のリクエストURIに基づいて処理を定義する

パフォーマンスへの影響

  • Nginxは設定ファイルを予め読み込み、メモリに保持するため、リクエストごとに設定を読み込む必要がなく、高いパフォーマンスを提供する
  • この設計により、特に静的コンテンツの配信やリバースプロキシとしての利用において、NginxはApacheよりも高速に動作する場合がある

Apacheの.htaccessのような動的な設定変更は、Nginxではサポートされていないが、これにはセキュリティとパフォーマンスの向上が含まれている。設定変更は中央の設定ファイルで行う必要があり、これにはWebサーバーの再起動やリロードが必要になる場合があるが、一貫性と予測可能性が向上する

2024-8-29

docker-compose.ymlにて記述可能なcontextの影響範囲について知ることができました

contextとは、docker-compose.yml内で定義した各サービスのビルド時に使用されるファイル等にアクセスする際の基準となるパスですが、その基準はdocker-compose.yml内でのみ適用されると認識していました。しかし実際には、そのサービスが利用するdockerfile内に記述されたパスに関しても、contextで指定したパスからの相対パスで参照されるみたいでした

services:
app:
build:
context: ./app
dockerfile: Dockerfile #
volumes:
“./src:/var/www/html” # ./app/srcを参照する

(dockerfile)
〜省略〜
COPY ./config/ /var/www/html # ./app/configを参照する
〜省略〜

2024-8-30

Laravelでは、vendorディレクトリをgitで管理せず、各開発者がローカルでcomposer installすることで、vendor以下のコードを用意することが通例であることを知りました。

Laravelのvendorディレクトリには、Laravel本体のコードやComposerを通じてインストールされた他の依存パッケージのコードが格納されている。そのため、非常に重いディレクトリである。また、基本的にvendor以下のコードには変更を加えない。そのため、vendorディレクトリに関しては、gitで管理しない。各開発者がリポジトリをローカルにクローン後、composer installを実行し、composer.lockに定義された必要な依存関係をvendor以下にインストールすることで対応することが通例。これにより、リポジトリの不要な肥大化を防ぐことができる。

考えてみれば、これはLaravelに限った運用ではなく、このような「変更を加えるべきではない、フレームワーク本体やライブラリ本体のコードが格納されたディレクトリ」に関して、gitで管理せず、各開発者が各技術のパッケージ管理システムを使って依存関係をインストールする運用が一般的な運用なのかなと思いました。世の中のプロジェクトがどのようなGit戦略を取っているのか、色々知りたいなと興味が湧きました。