私は自分のソーシャルネットワークを開発していますが、ユーザーのアクションのストリームの実装例をWeb上で見つけていません...たとえば、各ユーザーのアクションをフィルターする方法は?アクションイベントを保存する方法 アクションストリームとそのアクションにどのデータモデルとオブジェクトモデルを使用できますか?
私は自分のソーシャルネットワークを開発していますが、ユーザーのアクションのストリームの実装例をWeb上で見つけていません...たとえば、各ユーザーのアクションをフィルターする方法は?アクションイベントを保存する方法 アクションストリームとそのアクションにどのデータモデルとオブジェクトモデルを使用できますか?
回答:
要約:約100万人のアクティブユーザーと1億5,000万件の保存されたアクティビティについて、私は単純にしています:
Redisにクエリを送信して任意のユーザーのアクティビティストリームを取得し、必要に応じてdbから関連データを取得します。ユーザーが時間をさかのぼって参照する必要がある場合は、時間を指定してデータベースのクエリにフォールバックします(これを提供した場合でも)。
約1500万のアクティビティを処理するために、私はプレーンな古いMySQLテーブルを使用します。
次のようになります。
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
activity_type
アクティビティのタイプsource_id
、アクティビティが関連するレコードを教えてくれます。したがって、アクティビティタイプが「お気に入りの追加」を意味する場合、source_idがお気に入りのレコードのIDを参照していることがわかります。
parent_id
/ parent_type
私のアプリのために便利です-彼らは活動が関連するものを私に教えてください。本がお気に入りの場合、parent_id / parent_typeは、アクティビティが特定の主キー(id)を持つ本(タイプ)に関連していることを通知します
私(user_id, time)
はである活動に索引を付け、クエリを行いuser_id IN (...friends...) AND time > some-cutoff-point
ます idを破棄し、別のクラスター化インデックスを選択することは良い考えかもしれません-私は実験していません。
かなり基本的なものですが、機能し、シンプルで、ニーズの変化に応じて簡単に操作できます。また、MySQLを使用していない場合は、インデックスごとに改善できる可能性があります。
最新のアクティビティにすばやくアクセスできるように、私はRedisを実験しています。Redisはすべてのデータをメモリに格納するため、すべてのアクティビティをそこに配置することはできませんが、サイトで頻繁にヒットする画面のほとんどに十分に格納できます。各ユーザーの最新の100など。Redisを併用すると、次のように機能する可能性があります。
Redisは高速で、1つの接続を介してコマンドをパイプライン処理する方法を提供します。そのため、アクティビティを1,000人の友人にプッシュするには数ミリ秒かかります。
私が話していることの詳細な説明については、RedisのTwitterの例を参照してください:http : //redis.io/topics/twitter-clone
2011年2月の更新現在、5,000万のアクティブなアクティビティがあり、何も変更していません。これと同様のことを行うことの1つの良い点は、コンパクトで小さな行を使用することです。私はより多くのアクティビティとそれらのアクティビティのより多くのクエリを含むいくつかの変更を加えることを計画しており、私は間違いなく物事を迅速に保つためにRedisを使用します。私は他の分野でRedisを使用していますが、これは特定の種類の問題に本当にうまく機能します。
2014年7月更新月間アクティブユーザー数は最大で約70万人です。過去数年間、私は各ユーザーの最新の1000個のアクティビティIDを格納するために(箇条書きで説明されているように)Redisを使用してきました。システムには通常約1億のアクティビティレコードがあり、それらはまだMySQLに保存されており、同じレイアウトです。これらのレコードを使用すると、Redisのメモリを節約でき、アクティビティデータのレコードとして機能します。ユーザーが時間をさかのぼって何かを見つける必要がある場合は、これらのレコードを使用します。
これは賢い、または特に興味深い解決策ではありませんでしたが、うまく機能しました。
JOIN
さまざまなactivity_type
テーブルでどのように実行しますか?それらは、パフォーマンス面で高価な結合ですか?
activity_type
で、必要な他のデータを取得します。
これは、mysqlを使用したアクティビティストリームの私の実装です。3つのクラスがあります:Activity、ActivityFeed、Subscriber。
Activityはアクティビティエントリを表し、そのテーブルは次のようになります。
id
subject_id
object_id
type
verb
data
time
Subject_id
アクションを実行するオブジェクトobject_id
のID、アクションを受け取るオブジェクトのIDです。type
そしてverb
アクション自体説明します(たとえば、ユーザーが記事にコメントを追加すると、それぞれ「コメント」と「作成」になります)、結合を回避するためにデータに追加データが含まれます(たとえば、サブジェクト名を含めることができます)姓、記事のタイトルとURL、コメント本文など)。
各アクティビティは1つ以上のActivityFeedに属し、次のようなテーブルで関連付けられています。
feed_name
activity_id
私のアプリケーションでは、ユーザーごとに1つのフィードとアイテム(通常はブログ記事)ごとに1つのフィードがありますが、それらは自由に設定できます。
サブスクライバーは通常、サイトのユーザーですが、オブジェクトモデル内の任意のオブジェクトにすることもできます(たとえば、記事は彼の作成者のfeed_actionにサブスクライブできます)。
すべてのサブスクライバーは1つ以上のActivityFeedに属し、上記と同様に、次の種類のリンクテーブルによって関連付けられています。
feed_name
subscriber_id
reason
reason
ここのフィールドは、購読者がフィードを購読した理由を説明します。たとえば、ユーザーがブログ投稿をブックマークした場合、その理由は「ブックマーク」です。これは、ユーザーへの通知のアクションを後でフィルタリングするのに役立ちます。
サブスクライバーのアクティビティーを取得するために、3つのテーブルを単純に結合します。WHERE
今のような状態のため、選択するアクティビティが少ないため、結合は高速time > some hours
です。アクティビティテーブルのデータフィールドのおかげで、他の結合を避けています。
reason
フィールドの詳細な説明。たとえば、ユーザーへの電子メール通知のアクションをフィルタリングし、ユーザーがブログ投稿をブックマークした場合(そのため、「ブックマーク」の理由で投稿フィードをサブスクライブした場合)、ユーザーが受け取ることを望まないそのアイテムに対するアクションに関する電子メール通知。ただし、彼が投稿にコメントした場合(したがって、「コメント」の理由で投稿フィードを購読している場合)、他のユーザーが同じ投稿にコメントを追加したときに通知を受けたいです。理由フィールドは、ユーザーの通知設定とともに、この識別(ActivityFilterクラスを介して実装した)に役立ちます。
よく知られている多くの人々によって開発されている活動ストリームの現在のフォーマットがあります。
基本的に、すべてのアクティビティには、アクター(アクティビティを実行する)、動詞(アクティビティのアクション)、オブジェクト(アクターが実行する)、およびターゲットがあります。
たとえば、マックスはアダムの壁へのリンクを投稿しました。
彼らのJSONの仕様は、執筆時点でバージョン1.0に達しています。これは、適用できるアクティビティのパターンを示しています。
これらのフォーマットは、BBC、Gnip、Googleバズゴワラ、IBM、MySpace、Opera、Socialcast、Superfeedr、TypePad、Windows Live、YIID、その他の多くですでに採用されています。
通知システムが大規模なWebサイトでどのように機能するかについての説明は、ソーシャルネットワーキングWebサイトが友達の更新をどのように計算するかというスタックオーバーフローの質問にあると思います。、ジェレミーウォールの答えで。彼はMessage Qeueの使用を提案し、それを実装する2つのオープンソースソフトウェアを示しています。
ソーシャルアクティビティストリームを実装する最良の方法は何ですか?の質問も参照してください。
パフォーマンスと分散型のメッセージキューが絶対に必要です。しかし、それだけではありません。永続データとして何を保存し、一時データとして何を保存するかなどを決定する必要があります。
とにかく、あなたが高性能でスケーラブルなシステムを求めているなら、それは私の友人にとって本当に難しい仕事です。しかし、もちろん、寛大なエンジニアの中にはこれに関する経験を共有している人もいます。LinkedInは最近、メッセージキューシステムKafkaをオープンソースにしました。その前に、FacebookはすでにオープンソースコミュニティにScribeを提供していました。KafkaはScalaで作成されており、最初は実行に時間がかかりますが、いくつかの仮想サーバーでテストしました。本当に速いです。
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/
独自にロールする代わりに、APIを介して使用されるサードパーティのサービスを探すことができます。Collabinate(http://www.collabinate.com)と呼ばれるものを開始しました。これは、グラフデータベースバックエンドと、高度な並行性とパフォーマンスを備えた方法で大量のデータを処理するためのかなり高度なアルゴリズムを備えています。FacebookやTwitterにあるような幅広い機能はありませんが、アクティビティストリーム、ソーシャルフィード、またはマイクロブログ機能をアプリケーションに構築する必要があるほとんどのユースケースでは十分です。