- Lichess, istek yükü nedeniyle 7 taşlı Syzygy tablebase sunucusunda periyodik RAID denetimleri aksayınca, tüm blokları taramak yerine okuma sırasında bütünlük doğrulamasına geçti
- Uzun kesinti yaşamadan 17TiB tablebase’i taşımak için yeni bir sunucu kuruldu ve 32GiB RAM, 2×201GiB NVMe, 6×5.46TiB HDD ortamında gerçek istek günlükleri yeniden oynatılarak doğrulama yapıldı
- Prodüksiyonda kaydedilen 1 milyon istek, 12 paralel istemciyle yeniden oynatıldığında, ortalama yanıttan çok kullanıcının hissettiği kuyruk gecikmesinin temel darboğaz olduğu ortaya çıktı
- Uygulama tarafında
mmap yerine pread(2), hata işleme ve kuyruk gecikmesi açısından daha avantajlıydı; POSIX_FADV_RANDOM ve MADV_RANDOM gibi rastgele erişim ipuçları ise çoğunlukla ters etki yaptı
- Sınırlı SSD alanında table prefix’leri yerleştirip istek içi probe işlemlerini paralelleştirerek yavaş disk erişimi azaltıldı; ayrıca benchmark iyileştirmelerinin prodüksiyon yanıt sürelerine de yansıyıp yansımadığı doğrulandı
RAID tam taraması yerine okuma sırasında doğrulama
- Lichess’in 7 taşlı Syzygy tablebase sunucusunda, tablebase istekleri yoğunken periyodik RAID bütünlük denetimlerini tamamlamak zordu
- Yeni yapılandırma, LVM üzerinde dm-integrity kullanarak tüm veri bloklarını periyodik olarak taramak yerine, blok her okunduğunda doğrulama yapıyor
- 17TiB tablebase’i birkaç saatlik kesinti olmadan taşımak için ayrı bir yeni sunucu kuruldu
- Gerçek geçişten önce tüm tablebase üzerinde kontrollü benchmark çalıştırılabildi
- Ardından yeni sunucuya geçildi ve eski sunucu kullanımdan çıkarıldı
Yeni sunucu yapılandırması
- RAM, önceki sunucudaki gibi 32GiB olarak korundu
- Depolamada, önceki sunucuda olmayan 2×201GiB NVMe eklendi; 476GiB diskin kalan alanı ise işletim sistemi ve çalışma alanı için ayrıldı
- HDD sayısı önceki 5 diskten 6×5.46TiB HDD seviyesine çıkarıldı
- İşletim sistemi Debian bookworm, çekirdek ise
Linux 6.1.0-21-amd64 ailesi
- Varsayılan G/Ç zamanlayıcısı NVMe için
none, HDD için mq-deadline olarak seçilmişti
RAID 5 kurulumu ve izleme
- RAID 5, tek disk arızasında kurtarma sağlayabildiği ve rastgele okumaları birden fazla diske dağıtabildiği için tablebase sunucusu için uygun
- İlk yapılandırma şöyleydi
lvcreate --type raid5 --raidintegrity y --raidintegrityblocksize 512 --name tables --size 21T vg-hdd
- İlk test performansı iyiydi, ancak izleme olmasaydı bazı disklerin aynı düzeyde katkı vermediği sorun gözden kaçabilirdi
--stripes belirtilmezse tüm fiziksel birimler varsayılan olarak kullanılmıyor
- Disk başına okuma etkinliğinin izlenmesi, hatalı RAID yapılandırmasını yakalamak için gerekliydi
Gerçek istek günlüklerinde görülen darboğaz
- Normal koşullarda sunucu saniyede 10 ila 35 istek alıyor
- Prodüksiyon ortamında 1 milyon istek kaydedildi ve seçilen senaryoda 12 paralel istemci bunları sırayla gönderdi
- Table’lar gecikmeli açma yöntemiyle açılıyor, uygulama ve işletim sistemi önbellekleri de kademeli olarak doluyor
- İlk 800 bin yanıt süresi ısınma dönemi olarak analiz dışında bırakıldı
- Sonraki 200 bin isteğin yanıt süreleri incelendi
- Ortalama yanıt süresi yeterince hızlı olsa da, kuyruk gecikmesi yüksek olduğu için optimizasyonun odağı bu oldu
- ECDF grafiği, belirli bir yanıt süresinden daha hızlı tamamlanan isteklerin oranını gösteriyor ve x ekseni logaritmik ölçekte
- Grafikte, istemcinin 30ms ping süresini yansıtmak için her yanıt süresine 30ms eklendi
- Bu, logaritmik x ekseninin düşük aralıklarda birkaç milisaniyelik farkları olduğundan fazla vurgulamasını önlemek için yapıldı
mmap yerine avantaj sağlayan pread(2)
- Syzygy tablebase uygulaması shakmaty-syzygy, table dosyalarını açma ve okuma yöntemlerini değiştirilebilen bir arayüz sunuyor
- İki ana aday vardı
mmap: table dosyasını belleğe eşler ve ilgili bellek alanına erişildiğinde disk okuması saydam biçimde gerçekleşir
pread(2): her okumada sistem çağrısı yapar ve okuma hatalarını dönüş değeriyle bildirir
mmap, eşleme sonrasında ek sistem çağrısı gerektirmez; ancak okuma işlemi normal bellek erişimi gibi göründüğü için hatalar sinyal gibi bant dışı yöntemlerle ele alınmak zorundadır
- Sunucu uygulamasında yalnızca daha sağlam hata işleme bile
pread kullanımını haklı çıkarıyordu ve benchmark’larda da ilgili senaryolarda pread daha iyi performans verdi
- Olası nedenlerden biri, belleğe eşlenmiş tek bir veri bloğuna erişimin sayfa sınırını aşması durumunda bunun iki ayrı disk okumasına yol açabilmesi
- Bunun satranç motorlarına doğrudan
pread uygulanması gerektiği anlamına gelmiyor
- Motor maçlarında tablebase kullanımı genellikle tüm WDL table’ları yeterince hızlı bir depolama üzerinde tutmak mümkün olduğunda yapılıyor
- Bu durumda tipik yanıt süreleri grafikte görünmeyecek kadar düşük olur ve sistem çağrısı yükünü azaltan bellek eşleme daha uygundur
Rastgele erişim ipuçlarının ters etkisi
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM) ve bunun bellek eşlemeli karşılığı olan ipuçları, sonuçta çoğunlukla ters etki yaptı
POSIX_FADV_RANDOM, dosya erişiminin rastgele olduğunu ve otomatik read-ahead’in muhtemelen faydalı olmayacağını işletim sistemine bildirerek sayfa önbelleği baskısını azaltmayı amaçlayan bir ipucu
- İnsanlar oyun sonlarını analiz ederken oluşan tablebase erişim örüntüsü, beklenenden daha az rastgele olabilir
- Satranç motorlarında probe işlemleri farklı olası oyun sonlarına daha fazla dağılabildiği için sonuç farklı çıkabilir
Sınırlı SSD alanına yerleştirilen table prefix’leri
- Table probe işlemi önce pozisyonu, table header’daki kodlama bilgisine dayanarak bir tamsayı indekse dönüştürüyor
- Sonrasında bu indeksin sonucunu içeren sıkıştırılmış veri bloğunun bulunması gerekiyor
- Syzygy, doğru girdinin yakınını işaret eden bir sparse block length list sağlıyor; ardından ilgili veri bloğunu bulmak için block length list kullanılıyor
- Table bölümlerinin boyutları şöyle
| Table section |
WDL |
DTZ |
Total |
| Headers and sparse block length lists |
38GiB |
9GiB |
47GiB |
| Block length lists |
274GiB |
64GiB |
339GiB |
| Compressed data blocks |
8433GiB |
8458GiB |
16891GiB |
- SSD alanı, sıcak liste girdileri ve veri bloklarını önbelleğe alan uyarlanabilir bir önbellek katmanı olarak da kullanılabilirdi
- Ancak kuyruk gecikmesini azaltma hedefinde, en kötü durumu esas alan sparse block length list ve block length list verilerini SSD’de tutma yaklaşımı daha uygundu
- Bu yerleşim, sıcak/soğuk veri ayrımından bağımsız olarak table probe başına yavaş diskten yapılan okumayı en fazla 1 kez ile sınırlayabiliyor
- Bu sunucuda RAID 1 yansılama için yeterli SSD alanı yoktu; bu yüzden seçmeli bir optimizasyon olması nedeniyle yedeklilikten vazgeçilip RAID 0 kullanıldı
İstek içindeki probe işlemlerini paralelleştirme
- Satranç motorlarında tipik bir tablebase isteği, tek bir WDL değeri için yapılan istektir
- Kullanıcı arayüzünde ise tüm hamleler için DTZ değerleri gösterilmek isteniyor
- Syzygy içinde capture çözümlemesi de dahil edildiğinde ortalama bir istek 23 WDL probe ve 70 DTZ probe üretiyor
- İlk uygulama, istek işlemeyi paralelleştiriyordu; ancak her isteğin içindeki probe işlemlerini sıralı çalıştırıyordu
- Daha ince taneli paralellik, düşük gecikme aralığında ek yük oluştursa da kuyruk gecikmesini belirgin biçimde azalttı
- Diskler fiziksel olarak çok sayıda paralel okumayı gerçekten işleyemese bile, G/Ç zamanlayıcısının her isteği daha hızlı tamamlayacak şekilde okumaları planlama olasılığı artıyor
- Bu yaklaşım, disk kafasının bir sonraki istek sektörüne ulaşana kadar geçen süreyi azaltacak biçimde, ilgili disk erişim sırasının daha iyi planlanmasına yardımcı oluyor
Prodüksiyonda doğrulama ve ham veriler
- Benchmark senaryosundaki optimizasyonların gerçek prodüksiyonda da fayda sağlayıp sağlamadığı, yanıt süresi grafikleriyle doğrulandı
- Ham veriler lila-tablebase-bench içinde açık olarak yayınlandı
1 yorum
Hacker News görüşleri
Lichess, iyi bir şarap gibi insanın durup hayran kalmasına neden olan bir hizmet. Satranç topluluğu için gerçekten harika ve her gün kullanırken özellikleriyle ve performansıyla beni etkilemeye devam ediyor
Özellikle bunun 1-2 kişilik, sınırlı bütçeli bir ekip olduğunu bilince daha da şaşırtıcı
Her yanıt süresine 30 ms eklenmiş ECDF gösterimi ilginçti
Sabit bir değer eklemek yapay görünebilir ama aslında sonuçlara 30 ms ping'e sahip bir istemcinin gözünden bakma yöntemi ve log ölçekli x ekseninin düşük aralıktaki birkaç ms farkı abartmasını engelliyor. Standart bir teknik olabilir ama oldukça akıllıca bir numara gibi görünüyor
Maliyet düşürmenin gerçekten gerekli olup olmadığını ya da tek bir makineye 20 TB SSD takıp geçmemek için başka bir sebep bulunup bulunmadığını merak ediyorum. 4 TB SSD'ler de kabaca 300 dolar ve HP ya da Dell SFF sürücüler de bundan çok daha pahalı değil
Sanırım asıl ilgi test ve optimizasyonun kendisindeydi; ürün bakış açısından bakınca sınırlı zamanı başka projelere harcarlardı gibi geliyor
Kuruluşun Fransa merkezli olmasının maliyetleri nasıl etkilediğini bilmiyorum ama anmaya değer
Bundan daha iyi bir zaman yatırımını ancak kullanıcı deneyiminin daha kötü olduğu başka bir proje varsa ya da ticari bir kuruluşta başka yerde para kazanma fırsatı olup müşteri sıkıntısıyla çok ilgilenilmediği açıkça kabul ediliyorsa gerekçelendirebilirsiniz
Bu, aşırı güçlü ve ucuz donanım ile “bugünlük bu kadar” demek isteyen tembel insanların birleşiminin bir sonucu gibi duruyor. İnsan yaptığı işle gurur duymalı denmez mi zaten
Bu optimizasyonda birkaç şüpheli tercih var. Optimizasyonun gerekçesi, girdi/çıktı etkinliğinin çok fazla olması yüzünden RAID taramasının tamamlanamaması
Yazıdan, 17 TiB veri üzerindeki RAID taramasının gerçekten hiç tamamlanıp tamamlanmadığı anlaşılmıyor. Bunun yerine periyodik RAID taramasını kapatıp veri okunurken sayfa düzeyinde hata denetimi yapmaya geçmişler ama bu ikisi aynı şey değil ve veri önemliyse ikisini de kullanmak gerekir
Bozulmayı ancak veriyi okumaya çalıştığınızda tespit ederseniz eski veri bozulmaları orada kalmaya devam edebilir ve yedek saklama süresi aşıldığında özgün kopyayı kurtarmak imkânsız olabilir. Buna bir de RAID 0'a geçiş eklenmiş; en hızlı seçenek olsa da, bu NVMe kurulumunun böyle bir yükü kaldıracağına oldukça büyük bir güven anlamına geliyor
Umarım yedekleri iyidir. İyi çözüm, geçici bir sunucu ayağa kaldırıp yedeği geri yüklemek, tüm veri doğrulamasını çalıştırmak ve başarılı olursa hem yedekleme/geri yükleme prosedürünü hem de dosya bütünlüğünü doğrulamaktır. Yine de ana sunucuda RAID taramasını tamamlayacak kadar boşluk bırakılmalı ve performans uğruna RAID 0 tercih edilmemeli
Bu, serbestçe edinilebilen bir veri kümesi; sadece biraz büyük. https://en.wikipedia.org/wiki/Endgame_tablebase bunu daha iyi açıklıyor. Bu yüzden yedek de tutulmuyor
lishogi de var ama henüz ölçeği bu tür optimizasyonları gerektirecek kadar büyük değil
Satranç varyantları içinde en eğlencelisi şogi; siangçi o kadar değil
lichess'in kadın lich anlamına gelip gelmediğini merak ettim. hani baron/barones gibi
Teknik olarak erkek lich “werlich”, kadın lich “wiflich” ve çoğulda “-en” eki gelir. Ama undead varlıklarda cinsiyet çoğunlukla alakasız olduğundan nötr biçim ezici biçimde daha yaygın kullanılır
“lichess”, Almanca ve Fransızca köklerin karıştığı tuhaf bir birleşim; bu yüzden İngilizcedeki başka sözcüklerden doğal biçimde ayrışmıyor
Tam adil bir karşılaştırma değil ama Lichess ekibinin mühendislik kalitesi gerçekten hayranlık uyandırıyor. Ana rakibi GCP'ye geçişiyle övünürken popülerlik arttıkça tekrar tekrar kesintiler yaşadı; üstelik çalışan sayısı muhtemelen 100 kat fazladır
Lichess'in zayıf noktası mobil uygulamasıydı ama Flutter ile yeniden yapılan v2, hâlâ betada olmasına rağmen şimdiden oldukça iyi
Ve Thibault'nun kendi maaşı olarak yılda 60 bin dolar bile almadığını da unutmamak gerek
Yalnız Lichess'in nasıl telaffuz edildiğini merak ediyorum. Lie chess mi, Le chess mi, League chess mi