アクセスカウンタを作るときのデータベースについて考えてみます。
RDB
例えばCloud SQL/MySQLならこんな感じのテーブルでしょうか。
PVカラムをインクリメントしていけばカウントできそうです。
問題点
MySQLでは更新時にロックをかけます。
複数人が同時にアクセスすると1人1人処理する必要があるため、パフォーマンスが悪いです。
対策
1つのページに対するレコードの数を増やし、増やした行の中からランダムな行でインクリメントするようにします。
アクセス数を出すときは、それぞれのレコードを集計して出します。
レコードを増やした分だけ同時アクセスに対するパフォーマンスの向上が期待できます。
ただし、あらかじめどの程度アクセスがあるかを予測した上でレコードの数を考える必要があります。
NoSQL
例えばGCPのCloud Datastoreとしたら、こんな感じでしょうか。
pvをインクリメントすればアクセス数をカウントできそうです。
class Pages(ndb.Model): page = ndb.StringProperty(indexed=True) pv = ndb.IntegerProperty(indexed=False)
問題点
Cloud Datastoreは1つのエンティティに対しての変更が1回/1secに制限されています。
そのため、上記実装だと1秒に1アクセスしか捌くことができません。
対策
高パフォーマンスなkey-value NoSQLを利用する。
(自信ない対策案です...)
GCPだとBigtableとかでしょうか。Bittableは大規模データ用なので微妙かもしれませんけど。
Firesttoreでは分散カウンタを紹介しています。
先述したMySQLの対策と同じコンセプトですかね。
ユニークユーザーを数える場合
上記データベースではPVは計測できてもUUはわかりません。
UUも数える場合は、来訪者が来るたびにIPでuserを判別し、重複不可で追加していけばいいと思います。
最後にまとめてSUMでUUがわかります。
これならロックの心配もありません。
あるいはページごとにテーブルを作成するのもいいかもしれません。
その他
メルカリのPV管理では一度プールしてからまとめてSQLを更新しているみたいです。