<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>CakePHP &#8211; エンジニア見習い</title>
	<atom:link href="https://otonan-syusyoku.work/archives/tag/cakephp/feed" rel="self" type="application/rss+xml" />
	<link>https://otonan-syusyoku.work</link>
	<description>三流プログラマー</description>
	<lastBuildDate>Sat, 22 Feb 2025 05:29:24 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://otonan-syusyoku.work/wp-content/uploads/2023/10/cropped-名称未設定のデザイン-16-32x32.png</url>
	<title>CakePHP &#8211; エンジニア見習い</title>
	<link>https://otonan-syusyoku.work</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>【AWS】S3への通信量削減の手法</title>
		<link>https://otonan-syusyoku.work/archives/1842</link>
					<comments>https://otonan-syusyoku.work/archives/1842#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sun, 15 Sep 2024 07:31:51 +0000</pubDate>
				<category><![CDATA[インフラ]]></category>
		<category><![CDATA[生涯独学]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[サーバー]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1842</guid>

					<description><![CDATA[便利なストレージサービスであるS3を皆さん使っていますか…!? 静的コンテツの配信サーバーの役割をこなしたり、イレブンナインの耐久性を持ったストレージサービスといった点からAWSの中でも大好きなサービスです。 便利が故に [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>便利なストレージサービスであるS3を皆さん使っていますか…!?</p>
<p>静的コンテツの配信サーバーの役割をこなしたり、イレブンナインの耐久性を持ったストレージサービスといった点からAWSの中でも大好きなサービスです。</p>
<p>便利が故にコスト面でネックになってしまう状況が多々あるかと思いましたので、個人的に経験したコストダウンの設計手法をご紹介したいと思いますー！</p>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">話すこと</div>
<div class="sc_frame">
<p>今回は設計について話します。<br />
実装については話しません。</p>
</div>
</div>
<h2>手始めに</h2>
<p>まず初めにS3に関わる費用のざっくりとした内訳を確認しておきましょう。</p>
<ul>
<li>ストレージ</li>
<li>データ転送（IN/OUT）</li>
<li>セキュリティコントロール</li>
<li>レプリケーション</li>
<li>etc&#8230;</li>
</ul>
<p>一般的な運用を想定すると <strong>ストレージ </strong>と <strong>データ転送 </strong>が費用の大部分を占めるはずです。</p>
<p>その中でストレージに関しては、<br />
不必要なデータを置かない, データのライフサイクルを短くする, ストレージクラスを最適なものに設定するなどはありますが、<span class="sc_marker blue"><strong>S3にどのようなデータを置くかは各システムで要件が異なってくるため、費用の削減はあまり期待できません。</strong></span></p>
<p>そうなってくるとデータ転送の部分でコストを最適化するのが必要になってきます。</p>
<h2>通信量削減の取り組み</h2>
<h3>イメージ図</h3>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 50%;"><a href="https://otonan-syusyoku.work/archives/1842/flow-drawio" rel="attachment wp-att-1883"><img fetchpriority="high" decoding="async" src="https://otonan-syusyoku.work/wp-content/uploads/2024/09/flow.drawio.png" alt="" width="722" height="514" class="aligncenter size-full wp-image-1883" srcset="https://otonan-syusyoku.work/wp-content/uploads/2024/09/flow.drawio.png 722w, https://otonan-syusyoku.work/wp-content/uploads/2024/09/flow.drawio-300x214.png 300w" sizes="(max-width: 722px) 100vw, 722px" /></a></td>
<td style="width: 50%;"><a href="https://otonan-syusyoku.work/archives/1842/aws-s3-request-cosst" rel="attachment wp-att-1880"><img decoding="async" src="https://otonan-syusyoku.work/wp-content/uploads/2024/09/aws-s3-request-cosst.png" alt="" width="632" height="308" class="aligncenter size-full wp-image-1880" srcset="https://otonan-syusyoku.work/wp-content/uploads/2024/09/aws-s3-request-cosst.png 632w, https://otonan-syusyoku.work/wp-content/uploads/2024/09/aws-s3-request-cosst-300x146.png 300w" sizes="(max-width: 632px) 100vw, 632px" /></a></td>
</tr>
</tbody>
</table>
<h3>やりたいこと</h3>
<p><span class="sc_marker blue"><strong>S3に゙保管しているコンテンツを毎回S3からダウンロードすることを辞めるための設計</strong></span>です。</p>
<p>これにより、キャッシュを用いてS3からの転送量を大幅に減らすことができます。（サイトへのアクセスが多ければ多いほど今回の設計は意味を増してくると思います。</p>
<p>&nbsp;</p>
<p>添付した画像のフローを改めて文字に起こします。</p>
<ol>
<li><strong>ページアクセス</strong>後に、必要なViewやCSS、画像などがリクエストされます。</li>
<li>まずアプリケーションサーバー（EC2）にコンテンツがキャッシュされているか確認します。</li>
<li>キャッシュに存在する場合は、そのままレスポンスを返します（転送料金が発生しません）。</li>
<li>キャッシュに存在しない場合は、S3からコンテンツを取得し、その後キャッシュします（S3へのアクセスを減らす）。</li>
</ol>
<h3>ChatGPT に計算してもらった</h3>
<pre class="line-numbers"><code class="language-php">### 東京リージョン（Asia Pacific (Tokyo)）でのS3のデータ転送料金

2023年9月現在、東京リージョンでのS3のデータ転送料金は次の通りです：

- 最初の1GB: **無料**
- 1GB～10TBまでのデータ転送: **$0.114/GB**

これに基づいて、東京リージョンでの転送料金削減を計算します。

### 仮定
- 1回のアクセスでS3からダウンロードされるデータの量：**1MB**
- 1日のアクセス数：**10,000回**
- キャッシュ成功率：**80%**
- 東京リージョンでのS3データ転送料金：**$0.114/GB**

### 計算式（東京リージョン）
1MBのデータが10,000回ダウンロードされる場合：
```
1MB × 10,000 = 10,000MB = 10GB
```

#### S3へのアクセスがない場合のコスト（全アクセスがS3の場合）
```
10GB × 0.114 = $1.14
```

#### キャッシュ導入後のコスト
キャッシュ成功率80%の場合、S3へのアクセスが20%：
```
10,000 × 0.2 = 2,000回
```

2,000回分のダウンロードデータ量：
```
1MB × 2,000 = 2,000MB = 2GB
```

これに対する転送料金：
```
2GB × 0.114 = $0.228
```

#### 削減額
S3にすべてのリクエストを送る場合のコストは**$1.14**、キャッシュを利用した場合のコストは**$0.228**。
したがって、削減できる金額は：
```
$1.14 - $0.228 = $0.912
```

### 結論
キャッシュを使うことで、東京リージョンの場合は、
1日あたり約**$0.912**の転送料金削減が見込めます。

これを1ヶ月（30日）分に換算すると、約**$27.36**の削減が期待できます。

もちろん、アクセス数やキャッシュ成功率、ダウンロードデータのサイズによって結果は変わりますが、
このざっくりとした計算での削減効果は**80%**程度です。
</code></pre>
<h3>注意点①</h3>
<p><span class="sc_marker blue"><strong>キャッシュクリアの方法を適切に設定しない場合、全てのコンテンツリクエストがキャッシュデータを返却してしまいます。</strong></span></p>
<p>各方面から以下のようなお叱りが届いてしまうので、今回ご紹介した設計を取る場合は、しっかりとキャッシュクリアの戦略を練りましょう。。。</p>
<div class="voice left">
<div class="icon">
<p><img decoding="async" src="https://otonan-syusyoku.work/wp-content/uploads/2020/10/名称未設定のデザイン-69.png" /></p>
<div class="name">エンドユーザー</div>
</div>
<div class="text sc-inner-content sc_balloon left blue">
<p>ユーザーから保存したデータが古いままなんだけどどうなってるの!?</p>
</div>
</div>
<div class="sc_frame_wrap inline orange">
<div class="sc_frame_title">キャッシュクリア</div>
<div class="sc_frame">
<p>&#8211; バッチ処理にて定期的に削除する（1日1回、6時間毎に&#8230;<br />
&#8211; データの書き換えのタイミングで該当のキャッシュを削除</p>
</div>
</div>
<h3>注意点②</h3>
<p><span class="sc_marker blue"><strong>アプリケーションサーバーにコンテンツを配置するので、アプリケーションサーバー自体のストレージを圧迫する可能性が大いにあります。</strong></span><br />
アプリケーションサーバーのストレージを外部に移す目的でS3を導入している場合は、今回の手法は取れないので、CDNサービス等を用いてキャッシュさせるのも一つの手になってくると思います。</p>
<h3>注意点③</h3>
<p>注意点②と同様にアプリケーションサーバーにコンテンツを配置するが故の問題として、センシティブなデータをアプリケーションサーバーに配置する可能性があります。<br />
例： 個人情報の類のコンテンツ（運転免許証、何らかの明細）</p>
<p>これらを一時的にではありますが、アプリケーションサーバーに配置するのがシステム要件的にNGの場合は、絶対に今回の手法は取れません！</p>
<h2>最後に</h2>
<p>ちょいとした工夫でコストダウンを見込めますので、皆さんも試してみて欲しいですー！</p>
<p>システムの要件等で導入できなければごめんさい！！</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1842/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CakePHPのmatchingで困った話</title>
		<link>https://otonan-syusyoku.work/archives/1729</link>
					<comments>https://otonan-syusyoku.work/archives/1729#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sat, 20 Apr 2024 11:49:20 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[古の技術]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1729</guid>

					<description><![CDATA[古の技術と呼ばれることも多くなってきたCakePHPの記事です。 CakePHPを使った開発の際に躓いたポイントを解説しますぅ 概要 データ取得時に関連データを合わせて取得したい。関連データの取得時には条件に一致しないデ [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>古の技術と呼ばれることも多くなってきたCakePHPの記事です。</p>
<p>CakePHPを使った開発の際に躓いたポイントを解説しますぅ</p>
<h2>概要</h2>
<p>データ取得時に関連データを合わせて取得したい。関連データの取得時には条件に一致しないデータが</p>
<p>関連データを用いて取得条件を絞りこみ、関連データが条件に一致しない場合、親も取得しないようにしたい。</p>
<h2>関連データの取得方法</h2>
<p><span>CakePHPでのデータ取得は<code>matching</code>, <code>innerJoinWith</code> を用いることで、SQLのJOINに類似した操作が実現できます。</span></p>
<p><span>これにより、特定の関連データに基づく厳密なデータフィルタリングが可能となります。</span></p>
<p>matchingはN:Nの関係性のときに強力な関数となるが、条件指定の際に思った挙動にならないため注意が必要。</p>
<h2>MatchingとInnerJoinWith</h2>
<p>対応表として以下の形になる。</p>
<table style="border-collapse: collapse; width: 100%;">
<tbody>
<tr>
<td style="width: 33.4449%;"></td>
<td style="width: 33.2217%;">matching</td>
<td style="width: 33.3333%;">innerJoinWith</td>
</tr>
<tr>
<td style="width: 33.4449%;">関連データの取得</td>
<td style="width: 33.2217%;">できる</td>
<td style="width: 33.3333%;">できない</td>
</tr>
<tr>
<td style="width: 33.4449%;">関連データの条件指定</td>
<td style="width: 33.2217%;">できる</td>
<td style="width: 33.3333%;">できる</td>
</tr>
<tr>
<td style="width: 33.4449%;">条件一致しない場合の挙動</td>
<td style="width: 33.2217%;">空として</td>
<td style="width: 33.3333%;"></td>
</tr>
<tr>
<td style="width: 33.4449%;">生成されるSQL</td>
<td style="width: 33.2217%;"><span>Inner Join</span></td>
<td style="width: 33.3333%;"><span>Inner Join</span></td>
</tr>
<tr>
<td style="width: 33.4449%;">使用どころ</td>
<td style="width: 33.2217%;">N:Nの関係のときにとりあえず便利</td>
<td style="width: 33.3333%;"><span>関連データに基いて結果を計算したいとき使う<br />
(サブクエリとして取ったり…</span></td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1729/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>CakePHPのURL生成で死んだ話</title>
		<link>https://otonan-syusyoku.work/archives/1731</link>
					<comments>https://otonan-syusyoku.work/archives/1731#respond</comments>
		
		<dc:creator><![CDATA[hrokig2]]></dc:creator>
		<pubDate>Sat, 20 Apr 2024 10:07:10 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[生涯独学]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[古の技術]]></category>
		<guid isPermaLink="false">https://otonan-syusyoku.work/?p=1731</guid>

					<description><![CDATA[古の技術と呼ばれることも多くなってきたCakePHPの記事です。 CakePHPのマニュアルのせいで時間取られたので、備忘録として残しておきっます。 概要 Commandクラスからメールに添付するURL生成を行いたい。  [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>古の技術と呼ばれることも多くなってきたCakePHPの記事です。</p>
<p>CakePHPのマニュアルのせいで時間取られたので、備忘録として残しておきっます。</p>
<h2>概要</h2>
<p>Commandクラスからメールに添付するURL生成を行いたい。</p>
<p>その際に生成されるURLはHTTPS化されたURLを添付したい。</p>
<p>&nbsp;</p>
<p>現環境 ↓</p>
<ul>
<li>CakePHP 4.4</li>
<li>PHP 8.1</li>
</ul>
<h2>困ったこと</h2>
<p><span class="sc_marker blue"><strong>ControllerやViewでURL生成を行うと現在のoriginを見るのですが、Commandクラスなどoriginを見れないものは明示的にオプションを示さないといけないのがCakePHPの掟です。</strong></span></p>
<p>今回の目的である、CommandクラスからHTTPS化されたURLを添付するにはどうしたらいいかというと、マニュアルのとおりに、生成時のオプションにHTTPSの指定をする必要がある。</p>
<blockquote><p>_https true にすると普通の URL から https に変換します。 false にすると、強制的に http になります。</p>
<p><cite class="blockquote_ref"> <a href="https://book.cakephp.org/4/ja/development/routing.html#id25" target="_blank" rel="noopener noreferrer">URL の生成</a> </cite></p></blockquote>
<pre class="line-numbers"><code class="language-php">$routes-&gt;url([
    'controller' =&gt; 'コントローラー名',
    'action' =&gt; 'アクション名',
    '_https' =&gt; true,
]);</code></pre>
<p>&nbsp;</p>
<p>これだけでHTTPSを指定できるのは、便利だなと思った矢先、HTTPSになっていない。</p>
<p>Routerクラスのインポート、スペルミスなどを確認してもHTTPS化ができていない。</p>
<p>&nbsp;</p>
<p>どうしてもHTTPS化が必須の要件だった、CakePHP3のマニュアルも読んでみた。</p>
<p><strong>驚きの展開だったのが、Cake3とCake４でオプションの内容が違うことがわかった。</strong></p>
<blockquote><p>_ssl true にすると普通の URL から https に変換します。 false にすると、強制的に http になります。</p>
<p><cite class="blockquote_ref"> <a href="https://book.cakephp.org/3/ja/development/routing.html#id23" target="_blank" rel="noopener noreferrer">URL の生成</a> </cite></p></blockquote>
<p>&nbsp;</p>
<p>以下の形で指定すると今回の目的を達成することができた。</p>
<pre class="line-numbers"><code class="language-php">$routes-&gt;url([
    'controller' =&gt; 'Articles',
    'action' =&gt; 'index',
    '_ssl' =&gt; true,
]);</code></pre>
<p>&nbsp;</p>
<p>枯れた技術を使うのはちょっと手間がかかりますねぇ。</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://otonan-syusyoku.work/archives/1731/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
