GAEでTwitterみたいなフォロー関係を実現する - fanout problem
http://dl.google.com/io/2009/pres/W_0415_Building_Scalable_Complex_App_Engines.pdf
古い資料だけど。何か驚くべき手法が書かれているのか?と思って読んだらそういうわけでもなく。大勢のフォロワーに向けてパブリッシングするメッセージエンティティに、フォロワーのキーをリストプロパティでもっておけということだった(下記コードはイメージです)。
public class Message implements Serializable { private Key key; private Key senderKey; private String body; private List<Key> followerKeys; }
あとからフォローしたりアンフォローした場合は、タスクでせっせと過去メッセージのfollowerKeysを書き換えるんでしょう。
エンティティあたりインデックス数の制限により、この設計ではフォロワー数の上限が10,000(インデックス数上限20,000として)になってしまうけれど、どうせそんな規模にはそうそうならないでしょう。そこだけ許容してしまえば、とてもシンプルに作れそう。
もうひとつ問題があって、リストプロパティのデシリアライズコストが馬鹿にならないらしい。この資料が作成された当時はどうにもならなかったようだけど、今のGAEにはProjectionクエリがあるので、followerKeysは取得せず欲しいプロパティだけを取得することができる。これはこれでまた制約があって、たとえばProjectionクエリで取得するプロパティはインデックス作成対象になっていなければならないので、Text型などは使えなかったりするのだけど。