| @技術/プログラミング

キャッシュ

CloudFront 転送量削減の試みで色々やっていて、そういやウェブサイトのキャッシュについての説明記事っぽいの読んだことないし、開発現場だと「じゃあキャッシュすればいいじゃん」みたいな発言が行き交うけど、ひとくちにキャッシュと言っても色々あって、ウェブ開発始めたばかりの人にはよく分からないんじゃないかと思ったので書いておきます。

キャッシュの目的

キャッシュの目的.png

キャッシュの目的は大きく二つあって、コンテンツ表示の高速化とコストの削減がある。コンテンツの表示高速化は、時間のかかる処理の結果を捨てずに再利用して二回目以降の表示を高速化すること、コストの削減は、処理結果の再利用によってコンピューターの利用時間を減らしたり、データの通信量を減らすことをそれぞれ目的としている。表示高速化とコスト削減はどちらか一方だけを達成するものではなく、多くの場合で両方が同時に実現される。

キャッシュに向いているコンテンツ

キャッシュには向いているコンテンツと向いていないコンテンツがある。

キャッシュに向いているコンテンツ.png

ウェブサイトで配信するものに関して何でもキャッシュできるわけではなく、多くの人が共通して閲覧するものか、更新頻度が低いものでないとキャッシュしてはいけない。更新頻度が低くて多くの人が共通して閲覧するもの(画像、 CSS 、 JavaScript など)はキャッシュしやすい。だがショッピングサイトの購入履歴などは人それぞれなので一律にキャッシュしてはいけない。

キャッシュの種類

キャッシュにはブラウザーキャッシュとサーバーサイドのキャッシュがある。

キャッシュの種類.png

ブラウザーキャッシュ

ブラウザーキャッシュは、同じ人が繰り返し訪問するサイトで繰り返し利用されるサイト内画像や JavaScript 、 CSS (静的コンテンツ)に対して提供するのに向いている。二回目以降のアクセス時に前回端末にダウンロードした内容を使い回し、転送量を削減してユーザーの閲覧体験を高速化する。

ブラウザーキャッシュ図解.png

同じ人が繰り返し訪問しないタイプのサイト( SNS でバズって多くの人が訪れるが、一ページ見ただけで離脱するようなサイト)ではブラウザーキャッシュをフルに効かせても転送量の削減効果はない。逆に一度訪れた人が何度も訪れるような再訪率の高いウェブサイトでは、静的コンテンツに対して Cache-Control ヘッダーを付与することでブラウザーキャッシュを効かせ、転送量の削減とコンテンツの表示速度を高速化させることができる。

ブラウザーキャッシュを聞かせるには、適切な HTTP ヘッダー( Cache-Control ヘッダーなど)を付けてレスポンスを返せばよい。

サーバーサイドキャッシュ

サーバーサイドでキャッシュできるのは多くの人が共通して閲覧する、更新頻度の低いデータだけということに注意が必要。ログインが必要なサイトで、アクセスする人によってコンテンツを出しわけないといけないようなシステムではサーバーサイドのキャッシュはあまり利用できない。

サーバーサイドキャッシュ図解.png

サーバーサイドのキャッシュには転送量の削減効果はない(少なくとも自サイト訪問者との通信では)が、ランキング集計処理や外部 API の呼び出しなど CPU への負荷や時間がかかる処理の結果をキャッシュし、コンテンツの表示を高速化したいときに有効。

例えばこのサイトでは Amazon のアフィリエイトを利用しているが、 Amazon の API にリクエスト回数制限やリクエスト間隔制限があるので適度にキャッシュを行い、リクエスト回数制限に引っかからないようにしている。

サーバーサイドのキャッシュのやり方は色々ある。アプリケーションにキャッシュするためのコードを書いてメモリ上に保持したり、テキストファイルに保存したり、データベースに保存したり、 Redis などを使ったり。ウェブサーバーのキャッシュを使う方法もある。このブログでもいくつかのキャッシュ機構を組み合わせている。

アプリケーションキャッシュ.png

表示に関わる部分の一部をキャッシュする場合や、キャッシュの無効化をアプリケーションでコントロールしたい場合はアプリケーションでキャッシュする必要がある。

ウェブサーバーキャッシュ

レスポンス全体をキャッシュしてよい場合にはウェブサーバーのキャッシュを使うとよい。その方がアプリケーション層までリクエストが届かず、コンピューターリソースを節約できる。

様々なキャッシュの組み合わせ

更新頻度が低く、多くの人が共通して閲覧するコンテンツはサーバーサイドでもキャッシュできるしブラウザーキャッシュを効かせることができる。画像、 CSS 、 JavaScript などがそれで、これらのファイルはよく CDN ( Content Delivery Network )から配信される。 AWS だと CloudFront というのがある。この手のサービスはサーバーサイドのキャッシュとブラウザーキャッシュを効かせることに特化したもので、コンテンツの転送量を抑えつつウェブサイトの表示速度を高速化してくれる。

CDN もそうだが、サーバーサイドキャッシュとブラウザーキャッシュを併用すると、コンテンツを更新したいときに問題が出てくる。画像ファイルを新しいものに差し替えたが CSS が更新されず古いキャッシュが参照され、画像が非表示になってしまったり、ということが発生する。そういうことが起こらないように、 HTTP にはいくつか仕組みがある。

CDN だと ETag も自動付与してくれて、コンテンツの衝突を抑えてくれる。 CDN はよくできているのでよく分からない人はまずは CloudFront を使って勉強してみるとよいだろう。

特に注意が必要なのがアプリケーションキャッシュとウェブサーバーキャッシュの組み合わせだ。異なるレイヤーでキャッシュを効かせてしまうと、キャッシュを無効化したいときに狙い通りに無効化されず、意図しない障害になってしまったりする。コンテンツの特性に応じて、キャッシュは一つのレイヤーで行うようにするとよいだろう。画像や CSS はウェブサーバーでキャッシュし、更新頻度が低いが動的に生成される JSON はアプリケーションレイヤーでキャッシュするなど。

まとめ

  • ウェブサイトのコンテンツは何でもキャッシュすれば良いわけでない
  • サーバーサイドのキャッシュとブラウザーキャッシュの違いを理解する
  • 多段キャッシュに注意(特にアプリケーションキャッシュとウェブサーバーキャッシュの併用)

| @Mac/iPhone

Mac や iOS 用カレンダーアプリの Fantastical が買い切り型のビジネスモデルからサブスクリプションに移行した。

Fantastical 2 を買っていたユーザーは既存機能は無料で使えるみたいだけど、 iPhone 上でカレンダーセットを複数使ったり、複数のカレンダーに存在する別のイベントを統合して表示する機能はサブスクリプションに登録しないと使えない。

サブスクリプション、よさげなビジネスモデルに見えるが、何でもサブスクリプションにすればよいというものではないと思う。サブスクリプションにすることで、ビジネス側にもユーザー側にもメリットがなければ意味がない。 Netflix や Amazon Prime 、 Adobe CC に関しては個別に買ったりレンタルしてたら膨大な金額がかかるものがサブスクリプションになることで月々の負担を抑えながら利用でき、その結果ユーザー数が増えることでビジネスサイド、ユーザーサイドの両方にメリットがある。一方で、もともと 5000 円程度の買い切りソフトウェアが月額 600 円のサブスクリプションに移行しても既存ユーザーにとっては値上げでしかなく、 5000 円の買い切り価格に逡巡していたユーザーが加入する後押しにもならないのでパイが拡大しない。誰にとってもメリットがない。こういうのは本当に無駄なのでやめてほしい。

| @ブログ

GEORGIA at Dark

一つ前の記事で結構 Feed Crawler からのアクセスが多いことがわかった。

フィードは PubSubHubbub で利用する都合上、キャッシュしていない。しかもいまは 20 件記事を配信しているのでレスポンスが遅い。平均で 4 秒くらいかかっている。何とか効率的にキャッシュできないものかと思って FeedBurner を試してみることにした(サービス終了したかと思っていたけど、 .jp ドメインは終了しているものの .com の方は Google の中のサービスとして生き残っていた)。

FeedBurner からのアクセスの時だけ動的にフィードを生成し、それ以外の UA からのアクセスのときは FeedBurner の URL にリダイレクトするようにしてある。この記事を公開してちゃんと機能しているか確認したい。

追記

PubSubHubbub が機能しなくなってしまった😰 Googlebot に対しても動的なフィードを読ませないといけないのかもしれない…

追記 2020-04-08

PubSubHubbub の Google の Crawler は FeedFetcher-Google という文字列を含んでいるようだったので、以下のような記述を Nginx の設定ファイルに加えた。

if ($http_user_agent ~* (FeedBurner|FeedFetcher-Google\;)) {
    proxy_pass http://puma;
    break;
}

なぜ ; (セミコロン)を付けているのかというと、 Feedly などの Crawler も FeedFetcher-Google を名乗っているから。 Google の Crawler は FeedFetcher-Google のすぐ後ろにセミコロンを付けている。

Screenshot - 2020-04-08 08.58.24.png

Google と FeedBurner の Crawler にのみ本体のフィードを読ませ、それ以外の Crawler には FeedBurner のフィードを読ませるようにしている。

| @ブログ

今宿駅近くのバー

このブログのフィードを誰が読みに来ているのか調べてみた。一ヶ月間で 100 回以上見に来ている上位の UA は以下。

Feed Crawler Ranking

なんと一位はフィードリーダーの bot ではなく Slackbot だった。 Googlebot よりも多い。もはや Slack が一番のフィードリーダーになっているのかもしれない。こうなると PubSubHubbub とかの仕組みに乗っかって無駄なクローリングが発生しないようにして欲しい。フィードを購読する Slack の Workspace が増えるほどクローリング回数が増えてしまうと負荷がバカにならない。

三番目の Hatena::Russia::Crawler/0.01 ってのは Hatena と名前に入っているが本当にはてなのクローラーなのだろうか。 Russia という文字列が怪しい。

Feedly はもっと多いかと思ったが非常に少なかった。意外と Fastladder が多い。みんなどこかのサーバーで運用しているのだろう。ご苦労様です。

今回、ログを調べていて Feedeen といったサービスが存在していることを初めて知った。他に Feedbin などいくつか有料の RSS リーダーが存在しているようだ。 Google Reader や Livedoor Reader が終了した後、国内外で有料のフィードリーダーが開発されサービス提供されているのだろう。 Feedeen は料金が月 200 円で安い。日本人が作っているというのも安心感がある。自分は Google Reader 終了後はまず The Old Reader を使っていたけどいまは Inoreader を使っている。 Inoreader も開発元はルーマニアのインディー感あふれる会社で、フィードリーダーの世界は独立系の企業やデベロッパーによって活況を呈しているようだ。よいことだと思う。昔のインターネットを思い出す。

ちなみにフィードリーダー系の Crawler は UA にそのフィードの購読者数を表示しているのがおもしろい。こんだけ購読者数がいるんですよ、ということをブログ主に伝えて UA でブロックされないようにしているのだろう。

| @技術/プログラミング

DSC_4022.jpeg

Amazon Product Advertising API ( PA API )が 5.0 になるらしい。 4.0 は 3 月で廃止になるそうだ(当初は 2 月 11 日と言われていたが、 3 月まで伸びたみたい)。

最近 4.0 に対応させたのにな、と思って調べてみたら何と 4.0 対応したのは 10 年以上前だった。

PA API 4.0 までは AWS アカウントで利用する感じ1だったが、 PA API 5.0 では AWS から独立して Product Advertising API 専用のアカウントを登録しなければならないようだ。

AWS は US Amazon でアカウントを作るのに PA API のレポート画面へのログインでは Amazon Japan のアカウントを使うのは変だなと思っていたけど、 PA API 専用アカウントを設けることでその辺のねじれも解消されるだろう。

クライアントライブラリにはこれまで ecs という gem を使ってきたが、 PA API 5.0 対応はされてなくて、別の人が作った vacuum という gem に乗り換えた。

ecs という gem の名前に違和感をもつ人がいるかもしれない。いまでは Amazon で ECS といえば AWS の ECS ( Elastic Container Service ) のことを指すが、昔は Amazon 自身が PA API という名前ではなく Amazon ECS という名前でアフィリエイト用のシステムを提供していた。 Amazon は命名が色々紛らわしい。

PA API 5.0 は RESTful API ではなく GraphQL のような感じで、欲しいフィールド名を指定して API リクエストする感じになっている。レスポンスのサイズが小さくなって便利になった。

ちなみに移行ガイドは以下にあります。

DSC_4119.jpeg


  1. 10 年前にペパボの面接を受けに行ったときに「 AWS 使えますか?」と聞かれて「はい、使えます。アフィリエイトで小銭を稼いでいます」と答えてしまった。 

| @散財

iPhone 11 表面

親父にあげていた iPhone 6 のバッテリーが寿命のようで、 iPhone 7 を譲るために新しい iPhone を買った。 iPhone 11 の 128GB にした。 88000 円くらい。魅惑のオリコローン、 24 回払い分割金利手数料無料で購入した。 iPhone 7 は 2016 年末に買ったのでまるまる 3 年使った。

外観と Face ID

ごっついレンズが複数付いた外観は好きになれなかった。 iPhone 11 Pro は高すぎて買えなかったが外観的にも個人的に受け入れられなかった。 iPhone 11 のレンズ二つの外観もいびつに見えたが、いまさら iPhone XR を買うのは何だかなという感じなので消極的に iPhone 11 を選んだ。

iPhone 11 背面

ケースを付けるかは迷った( iPhone 7 はケースを付けない状態が一番使いやすかった)が、結局付けた。ケースを付けないとレンズの出っ張りが邪魔で、背面を下にしてテーブルに置いたときに安定しない(ガタガタする)。レンズ面の出っ張り対策としてケースは必要だと思った。ケースは Amazon で評価のよかった以下を騙されたと思って買ったけど実際とても良かった(サクラレビューではないようだった)。

ホームボタンと Touch ID のないモデルは初めてで、 Face ID は Apple Pay の支払時に不便かなと懸念していたが、スリープボタンをダブルタップして読み取り機にかざす前に Face ID 認証すればよいのでかえって便利になった。 NFC 認証のスピードも速くなっている気がする(コンビニのレジでもたつくことがなくなった)。

Face ID になってよかったことに、スクリーンプロテクターが全面を覆い隠せるようになったことがある。 Touch ID 方式だとホームボタンは指紋認証のために覆うことができず、スクリーンプロテクターに妙な穴が開いてたりしていて不格好だった。全面を覆えるものを買ったがとても良い。何もはっつけていないみたいに見える。

スクリーンプロテクターは以下のものを買った。貼り付け時に貼り付け位置を失敗しないようにサポートするプラスチックの枠が付いていてスーパー便利だった。これまで位置ずれを気にしながら貼っていたのがバカみたいだった。

重い

iPhone 11 、とにかく重い。調べたところ 194g のようだった1。 iPhone 7 は138g だったみたいなので 56g くらいしか重くなってないのに随分重く感じる。検証機として会社から借りてる Pixel 3a に比べても重い。 50g の差がスマートフォンでは決定的な違いになるんだなと思った。

iPhone 11 と Pixel 3a

電池のもち

重くなったおかげか、バッテリー容量が増えていて電池がとてもよくもつようになった。 iPhone 7 はバッテリーを一度 Apple Store で交換してもらったが、それでもヘビーに使うと一日電池がもたなかった。 iPhone 11 で不意に電池切れになって困った、ということは起こりそうにない。

写真

写真に関しては、日中に撮れる写真の画質は iPhone 7 の頃と大差ないと感じる。もっと綺麗な写真が撮れるかなと思ったけどそうでもなかった。ポートレートモードも試したが、ぼかし処理が甘くて(特に物撮り)被写界深度的に「そこ違うんだけどな」というところがぼけてしまったりする。一眼で撮るのには及ばない。

広角レンズはおもしろい。室内や街並みなどは広角で撮ると楽しい。

街並み

川や道路の大きさ、スケール感が伝わる。

博多川 リバレイン通り

室内

店内の壁一面に手書きのいろんなメニューが貼ってある面白定食屋の様子。店内は広くなく、標準のカメラでは到底壁一面の様子などを写すことはできないが、広角レンズで撮影することができた。

定食屋店内 定食屋店内

ナイトモード

ナイトモードもなかなかおもしろい。 NIKON Z6 を買って最近のカメラの夜景撮影能力に感動していたが、 iPhone 11 のカメラで撮る夜景も大分すごい。以下は近所の山に夜景を撮りに行ったやつの比較。

街の夜景

Z6 で撮った写真は三脚に固定して撮っている。一方 iPhone は手持ち。これはすごい。

今山から見る今宿( NIKON Z6 で撮影)

今山から見る今宿( iPhone 11 で撮影)

夜の踏切

Z6 は ISO 感度が 51200 まで上がってしまってノイズだらけになってしまっている。 iPhone 11 の方は ISO 800 で撮って補正しているのでノイズが少ない。

今宿の踏切( NIKON Z6 で撮影)

今宿の踏切( iPhone 11 で撮影)

こんな感じで、ミラーレスカメラと同等の、状況次第ではミラーレス以上に綺麗な夜景写真が撮れてしまう。画像補正処理技術の向上すごい。


最初は「う〜ん」と思っていた iPhone 11 の外観や重さだけど、使っていくうちに広角レンズの便利さや電池のもちの良さなど、 iPhone 11 の良さがしみじみとわかってきた。値段は iPhone 11 Pro ほどには高くないし、買ってよかったなと思える端末でした。便利。

| @散財

ペーパードリッパーホルダー

概要

ドリップバッグのコーヒーはお湯に浸かって味が薄くなるが、ドリップバッグホルダーを導入してドリップをしやすくなりコーヒーの味が改善(濃く抽出される)。付属の受け皿で水切りができ、片付けも楽になった。


以前は会社で豆を挽いてコーヒーをいれて飲んでいたが、最近忙しくて豆から挽いてコーヒーいれて飲んでるような余裕がない。とはいえ全自動マシンのやつは飽きてしまったのでドリップバッグのやつを買って飲むようになった。まずはドトールのものを飲んでみてなかなか悪くないとは思ったが、どこまでお湯を注げばよいかがわかりづらい点や、お湯に完全に浸ってしまうことにより片付け時に水がポタポタと垂れてしまう点でいまいち体験が良くなかった。

そんななかコーヒードリップバッグホルダーというアイテムの存在を知った。

試しに買ってみるにはちょっと値段が高いなと思ったがリストカット感覚で注文してみた。テレビか何かで紹介されたばかりのようで Amazon には在庫がなく、届くまで二週間くらい待った。

使うときはこんな感じで使う。カップの上にドリップバッグホルダーをセットし、その上にドリップバッグをかける。

カップの中の様子を見ながらお湯を注げるのでどこまで注げば良いかわからないという問題や、ドリップバッグがお湯にどっぷり浸かってびちゃびちゃになるという問題が解決する。

おまけに受け皿も付いているので、まだ少し水がしたたる状態でカップから引き上げてもとりあえず置いておく場所を確保できる。とても便利。

さらにこれは期待していなかったことだが、ドリップバッグをお湯の中にドボンとつけないことで味もおいしくなる気がする。これまでドリップバッグではコーヒーの味が薄めになるのが不満だった。大抵のドリップバッグは豆の量が 7g 程度で少なめなので仕方がないのかなと諦めていたが、ドリップバッグホルダーを使うようになってから濃いめに抽出されるようになった。ドボンとお湯に浸からないおかげでお湯がコーヒー豆の中を通り、コーヒーの成分がちゃんと抽出されるのだろう。

図で説明するとこんな感じ。

ドリップバッグホルダーなし: お湯がすぐにフィルターの中から抜け出してしまい、十分にコーヒーの成分が抽出されない ドリップバッグホルダーあり: お湯が豆の中を通り抜けてからフィルターの外に出て行き、コーヒーの成分がよく抽出される

というわけでドリップバッグホルダー、めちゃおすすめです。

ドリップバッグは以下を使ってます。 100 パックで 2000 円くらいで安い!