- Lichess ने request load के कारण 7-piece Syzygy tablebase सर्वर की periodic RAID checks पीछे छूटने पर, पूरे blocks को scan करने के तरीके के बजाय read के समय integrity verification पर स्विच किया
- लंबे downtime के बिना 17TiB tablebase को migrate करने के लिए नया सर्वर तैयार किया गया, और 32GiB RAM·2×201GiB NVMe·6×5.46TiB HDD environment में वास्तविक request logs replay करके verify किया गया
- production में रिकॉर्ड किए गए 10 लाख requests को 12 parallel clients से replay करने पर, average response के बजाय users द्वारा महसूस की जाने वाली tail latency मुख्य bottleneck निकली
- implementation के स्तर पर
mmap की तुलना में pread(2) error handling और tail latency में बेहतर रहा, और POSIX_FADV_RANDOM·MADV_RANDOM जैसे random access hints आम तौर पर उल्टा असर डालते दिखे
- सीमित SSD पर table prefix रखा गया और request के अंदर probes को parallelize करके धीमे disk access को घटाया गया, साथ ही यह verify किया गया कि benchmark improvements production response time में भी दिखते हैं या नहीं
RAID full check के बजाय read-time verification पर स्विच
- Lichess के 7-piece Syzygy tablebase सर्वर के लिए, tablebase requests अधिक होने के दौरान periodic RAID integrity checks पूरा करना मुश्किल था
- नई configuration dm-integrity on LVM का उपयोग करती है, जिससे सभी data blocks को periodically check करने के बजाय blocks को हर read पर verify किया जाता है
- कुछ घंटों के downtime के बिना 17TiB tablebase migrate करने के लिए नया सर्वर अलग से configure किया गया
- वास्तविक cutover से पहले पूरे tablebase पर controlled benchmark चलाया जा सका
- बाद में नए सर्वर पर switch किया गया और पुराने सर्वर को retire किया गया
नया सर्वर configuration
- RAM पहले जैसी 32GiB रखी गई
- storage में पुराने सर्वर में न मौजूद 2×201GiB NVMe जोड़ा गया, और 476GiB disk की बची जगह OS और workspace के लिए reserve की गई
- HDD पुराने 5 से बढ़ाकर 6×5.46TiB HDD किए गए
- operating system Debian bookworm है, और kernel
Linux 6.1.0-21-amd64 series का है
- default I/O scheduler NVMe पर
none और HDD पर mq-deadline चुना हुआ था
RAID 5 setup और monitoring
- RAID 5 single disk failure से recover कर सकता है और random reads को कई disks में distribute कर सकता है, इसलिए tablebase server के लिए उपयुक्त है
- शुरुआती configuration इस तरह थी
lvcreate --type raid5 --raidintegrity y --raidintegrityblocksize 512 --name tables --size 21T vg-hdd
- शुरुआती test performance ठीक थी, लेकिन अगर monitoring न होती तो कुछ disks के समान स्तर पर participate न करने की समस्या छूट सकती थी
--stripes छोड़ देने पर सभी physical volumes default रूप से उपयोग नहीं होते
- गलत RAID configuration पकड़ने के लिए per-disk read activity monitoring जरूरी थी
वास्तविक request logs से दिखा bottleneck
- सामान्य conditions में server प्रति सेकंड 10~35 requests पाता है
- production environment में 10 लाख requests रिकॉर्ड किए गए, और चुने गए scenario में 12 parallel clients ने उन्हें sequentially submit किया
- tables lazy-open तरीके से खोले जाते हैं, और application व OS caches धीरे-धीरे भरते हैं
- शुरुआती 8 लाख response times को warm-up के रूप में exclude किया गया
- उसके बाद 2 लाख requests के response times का analysis किया गया
- average response time पर्याप्त तेज है, लेकिन tail latency अधिक होने के कारण optimization का focus वही बना
- ECDF graph हर response time से तेज requests का ratio दिखाता है, और x-axis log scale है
- graph में client के 30ms ping time को reflect करने के लिए हर response time में 30ms जोड़ा गया
- यह इसलिए किया गया ताकि log-scale x-axis के निचले range में कुछ milliseconds का अंतर जरूरत से ज्यादा highlight न हो
mmap की तुलना में बेहतर रहा pread(2)
- Syzygy tablebase implementation shakmaty-syzygy table files खोलने और पढ़ने के तरीके को replace करने के लिए interface प्रदान करता है
- मुख्य candidates दो थे
mmap: table file को memory में map करता है, और उस memory region को access करने पर disk read transparently होता है
pread(2): हर read के लिए system call करता है, और return value से read errors report करता है
mmap में mapping के बाद अतिरिक्त system call की जरूरत नहीं होती, लेकिन read सामान्य memory access जैसा दिखता है, इसलिए errors को signal जैसी out-of-band method से handle करना पड़ता है
- server implementation में अधिक robust error handling भर से ही
pread का उपयोग justify हो सकता था, और benchmarks में भी जिन scenarios में रुचि थी उनमें pread की performance बेहतर थी
- एक संभावित कारण यह है कि memory-mapped single data block access जब page boundary cross करता है, तो वह दो disk reads में बदल सकता है
- chess engines में तुरंत
pread लागू करने की जरूरत नहीं है
- engine matches में tablebase usage आम तौर पर तभी होता है जब सभी WDL tables को पर्याप्त तेज storage पर रखा जा सके
- इस case में सामान्य response time range उस graph में दिखने लायक भी नहीं होती, और system call overhead घटाने वाली memory mapping बेहतर होती है
random access hints का उल्टा असर
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM) और memory map के संबंधित hints आखिरकार अधिकतर उल्टा असर डालते दिखे
POSIX_FADV_RANDOM OS को बताता है कि file access random है और automatic read-ahead उपयोगी न होने की संभावना है; यह page cache pressure घटाने के लिए hint है
- लोग endgame analyze करते समय tablebase access pattern उम्मीद से कम random हो सकता है
- chess engines में probes अलग-अलग possible endgames में ज्यादा फैले हो सकते हैं, इसलिए result अलग हो सकता है
सीमित SSD पर रखने लायक table prefix
- table probe पहले position को table header की encoding information के आधार पर integer index में encode करता है
- इसके बाद उस compressed data block को ढूँढना होता है जिसमें उस index का result है
- Syzygy सही entry के पास point करने वाली sparse block length list प्रदान करता है, और उसके बाद block length list से relevant data block मिलता है
- table section sizes इस प्रकार हैं
| 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 space को adaptive cache layer की तरह उपयोग करके hot list entries और data blocks cache किए जा सकते हैं
- tail latency घटाने के goal में worst case को ध्यान में रखते हुए sparse block length list और block length list को SSD पर रखना उपयुक्त है
- यह layout hot/cold स्थिति से स्वतंत्र होकर हर table probe में slow disk reads को अधिकतम 1 बार तक सीमित कर सकता है
- इस server में RAID 1 mirroring के लिए SSD space पर्याप्त नहीं था, और इसे selective optimization मानकर redundancy छोड़ी गई और RAID 0 उपयोग किया गया
request के अंदर probes को parallelize करना
- chess engine का सामान्य tablebase request single WDL value के लिए request होता है
- user interface सभी moves के लिए DTZ values दिखाना चाहता है
- Syzygy के अंदर capture resolution तक शामिल करने पर average request 23 WDL probes और 70 DTZ probes generate करता है
- शुरुआती implementation ने request handling को तो parallelize किया था, लेकिन हर request के अंदर probes sequentially चलाए
- ज्यादा granular parallelism low-latency range में overhead बनाता है, लेकिन tail latency को काफी घटाता है
- भले ही disk वास्तव में बहुत सारे parallel reads को physically process न कर सके, I/O scheduler द्वारा reads को इस तरह plan करने की संभावना बढ़ती है कि हर request जल्दी खत्म हो
- यह method related disk accesses की order planning को बेहतर बनाता है, ताकि disk head को अगले request sector तक पहुँचने में लगने वाला समय घटे
production verification और raw data
- benchmark scenario के optimizations वास्तविक production में भी मदद करते हैं या नहीं, इसे response time chart से verify किया गया
- raw data lila-tablebase-bench पर public है
1 टिप्पणियां
Hacker News की रायें
Lichess ऐसी सेवा है जिसकी आप अच्छे wine की तरह बस ठहरकर तारीफ़ करते रह जाते हैं। chess community के लिए यह वाकई शानदार है, और इसे रोज़ इस्तेमाल करते हुए इसके features और performance से लगातार प्रेरणा मिलती है
खासकर जब पता चलता है कि यह सीमित budget वाली 1–2 लोगों की टीम है, तो और भी हैरानी होती है
हर response time में 30ms जोड़कर ECDF दिखाने वाला हिस्सा दिलचस्प लगा
constant जोड़ना artificial लग सकता है, लेकिन असल में यह 30ms ping वाले client के नज़रिए से results देखने का तरीका है, और log scale x-axis को lower range में कुछ ms के फर्क को बढ़ा-चढ़ाकर दिखाने से रोकता है। शायद यह standard technique हो, लेकिन काफ़ी समझदार trick जैसी लगी
सोच रहा हूं कि cost reduction सच में ज़रूरी थी या फिर किसी और वजह से बस एक box में 20TB SSD डालकर बात खत्म नहीं की जा सकती थी। 4TB SSD भी लगभग 300 डॉलर का है, और HP या Dell SFF drives भी बहुत ज़्यादा महंगी नहीं हैं
शायद testing और optimization में ही दिलचस्पी रही होगी, और product perspective से देखें तो सीमित समय किसी दूसरे project पर लगाया जाता
organization France-based है, इससे costs पर क्या असर पड़ता है पता नहीं, लेकिन उल्लेख करने लायक है
इससे बेहतर time investment justify करने के लिए या तो user experience इससे भी खराब करने वाला कोई project होना चाहिए, या फिर for-profit organization में कहीं और पैसा कमाने का मौका हो और customer pain की खास परवाह न होने की बात माननी पड़ेगी
यह बहुत powerful और सस्ते hardware, और बस “आज के लिए इतना काफी है” कहना चाहने वाले आलसी लोगों के मेल का नतीजा लगता है। अपने काम पर गर्व करने की बात भी तो होती है
इस optimization में कुछ questionable choices हैं। optimization की वजह यह है कि input/output activity इतनी ज़्यादा थी कि RAID check पूरा नहीं हो पा रहा था
article से यह clear नहीं है कि 17TiB data पर RAID check कभी सच में पूरा हुआ था या नहीं। इसके बजाय periodic RAID checks बंद कर दिए गए, और data पढ़ते समय page level पर error check करने का तरीका अपनाया गया; दोनों तरीके समान नहीं हैं और अगर data important है तो दोनों इस्तेमाल होने चाहिए
अगर corruption सिर्फ data पढ़ने की कोशिश करते समय पता चले, तो पुराना data corruption बना रह सकता है, और backup retention period से आगे निकलकर original recover न हो पाए। इसके साथ RAID 0 पर switch करने की बात भी जुड़ी है; यह सबसे तेज़ option तो है, लेकिन इसका मतलब है कि उस NVMe configuration पर ऐसे load को संभालने का काफी बड़ा भरोसा किया जा रहा है
उम्मीद है backups अच्छे से हैं। अच्छा solution यह होगा कि temporary server चलाकर backup restore किया जाए और full data check किया जाए; सफल होने पर backup-restore procedure और file integrity भी साथ में validate हो जाएगी। फिर भी main server पर RAID check पूरा करने की गुंजाइश रखनी चाहिए, और performance के लिए RAID 0 न इस्तेमाल करना बेहतर है
यह freely available dataset है, बस size थोड़ा बड़ा है। https://en.wikipedia.org/wiki/Endgame_tablebase इसे बेहतर समझाता है। इसलिए backup भी नहीं करते
lishogi भी है, लेकिन अभी उसका scale छोटा है, इसलिए ऐसी optimization की ज़रूरत पड़ने लायक नहीं है
chess variants में shogi सबसे मज़ेदार है, xiangqi उतना नहीं
सोच रहा हूं कि lichess का मतलब female lich माना जा सकता है क्या। जैसे baron/baroness
सख्ती से कहें तो male lich “werlich” होगा, female lich “wiflich”, और plural में “-en” लगेगा। हालांकि undead के लिए gender आम तौर पर अप्रासंगिक होता है, इसलिए neutral form भारी रूप से ज़्यादा इस्तेमाल होता है
“lichess” German और French roots का अजीब मिश्रण है, इसलिए वह naturally English के दूसरे words से अलग नहीं दिखता
fair comparison तो नहीं है, लेकिन Lichess team की engineering quality वाकई प्रभावित करती है। इसका मुख्य competitor GCP migration का दावा करता रहा, फिर भी popularity बढ़ने के साथ बार-बार outages झेलता रहा, और मुझे लगता है उसके पास करीब 100 गुना ज़्यादा लोग होंगे
Lichess की कमजोरी mobile app थी, लेकिन Flutter में फिर से बनाई गई v2 अभी beta में होते हुए भी पहले ही काफी अच्छी है
और यह भी याद रखना चाहिए कि Thibault अपनी compensation के तौर पर सालाना 60 हज़ार डॉलर से भी कम लेते हैं
बस यह जानना है कि Lichess pronounce कैसे करते हैं। Lie chess, Le chess, या League chess?