SORU
12 Kasım 2010, Cuma


Nasıl bu PHP/MySQL haber kaynağı geliştirebilirim?

Bana bu en iyi çözüm değil biliyorum diyerek en başından başlayalım. Kludgy bir özellik ve kesmek bir olduğunu biliyorum.Ama bu yüzden buradayım!

Bu soru iş/inşa kapalı some discussion on Quora with Andrew Bosworth, Facebook haber besleme yaratıcısı.

Bir haber besleme yapıyorumtürlü. Sadece PHP MySQL inşa.

alt text


MySQL

Yem için ilişkisel model, iki tablo oluşur. Bir etkinlik gibi bir tablo fonksiyonları günlük; aslında, activity_log adında. Diğer Tablo newsfeed.Bu tablo hemen hemen aynı.

günlük şemaactivity_log(uid INT(11), activity ENUM, activity_id INT(11), title TEXT, date TIMESTAMP)

...veyem için şemanewsfeed(uid INT(11), poster_uid INT(11), activity ENUM, activity_id INT(11), title TEXT, date TIMESTAMP).

Her zaman bir kullanıcı bir şey yokhaber kaynağı, örneğin bir soru sorup, ilgilietkinlik günlüğüne kaydedilirhemen.


Haber üreten besler

Sonraher X dakika(Şu anda 5 dakika, 15-30 dakika sonra değiştirin)Bir cron işi çalıştırınbu senaryo altında yürütür. Bu komut, veritabanındaki tüm kullanıcıların döngüsü, kullanıcının tüm arkadaşları için tüm aktiviteleri bulur ve haber akışına bu faaliyetleri yazar.

Şu anda, bu aktivitesi (ActivityLog::getUsersActivity()) denilen kağıtları saklardı o SQL LIMIT 100 performans yük* bir sebep vardır. *Neden bahsettiğimi biliyorum.

<?php

$user = new User();
$activityLog = new ActivityLog();
$friend = new Friend();
$newsFeed = new NewsFeed();

// Get all the users
$usersArray = $user->getAllUsers();
foreach($usersArray as $userArray) {

  $uid = $userArray['uid'];

  // Get the user's friends
  $friendsJSON = $friend->getFriends($uid);
  $friendsArray = json_decode($friendsJSON, true);

  // Get the activity of each friend
  foreach($friendsArray as $friendArray) {
    $array = $activityLog->getUsersActivity($friendArray['fid2']);

    // Only write if the user has activity
    if(!empty($array)) {

      // Add each piece of activity to the news feed
      foreach($array as $news) {
        $newsFeed->addNews($uid, $friendArray['fid2'], $news['activity'], $news['activity_id'], $news['title'], $news['time']);
      }
    }
  }
}

Haber beslemeleri görüntüleniyor

Kullanıcının haber kaynağı getirilirken, istemci kodu, şöyle bir şey yapıyorum:

$feedArray = $newsFeed->getUsersFeedWithLimitAndOffset($uid, 25, 0);

foreach($feedArray as $feedItem) {

// Use a switch to determine the activity type here, and display based on type
// e.g. User Name asked A Question
// where "A Question" == $feedItem['title'];

}

Haber kaynağı geliştirmek

Şimdi bir haber besleme geliştirmek için en iyi uygulamalar benim sınırlı anlayış affet, ama denilen sınırlı bir versiyonu kullanıyorum yaklaşımını anlıyorumyazmak fan-outsınırlı bir ara adım olarak bir cron çalıştırmak yerine kullanıcılar için yazıyorum anlamda' haber doğrudan beslenir. Ama bu işi bir model çok farklı, düzenli olarak kullanıcının haber kaynağı yük derlenmiş anlamda, ama değil.

Bu muhtemelen ileri geri büyük miktarda hak ettiği büyük bir soru, ama benim gibi Yeni geliştiriciler için gereken pek çok önemli konuşmalar için bir mihenk taşı olarak hizmet edebilir bence. Sadece geliştirmek ne kadar sürer, hatta belki de sıfırdan başlamak ve farklı bir yaklaşım denemeliyim ne kadar yanlış yaptığımı anlamaya çalışıyorum.

Bu model işe yaraması konusunda beni rahatsız eden bir diğer şey yeniliği ziyade alaka dayalı. Eğer herkes bu geliştirilebilir nasıl alaka iş için önerebilirim eğer, pür dikkat olurum. Öneriler üretmek için Yönetmen Edge API kullanıyorum, ama bir haber besleme gibi bir şey için, recommenders işe yaramaz (daha önce hiçbir favorited beri!) gibi görünüyor.

CEVAP
30 HAZİRAN 2011, PERŞEMBE


Gerçekten harika bir soru. Aslında bu benim gibi bir uygulama yapıyorum. Yani, biraz yüksek sesle düşünmek için gidiyorum.

Burada geçerli olan uygulama ile zihnimde gördüğüm kusurları:

  1. Tüm kullanıcılar için tüm arkadaşları işleme, ama insanların aynı Grup, benzer arkadaşlara sahip olması nedeniyle aynı kullanıcılar birçok kez işlem sona erecek.

  2. Arkadaşlarımdan biri bir mesaj ise, en fazla 5 dakika internette gösterilmez. Hemen gösterilir gerekir oysa, değil mi?

  3. Bir kullanıcı için tüm haber kaynağı tespit ettik. Biz sadece biz günlükleri darlığı son kez bu yana yeni aktiviteleri almam gerek değil mi?

  4. Bu iyi ölçekli görünmüyor.

Bu haber besleme etkinliği günlük olarak aynı veri görünüşe göre, bir etkinlik günlüğü masa sopa ile olur.

Eğer aktivite veritabanları üzerinde günlükleri shard, daha kolay ölçek için izin verir. Eğer siz de isterseniz eğer, kullanıcılarınızın shard edebilirsiniz, ama eğer bir tablo içinde 10 milyon kullanıcı kayıtları varsa bile, mysql iyi okur yapıyor olmalı. Bir kullanıcı arama zaman, günlükleri, kullanıcının erişim elde eder. Sizin eski günlükleri sık sık arşiv ve sadece günlükleri yeni bir dizi korumak için, çok shard gerek yok. Ya da belki hiç bile. Varsa bile oldukça iyi ayarlanmış eğer MySQL kayıtları milyonlarca yönetebilirsiniz.

Ben kaldıraç kullanıcı tablo için memcached ve hatta kendilerini kaydeder. Memcached önbellek girdileri boyutu 1 MB kadar izin verir, ve eğer anahtarlarınızı organize aklın varsa önbellekten tüm günlükleri almak olabilir.

Bu daha fazla iş mimarlık gelince olur, ama gerçek zamanlı çalışma için izin verir, ve özellikle kullanıcıların başlamak istediğinizde gelecekte ölçekyorumher gönderme. ;)

Bu makaleyi gördün mü?

http://bret.appspot.com/entry/how-friendfeed-uses-mysql

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • We've moved!

    We've moved!

    7 Ocak 2008
  • jocc talking shit

    jocc talking

    6 NİSAN 2007
  • TeeMayneTV

    TeeMayneTV

    27 Kasım 2010