SD #3: Twitter System Design

Soru
Bize Twitter'in sistem tasarimini yapiniz. Ozellikler:

- Tweet'leme
- Timeline goruntuleme
    Kullanici timeline (bir kullanicinin attgini tum tweetlerin listesi)
    Home timeline (siz twittere girdiginizde gordugunuz timeline. takip edilen kullanicilarin attiklari tweetlerden olusur.)
- Kullanici takip etme

Cozum
Ilk olarak yine naive cozum ile baslayabiliriz. Ilk akla gelen yontem, tweet'leri bir tabloda saklamak. Buna ek olarak kullanicilar tablosu ile join de yapilarak timeline'lar olusturulabilir. Users table'in primary key'i de UserId uzerinden joinleniyor.


Seklinde bir Tweets tablosu bir de Users tablosu olusturdugumuzu dusunelim. Bu durumda bir tweet ile kullanici arasinda 1'e : n bir iliski olur. Yani bir kullanici icin birden fazla tweet kaydi bulunabilir. 

Bu durumda bir kullanici kendi ana sayfasina gittigi zaman, home timeline'i nasil olusturacagiz? 
1- Kullanicinin takip ettigi kullanicilari bulacagiz
2- Bu kullanicilarin attiklari tweetleri, Tweets tablosundan cekip tarihsel siralama ile birlestirecegiz

Ama zaten su asamada bunun olamayacagi anlasildi bile. Tweets tablosunda kac row olacagini ben hayal dahi edemiyorum. Boyle bir tablo olamaz, olsa da sorgulanamaz. Belki sharding ve birtakim indekslemeler yapilabilir ama yine de biz twitterin bu sorunu boyle cozmedigini biliyoruz. 

Twitterin acikladigina gore, birkac sene evvel bile, home timeline icin saniyede birkac birkac bin request aliyorlar. Boyle bir request sayisini yukaridaki yontem ile karsilamak mumkun olmazdi. 

Reads > Writes 
Ilk yapacagimiz sey, sistemin karakteristiklerine bir gozatmak. Bircok sosyal medya gibi twitter da read-heavy bir sistem. Insanlar write da yapiyor ama read, bunun yaninda cok daha fazla. Bu da bize in-memory cachleme hatirlatmali saniyorum. 

Bize home timeline'a mumkunse 1 saniyenin altinda erismemizi saglayacak cok hizli bir read servisi gerekiyor. Bunun yaninda birisi bir tweet attiktan sonra elbette ki insanlar bunu en kisa zamanda kendi timeline'larinda gorsunler istiyoruz ama availability bundan cok daha onemli. 

Yani birisi, bir baskasinin attigi bir tweet'i on dakika sonra gormesi, bir kullanicinin home timeline'nina 5 saniyede erismesi problemi yaninda gozardi edilebilir durumda. O zaman onceligimiz soyle:

1- Availability
2- Consistencey 

Bu siralama literaturde eventual consistency olarak adlandirilan bir model. 

Yeni Mimari
Kullanicinin gozunden olaya bakalim. Bir kullaniciyiz ve bir tweet attik. Ne olacak?

Bu tweet, kullaniciya cografi olarak en yakinda bulunan bir load balancer'a gonderilecek ki, gelen cok fazla sayida request scalable olarak sunuculara dagitilsin. Daha sonra twitterin fan out olarak adlandirdigi surec basliyor

Bizm tweet, bir in-memory database'e kaydediliyor. Bizi takip eden tum kullanicilarin home timeline'lari tekrar olusturuluyor ve in-memory databasede saklaniyor. Bu sayede, bizi takip eden birisi kendi home timeline'ine baktigi zaman bizim attigimiz tweet'i gorebiliyor. Ve bu home timeline okuma islemi hafizadan ve de O(1) kompleksitede gerceklesiyor. 

In-memory database olarak Redis kullandiklarini biliyoruz. Tum kullanicilarin home timeline'lari rediste tutuluyor demistik. Hatta availability cok onemli oldugu icin, 3 replika uzerinde tutuluyor. Bu da demek oluyor ki, fan out surecinde, bir kullanici bir tweet attigi zaman, bu kullaniciyi takip eden tum kullanicilarin home timeline'lari guncelleniyor ve 3 farkli Redis clusteri uzerinde barindiriliyor. 100 takipcisi var ise toplamda 300 Redis listesi uzerinde guncelleme islemi yapiliyor. 

Replika guncellemeleri de asenkron olarak yapildigi icin, bazi replikalar henuz guncellenmemis state'e sahip olabilir. Ancak eninde sonunda 3 replika da ayni state'e sahip olacaktir. Eventual consistency, tekrar. 

Ozetlersek; bir tweet icin 100 kisinin timeline'ni komple guncelledik ve de 3 replika seklinde ekstra hafizada tuttuk. Ama availability ve read performansi ars-i alaya cikti. Hersey bir trade-off sonucta. Bu sayede bir kullanici kendi hesabina girip baktigi zaman home timeline'ina ulasmasi bir hafizada yapilan bir hashtable lookup seklinde cok performansli olacak. 

Bir problem
Verdigimiz ornekteki arkadasin 100 takipcisi vardi. Bu yuzden bir tweet attigi zaman 100 kisinin home timeline'inin guncelledik. Peki ya abd baskani bir tweet atarsa? Ya da Lady Gaga? Bu kisilerin 70-80 milyon takipcisi var. Bu durumda 80 milyon kisinin timeline'nini guncellemek gerekecek. 

Yine twitter, sistem karakteristiklerini inceleyerek ara bir cozum bulmus. Bahsettigimiz gibi cok asiri sayida takipcisi olan kisi sayisi, oyle olmayanlara nazaran az sayida. Bir kullanicinin home timeline'i takip ettigi normal kullanicilar bir tweet attiginda onceden guncelleniyor, bahsettigimiz gibi. Ama milyonlarca takipcisi olan bir kullanciyi takip ediyor ise, bu durumda request esnasinda, onceden olusturulmus olan home timeline uzerine dinamik olarak bu kisilerden gelen tweetler bindiriliyor. 

Yani 80 milyon takipcisi olan bir hesap tweet attiginda 80 milyon kisinin timeline'i guncellenmiyor. Bu kisilerin attiklari tweetler request geldigi zaman timeline'lara bindiriliyor. 

Sonuc olarak ortaya soyle bir yapi cikiyor:

Diger bir system design probleminde gorusunceye kadar, stay hungry, stay foolish, stay healthy :)



Yorumlar

Bu blogdaki popüler yayınlar

Python'da Multithreading ve Multiprocessing

Threat Modeling 1

Encoding / Decoding