# bkdnOJ.v2 - Cấu hình uwsgi tối ưu hiệu năng server
- Updated 27 tháng 10, 2022
- Trong bài viết này đề cập về hai chủ đề chính:
- Các options trong file cấu hình `uwsgi.ini`
- Thiết lập uwsgi và phân tích nhu cầu sử dụng CPU và RAM của hai case: sử dụng bình thường (200 concurrent users) và sử dụng khi tổ chức contest (2000 concurrent users).
### File cấu hình `uwsgi.ini`:
Hiện tại, ta chỉ đang quan tâm đến các options sau:
```
cheaper-algo = backlog
cheaper = 3
cheaper-initial = 5
cheaper-step = 2
cheaper-rss-limit-soft = 201326592
cheaper-rss-limit-hard = 234881024
workers = 8
```
Một số thông tin:
- `cheaper-backlog`: Thuật toán tạo/giết threads, ta để là `backlog`
- `cheaper`: Số lượng threads tối thiểu luôn có
- `workers`: Số lượng threads tối đa mà uwsgi sẽ tạo ra
- `cheaper-initial`: Khi chạy uwsgi thì sẽ khởi tạo chừng này threads
- `cheaper-steps`: Bước nhảy, số threads mà uwsgi sẽ tạo ra cùng một lúc
- `cheaper-rss-limit-soft`: Giới hạn mềm memory của uwsgi. Khi uwsgi sử dụng nhiều hơn chừng này, uwsgi sẽ không tạo ra thread mới bất kể điều kiện.
- `cheaper-rss-limit-hard`: Giới hạn cứng memory. Khi uwsgi sử dụng nhiều hơn chừng này, uwsgi sẽ bắt đầu giết threads.
Nhận xét:
- `workers` nên là một số phụ thuộc vào số lượng người dùng cùng một lúc trong mong muốn. (ví dụ = số_người_cùng_lúc * hệ_số) (= 200 * 1.3). Hệ số sẽ phụ thuộc vào contest mà ta đang tổ chức, nên là một số thực trong khoảng \[1.0,2.0\]
- `cheaper-initial` nên là một số lớn, (ví dụ = worker/2). Vì có lúc đang thi nhưng ta cần khởi động lại uwsgi, uwsgi có thể ứng phó với `cheaper-initial` requests ngay lập tức mà không cần chờ tạo thêm threads.
- `cheaper-steps` là chỉ số sẽ giúp uwsgi đối phó với một tải lớn bất ngờ. Ví dụ số requests đến bỗng dưng nhảy lên 1000, thì `(1000-cheaper)/cheaper-steps` sẽ là upper bound cho số đơn vị thời gian mà uwsgi ứng phó được tải bất ngờ. Đối với options này ta sẽ thử nghiệm 5,10,20,100,200... chứ không rõ tiêu chí để gán.
- `cheaper-rss-limit-soft`, `cheaper-rss-limit-hard` ta sẽ thông qua chúng để đảm bảo vẫn còn dư memory cho các tiến trình khác (vd: máy chấm)
### Thiết lập cho ca sử dụng bình thường
Giả định:
- Máy có 4 core, 4GB RAM
- => Mục tiêu: sử dụng 70% RAM => 2.8GB
- Có 200 người sử dụng cùng lúc (tính admin = 4 user thường).
- => Workers = 200
- Request có max kích cỡ là 100kB (vd: Problem PDF size=100kB).
- => Tệ nhất 200 rq sẽ dùng maximum mem=40MB.
- Có 4 máy chấm, Problem có mem khoảng là 256~512MB
- => TH tệ nhất: chấm MLE hết sử dụng 1.5~2GB => dư 0.8~1.3GB.
- => Vì muốn dư dả nữa, ta cho phép uwsgi chỉ dùng 0.5~1GB RAM
Cấu hình:
```
cheaper-algo = backlog
cheaper = 10
cheaper-initial = 50
cheaper-step = 5
workers = 200
cheaper-rss-limit-soft = 536870912
cheaper-rss-limit-hard = 1073741824
```
Nhận xét:
- Cấu hình mặc định `workers=8,cheaper=3,cheaper-step=2` dù hơi lag nhưng cũng đủ để chạy https://bkdnoj.com/contest/icpc_dut_final/standing với số người 30~100, config mới đảm bảo trải nghiệm mượt mà hơn.
- Tối thiểu thì có lẽ chỉ cần 2GB RAM cũng chạy được.
- Phần RAM dư còn lại sẽ được Django/DB/OS sử dụng.
### Thiết lập cho contest lớn
Giả định:
- Máy có 48 core, 16GB RAM
- => Mục tiêu: sử dụng 14GB RAM
- Có 2000 người sử dụng cùng lúc (tính admin = 4 user thường).
- `[!]` Vì mỗi contest khác nhau có tải đề và tải standing khác nhau, việc chọn hệ số cân bằng cũng sẽ khó khăn. Ở đây tôi xin chọn hệ số 1.7.
- => Workers = max_users_count * hệ_số_cân_bằng = 2000 * 1.7 = 3400
- Request có max kích cỡ là 200kB.
- => Tệ nhất 3400 rq sẽ dùng maximum mem=665MB.
- Thực tế, ở cuộc thi ICPC Central 2022, Network Out đỉnh điểm là 242MB. Ta có thể xem đây là lower bound cho memory sẽ sử dụng bởi uwsgi.

- `[!]` Ở ICPC Central 2022 sử dụng 40 máy chấm và trải nghiệm chấm khá tốt. Chúng ta có thể theo cấu hình này.
- Cho rằng contest có 70% số bài có 256MB, và 30% là 512MB. Ta có mem avg=333MB một bài.
- => TH tệ nhất: chấm MLE hết sử dụng 13GB => dư 1GB. (Hiếm xảy ra nhưng vẫn có thể nếu nhiều đội phối hợp để phá hệ thống)
- => Có thể giảm số máy chấm xuống còn 33~36 máy để dư 2-3GB RAM.
- => Ta cho phép uwsgi dùng 1.5~2GB RAM
- `[!]` Ở ICPC Central 2022 ta đã khai báo uwsgi sử dụng 1.9~2.3GB RAM.
Cấu hình:
```
cheaper-algo = backlog
cheaper = 500
cheaper-initial = 2000
cheaper-step = 100
workers = 3400
cheaper-rss-limit-soft = 1610612736
cheaper-rss-limit-hard = 2147483648
```