- Do tải yêu cầu lớn khiến các lượt kiểm tra RAID định kỳ của máy chủ Syzygy tablebase 7 quân bị chậm trễ, Lichess đã chuyển từ cách quét toàn bộ block sang xác minh tính toàn vẹn khi đọc
- Để di chuyển tablebase 17TiB mà không phải downtime kéo dài, họ chuẩn bị một máy chủ mới và xác minh bằng cách phát lại log yêu cầu thực tế trong môi trường 32GiB RAM, 2×201GiB NVMe, 6×5.46TiB HDD
- Khi phát lại 1 triệu yêu cầu được ghi trong production bằng 12 client song song, điểm nghẽn chính lộ ra không phải độ trễ trung bình mà là độ trễ đuôi mà người dùng cảm nhận
- Về triển khai,
pread(2) có lợi hơn mmap ở xử lý lỗi và độ trễ đuôi, còn các hint truy cập ngẫu nhiên như POSIX_FADV_RANDOM và MADV_RANDOM nhìn chung lại phản tác dụng
- Họ đưa table prefix lên phần SSD giới hạn và song song hóa các probe bên trong mỗi yêu cầu để giảm truy cập đĩa chậm, rồi kiểm chứng rằng cải thiện benchmark cũng phản ánh vào thời gian phản hồi production
Chuyển sang xác minh khi đọc thay vì kiểm tra toàn bộ RAID
- Máy chủ Syzygy tablebase 7 quân của Lichess khó hoàn tất các lượt kiểm tra tính toàn vẹn RAID định kỳ trong lúc có nhiều yêu cầu tablebase
- Cấu hình mới dùng dm-integrity trên LVM, không kiểm tra định kỳ mọi block dữ liệu mà xác minh mỗi khi block được đọc
- Để di chuyển tablebase 17TiB mà không cần downtime vài giờ, họ dựng riêng một máy chủ mới
- Trước khi chuyển đổi thật, họ có thể chạy benchmark có kiểm soát trên toàn bộ tablebase
- Sau đó chuyển sang máy chủ mới và cho máy chủ cũ nghỉ hưu
Cấu hình máy chủ mới
- RAM được giữ ở mức 32GiB như trước
- Hệ thống lưu trữ được bổ sung 2×201GiB NVMe mà máy chủ cũ không có; phần dung lượng còn lại của ổ 476GiB được dành cho OS và không gian làm việc
- HDD tăng từ 5 ổ trước đây lên 6×5.46TiB HDD
- Hệ điều hành là Debian bookworm, kernel thuộc dòng
Linux 6.1.0-21-amd64
- I/O scheduler mặc định đang được chọn là
none trên NVMe và mq-deadline trên HDD
Thiết lập và giám sát RAID 5
- RAID 5 có thể phục hồi khi hỏng một ổ đĩa đơn và phân tán đọc ngẫu nhiên trên nhiều ổ, nên phù hợp với máy chủ tablebase
- Cấu hình ban đầu như sau
lvcreate --type raid5 --raidintegrity y --raidintegrityblocksize 512 --name tables --size 21T vg-hdd
- Hiệu năng kiểm thử ban đầu khá ổn, nhưng nếu không có giám sát thì có thể đã bỏ sót vấn đề một số ổ đĩa không tham gia ở cùng mức độ
- Nếu bỏ qua
--stripes, mặc định không dùng tất cả physical volume
- Cần giám sát hoạt động đọc theo từng ổ đĩa để phát hiện cấu hình RAID sai
Điểm nghẽn nhìn từ log yêu cầu thực tế
- Trong điều kiện bình thường, máy chủ nhận 10–35 yêu cầu mỗi giây
- Họ ghi lại 1 triệu yêu cầu trong môi trường production, rồi để 12 client song song gửi tuần tự các yêu cầu này trong kịch bản đã chọn
- Các table được mở theo kiểu lazy open, còn cache của ứng dụng và OS được lấp đầy dần
- 800 nghìn thời gian phản hồi đầu tiên bị loại khỏi phân tích như giai đoạn warm-up
- Sau đó họ phân tích thời gian phản hồi của 200 nghìn yêu cầu tiếp theo
- Thời gian phản hồi trung bình đủ nhanh, nhưng độ trễ đuôi cao nên trở thành trọng tâm tối ưu hóa
- Đồ thị ECDF cho biết tỷ lệ yêu cầu nhanh hơn từng mức thời gian phản hồi, với trục x dùng thang log
- Đồ thị cộng thêm 30ms vào mỗi thời gian phản hồi để phản ánh ping time 30ms của client
- Cách xử lý này nhằm tránh việc trục x thang log nhấn mạnh quá mức chênh lệch vài mili giây ở vùng thấp
pread(2) có lợi hơn mmap
- shakmaty-syzygy, triển khai Syzygy tablebase, cung cấp interface cho phép thay thế cách mở và đọc file table
- Có hai ứng viên chính
mmap: ánh xạ file table vào bộ nhớ, việc đọc đĩa diễn ra minh bạch khi truy cập vùng bộ nhớ tương ứng
pread(2): thực hiện system call cho mỗi lần đọc và báo lỗi đọc qua giá trị trả về
mmap không cần system call bổ sung sau khi mapping, nhưng vì thao tác đọc trông như truy cập bộ nhớ thông thường nên lỗi phải được xử lý bằng cơ chế ngoài luồng như signal
- Trong triển khai máy chủ, chỉ riêng khả năng xử lý lỗi chắc chắn hơn đã đủ để biện minh cho việc dùng
pread; benchmark cũng cho thấy trong kịch bản được quan tâm, hiệu năng của pread tốt hơn
- Một nguyên nhân có thể là việc truy cập một block dữ liệu đơn đã được memory-map có thể vượt qua ranh giới page và dẫn đến hai lần đọc đĩa
- Không nhất thiết phải áp dụng ngay
pread cho chess engine
- Việc dùng tablebase trong các trận engine thường diễn ra khi có thể đặt mọi WDL table trên thiết bị lưu trữ đủ nhanh
- Trong trường hợp này, phạm vi thời gian phản hồi thông thường nhanh đến mức không hiện trên đồ thị đó, và memory mapping giúp giảm overhead system call sẽ tốt hơn
Tác dụng ngược của hint truy cập ngẫu nhiên
posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM) và hint tương ứng cho memory map rốt cuộc hầu hết đều phản tác dụng
POSIX_FADV_RANDOM báo cho OS rằng truy cập file là ngẫu nhiên và read-ahead tự động nhiều khả năng không hữu ích, như một hint nhằm giảm áp lực lên page cache
- Mẫu truy cập tablebase khi người dùng phân tích tàn cuộc có thể không ngẫu nhiên như dự đoán
- Với chess engine, các probe có thể phân tán hơn giữa nhiều thế tàn cuộc khác nhau, nên kết quả có thể khác
Table prefix đưa lên SSD giới hạn
- Table probe trước hết mã hóa thế cờ thành chỉ số nguyên dựa trên thông tin mã hóa trong table header
- Sau đó cần tìm block dữ liệu nén chứa kết quả của chỉ số đó
- Syzygy cung cấp sparse block length list trỏ tới gần đúng entry phù hợp, rồi từ đó dùng block length list để tìm block dữ liệu liên quan
- Kích thước các table section như sau
| 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 |
- Cũng có thể dùng không gian SSD làm tầng cache thích ứng để cache các list entry và data block nóng
- Với mục tiêu giảm độ trễ đuôi, cách phù hợp là xét đến trường hợp xấu nhất và đặt sparse block length list cùng block length list trên SSD
- Bố trí này có thể giới hạn số lần đọc từ đĩa chậm xuống tối đa 1 lần cho mỗi table probe, bất kể dữ liệu nóng hay lạnh
- Trên máy chủ này, dung lượng SSD không đủ để mirror RAID 1; vì đây là tối ưu hóa có chọn lọc, họ chấp nhận bỏ tính dư thừa và dùng RAID 0
Song song hóa probe bên trong yêu cầu
- Một yêu cầu tablebase thông thường của chess engine là yêu cầu một giá trị WDL duy nhất
- Trong giao diện người dùng, hệ thống muốn hiển thị giá trị DTZ cho mọi nước đi
- Nếu tính cả việc xử lý capture nội bộ của Syzygy, một yêu cầu trung bình tạo ra 23 WDL probe và 70 DTZ probe
- Triển khai ban đầu đã song song hóa việc xử lý các yêu cầu, nhưng các probe bên trong từng yêu cầu vẫn chạy tuần tự
- Mức song song chi tiết hơn tạo ra overhead ở vùng độ trễ thấp, nhưng giảm đáng kể độ trễ đuôi
- Dù ổ đĩa thực tế không thể xử lý vật lý nhiều lượt đọc song song, I/O scheduler có khả năng lập kế hoạch đọc để từng yêu cầu hoàn tất nhanh hơn
- Cách này giúp lên kế hoạch tốt hơn cho thứ tự truy cập đĩa liên quan, nhằm giảm thời gian chờ đầu đọc đĩa đến sector của yêu cầu tiếp theo
Kiểm chứng production và dữ liệu gốc
- Họ dùng biểu đồ thời gian phản hồi để xác nhận các tối ưu hóa trong kịch bản benchmark có giúp ích cho production thực tế hay không
- Dữ liệu gốc được công bố tại lila-tablebase-bench
1 bình luận
Ý kiến trên Hacker News
Lichess là một dịch vụ khiến người ta chỉ biết đứng nhìn thán phục, như một chai rượu vang ngon. Nó thực sự tuyệt vời cho cộng đồng cờ vua, và tôi dùng mỗi ngày nên liên tục ấn tượng với tính năng lẫn hiệu năng của nó
Càng đáng kinh ngạc hơn khi biết đây là một đội chỉ khoảng 1~2 người với ngân sách hạn chế
Tôi thấy phần hiển thị ECDF cộng thêm 30ms vào mỗi thời gian phản hồi khá thú vị
Việc cộng một hằng số có thể trông hơi nhân tạo, nhưng thực ra đó là cách nhìn kết quả từ góc nhìn của một client có ping 30ms, đồng thời trục x theo thang log giúp không phóng đại chênh lệch vài ms ở vùng thấp. Có thể đây là kỹ thuật tiêu chuẩn, nhưng trông vẫn là một mẹo khá thông minh
Tôi tự hỏi liệu việc cắt giảm chi phí có thực sự cần thiết hay không, hay còn có lý do nào khác khiến họ không thể просто nhét SSD 20TB vào một cái hộp rồi xong chuyện. SSD 4TB cũng chỉ khoảng 300 USD, còn ổ SFF của HP hay Dell cũng không đắt hơn quá nhiều
Có lẽ họ đơn giản là hứng thú với việc thử nghiệm và tối ưu hóa, còn nếu nhìn từ góc độ sản phẩm thì tôi có lẽ sẽ dùng quỹ thời gian hạn chế đó cho dự án khác
Việc tổ chức đặt tại Pháp ảnh hưởng thế nào tới chi phí thì tôi không rõ, nhưng cũng đáng nhắc tới
Muốn biện minh tốt hơn cho việc dùng thời gian vào chỗ khác thì либо phải có dự án khác gây trải nghiệm tệ hơn nhiều, либо phải thừa nhận rằng trong một tổ chức vì lợi nhuận luôn có cơ hội kiếm tiền ở nơi khác và người ta cũng không quá bận tâm tới nỗi đau của khách hàng
Có vẻ đây là kết quả của phần cứng quá mạnh mà lại quá rẻ, cộng với những người lười chỉ muốn nói “đến đây là đủ cho hôm nay”. Chẳng phải người ta vẫn nói hãy tự hào về công việc mình làm sao
Có vài lựa chọn trong đợt tối ưu này khiến tôi thấy hơi đáng nghi. Lý do tối ưu là vì hoạt động I/O quá nhiều khiến kiểm tra RAID không thể hoàn thành
Chỉ đọc bài thì không rõ việc kiểm tra RAID trên 17TiB dữ liệu đó đã từng thực sự chạy xong hay chưa. Thay vào đó họ tắt kiểm tra RAID định kỳ và đổi sang kiểm tra lỗi theo từng trang khi đọc dữ liệu, nhưng hai cách này không giống nhau, và nếu dữ liệu quan trọng thì nên dùng cả hai
Nếu chỉ phát hiện hỏng hóc lúc định đọc dữ liệu, thì hỏng dữ liệu cũ có thể tồn tại rất lâu và có thể vượt quá thời hạn lưu bản sao lưu, khiến không thể khôi phục bản gốc. Ở đây còn hàm ý là họ đã chuyển sang RAID 0; đúng là đây là lựa chọn nhanh nhất, nhưng cũng đồng nghĩa đặt khá nhiều niềm tin rằng cấu hình NVMe đó sẽ chịu nổi tải kiểu này
Mong là họ có backup tốt. Một giải pháp hay là dựng máy chủ tạm, khôi phục bản sao lưu rồi kiểm tra toàn bộ dữ liệu; nếu thành công thì cũng đồng thời xác minh luôn quy trình backup/restore và tính toàn vẹn tệp. Dù vậy vẫn nên đảm bảo có đủ khoảng trống để hoàn thành kiểm tra RAID trên máy chủ chính, và tốt nhất không nên dùng RAID 0 chỉ vì hiệu năng
Đây là một bộ dữ liệu công khai, chỉ hơi lớn thôi. https://en.wikipedia.org/wiki/Endgame_tablebase giải thích rõ hơn. Vì thế họ cũng không backup
Cũng có lishogi, nhưng hiện vẫn nhỏ nên chưa đến mức cần kiểu tối ưu này
Trong các biến thể cờ, shogi là thú vị nhất, còn xiangqi thì không đến mức đó
Tôi từng tự hỏi liệu lichess có nghĩa là lich nữ không, kiểu như baron/baroness vậy
Nói chính xác thì lich nam là “werlich”, lich nữ là “wiflich”, và số nhiều thêm “-en”. Nhưng với undead thì giới tính thường chẳng quan trọng, nên dạng trung tính được dùng áp đảo
“lichess” là một tổ hợp kỳ quặc giữa gốc từ Đức và Pháp, nên nghe không khác mấy các từ tiếng Anh khác
Dù không phải so sánh hoàn toàn công bằng, tôi thực sự khâm phục chất lượng kỹ thuật của đội Lichess. Đối thủ chính của họ khoe chuyện chuyển sang GCP nhưng vẫn liên tục gặp sự cố mỗi khi độ phổ biến tăng lên, dù tôi đoán nhân sự phải nhiều hơn cỡ 100 lần
Điểm yếu của Lichess từng là ứng dụng di động, nhưng bản v2 làm lại bằng Flutter dù vẫn đang beta cũng đã khá tốt
Và cũng nên nhớ rằng Thibault nhận thù lao cho bản thân chưa tới 60.000 USD mỗi năm
Nhưng tôi vẫn thắc mắc Lichess được phát âm thế nào. Là Lie chess, Le chess hay League chess