Các cài đặt mặc định Linux TCP này được quyết định như thế nào?


13

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_timelà 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 psqlphiê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.


Một số thông tin có liên quan ở đây ... tldp.org/HOWTO/TCP-Keepalive-HOWTO/USEkeepalive.html
Drav Sloan

Lưu ý rằng bạn có thể thay đổi ba mỗi kết nối đầu tiên trong mã khách hàng với các tùy chọn ổ cắm TCP_KEEPIDLE, TCP_KEEPCNTTCP_KEEPINTVL.
wnoise

1
@wnoise thực sự kể từ Linux 2.6.37 cũng có thể chỉ định tùy chọn ổ cắm TCP_USER_TIMEOUT, thay vì cài đặt toàn net.ipv4.tcp_retries2hệ 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.
Josh Kupershmidt

Câu trả lời:


6

RFC 1122 chỉ định trong mục 4.2.3.6 rằng thời gian duy trì không được mặc định dưới hai giờ.


1
Rất vui, cảm ơn bạn đã đào nó lên. Tôi nghĩ rằng chủ yếu trả lời câu hỏi tại sao tcp_keepalive_timemặc định là 7200, mặc dù tôi vẫn quan tâm đến tiền lệ / giải thích cho ba cài đặt có liên quan khác.
Josh Kupershmidt

Xóa câu trả lời của tôi vì điều này trả lời câu hỏi (ít nhất là cho một trong các giá trị)
coteyr

1
@coteyr Dù sao cũng cảm ơn, tôi đánh giá cao nỗ lực này. IIRC đã có một nhận xét hấp dẫn về câu trả lời của bạn cho thấy rằng trong các nhân Linux trước đó, mặc định là 15 phút. Tôi muốn biết làm thế nào / tại sao điều đó đã thay đổi thành 2 giờ hoặc đặt thành 15 phút ở vị trí đầu tiên.
Josh Kupershmidt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.