Özet : Yaklaşık 1 milyon aktif kullanıcı ve 150 milyon depolanmış etkinlik için bunu basit tutuyorum:
- Benzersiz etkinliklerin depolanması için ilişkisel bir veritabanı kullanın (etkinlik başına 1 kayıt / "olan") Kayıtları olabildiğince kompakt hale getirin. Etkinlik kimliğini veya zaman kısıtlamaları olan bir dizi arkadaş kimliğini kullanarak bir dizi etkinliği hızlı bir şekilde alabileceğiniz yapı.
- Her etkinlik kaydı oluşturulduğunda etkinlik kimliklerini Redis'te yayınlayın, kimliği etkinliği görmesi gereken bir arkadaş / abone olan her kullanıcı için bir "etkinlik akışı" listesine ekleyin.
Sorgu Redis herhangi bir kullanıcı için etkinlik akışı almak ve daha sonra gerektiği gibi db ilgili verileri almak için. Kullanıcının zamanda geriye doğru göz atması gerekiyorsa db'yi sorgulamaya geri dönün (bunu bile teklif ederseniz)
Yaklaşık 15 milyon faaliyetle uğraşmak için eski bir MySQL tablosu kullanıyorum.
Şuna benziyor:
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
bana etkinlik türünü source_id
söyler, etkinlikle ilgili kaydı söyler. Etkinlik türü "eklenen favori" anlamına gelirse, o zaman source_id bir favori kaydın kimliğini ifade biliyorum.
parent_id
/ parent_type
Uygulamam için yararlıdır - onlar aktivite ile ilgilidir söyle. Bir kitap favorilere eklendiyse parent_id / parent_type, etkinliğin belirli bir birincil anahtarla (id) bir kitap (tür) ile ilgili olduğunu söylerdi
Ben endeks (user_id, time)
ve olan faaliyetler için sorgu user_id IN (...friends...) AND time > some-cutoff-point
. Kimliği atmak ve farklı bir kümelenmiş dizin seçmek iyi bir fikir olabilir - bunu denemedim.
Oldukça basit şeyler, ama işe yarıyor, basit ve ihtiyaçlarınız değiştikçe çalışmak kolaydır. Ayrıca, MySQL kullanmıyorsanız, daha iyi dizin bazında yapabilirsiniz.
En son etkinliklere daha hızlı erişim için Redis ile denemeler yapıyorum . Redis, tüm verilerini bellekte saklar, böylece tüm etkinliklerinizi oraya koyamazsınız, ancak sitenizdeki yaygın olarak kullanılan ekranların çoğu için yeterince depolayabilirsiniz. Her kullanıcı için en yeni 100 veya bunun gibi bir şey. Karışımdaki Redis ile şu şekilde çalışabilir:
- MySQL etkinlik kaydınızı oluşturun
- Etkinliği oluşturan kullanıcının her arkadaşı için, kimliği Redis'teki etkinlik listesine itin.
- Her listeyi son X öğeye kırp
Redis hızlıdır ve komutları tek bir bağlantıda boru hattı oluşturmak için bir yol sunar - bu nedenle bir etkinliği 1000 arkadaşa göndermek milisaniye sürer.
Neden bahsettiğimin daha ayrıntılı bir açıklaması için Redis'in Twitter örneğine bakın: http://redis.io/topics/twitter-clone
Şubat 2011 Güncellemesi Şu anda 50 milyon aktif etkinliğim var ve hiçbir şey değiştirmedim. Buna benzer bir şey yapmakla ilgili güzel bir şey, kompakt, küçük sıralar kullanmasıdır. Daha fazla etkinlik ve bu etkinliklerin daha fazla sorgusunu içerecek bazı değişiklikler yapmayı planlıyorum ve Redis'i işleri hızlı tutmak için kesinlikle kullanacağım. Redis'i diğer alanlarda kullanıyorum ve bazı problemler için gerçekten iyi çalışıyor.
Temmuz 2014 Güncellemesi Aylık yaklaşık 700 bin aktif kullanıcıya sahibiz. Son birkaç yıldır, her kullanıcı için son 1000 etkinlik kimliğini saklamak için Redis'i (madde işaretli listede açıklandığı gibi) kullanıyorum. Sistemde genellikle yaklaşık 100 milyon aktivite kaydı vardır ve bunlar hala MySQL'de saklanır ve hala aynı düzendedir. Bu kayıtlar, daha az Redis belleği ile kaçmamıza izin veriyor, etkinlik verilerinin kaydı olarak hizmet veriyor ve kullanıcıların bir şeyler bulmak için zamanda daha fazla sayfa geriye gitmeleri gerekiyorsa bunları kullanıyoruz.
Bu akıllıca veya özellikle ilginç bir çözüm değildi ama bana iyi hizmet etti.