- Discord, mevcut Elasticsearch tabanlı arama altyapısının sınırlarını aşmak için tüm yapıyı Kubernetes tabanlı olarak yeniden tasarladı ve mesaj indeksleme performansı ile kararlılığını kayda değer biçimde iyileştirdi
- Mevcut Redis kuyruğu mesaj kaybı riski taşıyordu; ancak PubSub ile değiştirilerek güvenilir mesaj teslimi sağlandı, aynı zamanda mesajlar küme/indeks bazında sınıflandırılarak verimli şekilde işlendi
- "Hücre (cell)" mimarisi kullanılarak çok sayıda küçük Elasticsearch kümesine dağıtım yapıldı; böylece düğüm aşırı yüklenmesi ve güncelleme yapılamaması sorunları çözüldü
- Kişisel DM mesajları ve sunucu (guild) mesajları ayrı hücrelerde indeksleniyor; bu da yeni sunulan tüm DM'lerde arama özelliğinin temelini oluşturuyor
- Çok büyük topluluklar (BFGs), özel hücreler ve çoklu shard indeksleri sayesinde Lucene'in azami mesaj sayısı sınırını aşacak şekilde ölçeklenebiliyor
Mevcut altyapının sınırları
- Redis tabanlı mesaj kuyruğu, Elasticsearch düğüm arızalarında darboğaz oluşturuyordu ve mesaj kaybı ihtimali vardı
- Büyük kümelerde (200+ düğüm), tek bir düğüm arızası tüm indeksleme sürecinde başarısızlık oranını %40'a kadar çıkarıyordu
- Lucene'in
MAX_DOCS (2 milyar mesaj) sınırına ulaşan indeksler indekslemenin tamamen durmasına yol açıyordu
- Eskiyen sistem nedeniyle log4shell yaması bile ancak tüm sistem çevrimdışı alındıktan sonra uygulanabiliyordu
Çözüm stratejisi
Kubernetes tabanlı yeniden kurulum
- Elasticsearch kümelerinin işletimini otomatikleştirmek için Elastic Kubernetes Operator (ECK) kullanıldı
- Rolling restart, işletim sistemi ve yazılım yükseltmeleri güvenli şekilde yapılabilir hale geldi
Kümeleri “hücre (cell)” mimarisiyle dağıtma
- Tek büyük küme yerine birden fazla küçük kümenin bir hücre oluşturduğu yapı tercih edildi
- Her hücrede indeks sayısı sınırlandırıldı ve shard boyutu 50 GB ile 200 milyon mesajın altında tutuldu
- İndeksleme ve sorgu performansı arttı, küme durumunu koruma yükü azaldı
PubSub tabanlı mesaj kuyruğu
- Redis → PubSub geçişiyle mesaj kaybı olmadan kuyrukların korunması mümkün oldu
- PubSub'ın kullanım alanı diğer işlevlere de (iş planlama vb.) genişletiliyor
Küme bazlı toplu indeksleme
- PubSub'dan alınan mesajlar hedef küme ve indeks ölçütüne göre sınıflandırılarak ayrı task'larda paralel işlendi
- Rust'ın tokio task + channel yapısıyla mesaj dağıtım işleme mimarisi kuruldu
Arama özelliğindeki iyileştirmeler
Kullanıcı bazlı DM araması
- Daha önce DM'ler kanal bazında indekslendiği için tüm DM'lerde arama verimsizdi
- Artık DM mesajları kullanıcı başına indekslere çiftli olarak yazılıyor ve tüm DM'lerde tek seferde arama yapılabiliyor
BFG (Big Freaking Guilds) desteği
- Lucene'in mesaj sayısı sınırını aşan çok büyük topluluklar için çoklu shard indeksleri devreye alındı
- BFG'ler özel Elasticsearch hücrelerinde çoklu primary shard yapısıyla işleniyor
- Mevcut indekslere ve yeni indekslere aynı anda çiftli indeksleme yapıldıktan sonra, sorgular kademeli olarak yeni hedeflere yönlendiriliyor
Sonuçlar
- Trilyonlarca mesaj indekslendi, önceye kıyasla indeksleme hacmi 2 katına çıktı
- Sorgu yanıt süresi: ortalama 500ms → 100ms, p99 ise 1s → 500ms altı
- 40'tan fazla küme ve binlerce indeks işletiliyor
- Küme yükseltmeleri ve rolling restart işlemleri tamamen otomatik hale geldi ve hizmet kesintisi yaşanmadı
4 yorum
O işi bir yandan işletirken bunu da yapmaları... saygı duyuyorum.
Discord mühendisliği her zaman örnek alınacak düzeyde. Kıskanıyorum.
pubsub’ın ne olduğunu merak etmiştim; meğerse GCP’nin sunduğu bir IaaS’mış.
https://cloud.google.com/pubsub?hl=en
Etkileyici. Sorunu çözmek için her şeyi baştan kurmaları da öyle.