Gần đây tôi đã dành khá nhiều thời gian để theo dõi một vấn đề trong sản xuất, khi một máy chủ cơ sở dữ liệu biến mất sẽ gây ra sự cố kéo dài tới 2 giờ (chờ đợi một poll()
cuộc gọi trong thư viện máy khách libpq) cho một máy khách được kết nối. Đi sâu vào vấn đề, tôi nhận ra rằng các tham số kernel này nên được điều chỉnh xuống để các kết nối TCP bị cắt đứt được chú ý một cách kịp thời:
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries2 = 15
Bốn giá trị trên là từ một máy Ubuntu 12.04 và có vẻ như các giá trị mặc định này không thay đổi so với mặc định của nhân Linux hiện tại .
Các cài đặt này dường như thiên vị rất nhiều đối với việc giữ kết nối hiện có mở và cực kỳ keo kiệt với các đầu dò cố định. AIUI, mặc định tcp_keepalive_time
là 2 giờ có nghĩa là khi chúng tôi chờ phản hồi cho máy chủ từ xa, chúng tôi sẽ kiên nhẫn chờ trong 2 giờ trước khi bắt đầu một thăm dò cố định để xác minh kết nối của chúng tôi vẫn hợp lệ. Và sau đó, nếu máy chủ từ xa không phản hồi với đầu dò cố định, chúng tôi thử lại các đầu dò cố định đó 9 lần ( tcp_keepalive_probes
), cách nhau 75 giây ( tcp_keepalive_intvl
), do đó, thêm 11 phút trước khi chúng tôi quyết định kết nối thực sự đã chết.
Điều này khớp với những gì tôi đã thấy trong trường: ví dụ: nếu tôi bắt đầu một psql
phiên được kết nối với một phiên bản PostgreQuery từ xa, với một số truy vấn đang chờ phản hồi, ví dụ:
SELECT pg_sleep(30);
và sau đó máy chủ từ xa sẽ chết một cách khủng khiếp (ví dụ: giảm lưu lượng truy cập vào máy đó), tôi thấy phiên psql của tôi chờ tới 2 giờ 11 phút trước khi kết nối được kết nối của nó đã chết. Như bạn có thể tưởng tượng, các cài đặt mặc định này gây ra các vấn đề nghiêm trọng cho mã mà chúng ta đã nói chuyện với cơ sở dữ liệu trong quá trình chuyển đổi cơ sở dữ liệu. Vặn các núm này xuống đã giúp rất nhiều! Và tôi thấy rằng tôi không đơn độc trong việc khuyến nghị những mặc định này được điều chỉnh.
Vì vậy, câu hỏi của tôi là:
- Đã bao lâu mặc định như thế này?
- Lý do ban đầu để biến các cài đặt TCP này thành mặc định là gì?
- Có bất kỳ bản phân phối Linux nào thay đổi các giá trị mặc định này không?
Và bất kỳ lịch sử hoặc quan điểm nào khác về lý do cho các cài đặt này sẽ được đánh giá cao.
TCP_KEEPIDLE
, TCP_KEEPCNT
và TCP_KEEPINTVL
.
TCP_USER_TIMEOUT
, thay vì cài đặt toàn net.ipv4.tcp_retries2
hệ thống. Tất nhiên, nhiều ứng dụng (như PostgreSQL trong ví dụ của tôi ở đây) chưa hỗ trợ TCP_USER_TIMEOUT
.