Điều chỉnh các tham số định tuyến IP của Linux - secret_interval và tcp_mem


30

Chúng tôi đã có một chút vấn đề chuyển đổi dự phòng với một trong những máy ảo HAProxy của chúng tôi ngày hôm nay. Khi chúng tôi đào sâu vào nó, chúng tôi thấy điều này:

Ngày 26 tháng 1 07:41:45 kernel haproxy2: [226818.070059] __rat006it: 10 cuộc gọi lại bị chặn
26 tháng 1 07:41:45 kernel haproxy2: [226818.070064] Hết bộ nhớ ổ cắm
26 tháng 1 07:41:47 kernel haproxy2: [226819.560048] Hết bộ nhớ ổ cắm
26 tháng 1 07:41:49 kernel haproxy2: [226822.030044] Hết bộ nhớ ổ cắm

Mà, trên mỗi liên kết này , rõ ràng phải làm với các cài đặt mặc định thấp cho net.ipv4.tcp_mem. Vì vậy, chúng tôi đã tăng chúng lên gấp 4 lần từ mặc định của họ (đây là Ubuntu Server, không chắc là hương vị Linux có quan trọng không):

giá trị hiện tại là: 45984 61312 91968
giá trị mới là: 183936 245248 367872

Sau đó, chúng tôi bắt đầu thấy một thông báo lỗi kỳ quái:

26 tháng 1 08:18:49 kernel haproxy1: [2291.579726] Chuỗi băm tuyến quá dài!
26 tháng 1 08:18:49 hạt nhân haproxy1: [2291.579732] Điều chỉnh secret_interval của bạn!

Suỵt .. đó là một bí mật !!

Điều này rõ ràng phải làm với /proc/sys/net/ipv4/route/secret_intervalmặc định là 600 và kiểm soát việc xả định kỳ bộ đệm của tuyến đường

Các secret_intervalchỉ thị hạt nhân mức độ thường xuyên để thổi bay tất cả mục tuyến đường băm bất kể như thế nào mới / cũ họ đang có. Trong môi trường của chúng tôi điều này nói chung là xấu. CPU sẽ bận rộn xây dựng lại hàng ngàn mục mỗi giây mỗi khi xóa bộ nhớ cache. Tuy nhiên, chúng tôi đặt chế độ này để chạy mỗi ngày một lần để tránh rò rỉ bộ nhớ (mặc dù chúng tôi chưa bao giờ có một cái).

Mặc dù chúng tôi rất vui khi giảm điều này, nhưng có vẻ kỳ lạ khi khuyên bạn nên bỏ toàn bộ bộ đệm tuyến đường theo định kỳ , thay vì chỉ đơn giản là đẩy các giá trị cũ ra khỏi bộ đệm tuyến nhanh hơn.

Sau một số điều tra, chúng tôi thấy /proc/sys/net/ipv4/route/gc_elasticityrằng dường như là một lựa chọn tốt hơn để giữ kích thước bảng tuyến đường trong kiểm tra:

gc_elasticitytốt nhất có thể được mô tả là độ sâu xô trung bình mà hạt nhân sẽ chấp nhận trước khi nó bắt đầu hết hạn các mục băm tuyến. Điều này sẽ giúp duy trì giới hạn trên của các tuyến đang hoạt động.

Chúng tôi điều chỉnh độ co giãn từ 8 đến 4, với hy vọng bộ đệm tuyến đường tự cắt tỉa mạnh mẽ hơn. Điều secret_intervalđó không đúng với chúng tôi. Nhưng có một loạt các cài đặt và không rõ đó là cách đúng đắn để đi đến đây.

  • / Proc / sys / net / ipv4 / tuyến / gc_elasticity (8)
  • / Proc / sys / net / ipv4 / tuyến / gc_interval (60)
  • / Proc / sys / net / ipv4 / tuyến / gc_min_interval (0)
  • / Proc / sys / net / ipv4 / tuyến / gc_timeout (300)
  • / Proc / sys / net / ipv4 / tuyến / secret_interval (600)
  • / Proc / sys / net / ipv4 / tuyến / gc_thresh (?)
  • rhash_entries (tham số kernel, không xác định mặc định?)

Chúng tôi không muốn làm cho việc định tuyến Linux trở nên tồi tệ hơn , vì vậy chúng tôi sợ phải làm phiền với một số cài đặt này.

Bất cứ ai có thể tư vấn các tham số định tuyến nào là tốt nhất để điều chỉnh, cho một trường hợp HAProxy lưu lượng truy cập cao?

Câu trả lời:


28

Tôi chưa bao giờ gặp phải vấn đề này. Tuy nhiên, có lẽ bạn nên tăng chiều rộng bảng băm của mình để giảm độ sâu của nó. Sử dụng "dmesg", bạn sẽ thấy có bao nhiêu mục bạn hiện có:

$ dmesg | grep '^IP route'
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)

Bạn có thể thay đổi giá trị này với tham số dòng lệnh khởi động kernel rhash_entries. Trước tiên hãy thử bằng tay sau đó thêm nó vào lilo.confhoặc grub.conf.

Ví dụ: kernel vmlinux rhash_entries=131072

Có thể bạn có một bảng băm rất hạn chế vì bạn đã chỉ định ít bộ nhớ cho máy ảo HAProxy của mình (kích thước băm tuyến được điều chỉnh tùy thuộc vào tổng RAM).

Liên quan tcp_mem, cẩn thận. Cài đặt ban đầu của bạn khiến tôi nghĩ rằng bạn đang chạy với 1 GB RAM, 1/3 trong số đó có thể được phân bổ cho các ổ cắm TCP. Bây giờ bạn đã phân bổ 367872 * 4096 byte = 1,5 GB RAM cho ổ cắm TCP. Bạn nên rất cẩn thận để không bị hết bộ nhớ. Một nguyên tắc nhỏ là phân bổ 1/3 bộ nhớ cho HAProxy và 1/3 khác cho ngăn xếp TCP và 1/3 cuối cùng cho phần còn lại của hệ thống.

Tôi nghi ngờ rằng thông báo "hết bộ nhớ ổ cắm" của bạn đến từ cài đặt mặc định trong tcp_rmemtcp_wmem. Theo mặc định, bạn có 64 kB được phân bổ ở đầu ra cho mỗi ổ cắm và 87 kB cho đầu vào. Điều này có nghĩa là tổng cộng 300 kB cho kết nối được ủy quyền, chỉ dành cho bộ đệm ổ cắm. Thêm vào đó là 16 hoặc 32 kB cho HAProxy và bạn thấy rằng với 1 GB RAM, bạn sẽ chỉ hỗ trợ 3000 kết nối.

Bằng cách thay đổi cài đặt mặc định của tcp_rmemtcp_wmem(param param), bạn có thể giảm bộ nhớ xuống rất nhiều. Tôi nhận được kết quả tốt với các giá trị thấp tới 4096 cho bộ đệm ghi và 7300 hoặc 16060 trong tcp_rmem(5 hoặc 11 phân đoạn TCP). Bạn có thể thay đổi các cài đặt đó mà không cần khởi động lại, tuy nhiên chúng sẽ chỉ áp dụng cho các kết nối mới.

Nếu bạn không muốn chạm vào sysctls của mình quá nhiều, HAProxy mới nhất, 1.4-dev8, cho phép bạn điều chỉnh các tham số đó từ cấu hình toàn cầu và mỗi bên (máy khách hoặc máy chủ).

Tôi hy vọng điều này sẽ giúp!


8

Việc Out of socket memory errornày thường gây hiểu lầm. Hầu hết thời gian, trên các máy chủ phải đối mặt với Internet, nó không chỉ ra bất kỳ vấn đề nào liên quan đến việc hết bộ nhớ. Như tôi đã giải thích chi tiết hơn nhiều trong một bài đăng trên blog , lý do phổ biến nhất là số lượng ổ cắm mồ côi. Ổ cắm mồ côi là ổ cắm không liên quan đến bộ mô tả tệp. Trong một số trường hợp nhất định, kernel sẽ phát hành Out of socket memory errorngay cả khi bạn cách xa giới hạn (hoặc 2x /proc/sys/net/ipv4/tcp_max_orphans). Điều này xảy ra thường xuyên trong các dịch vụ phải đối mặt với Internet và là điều hoàn toàn bình thường. Hành động đúng đắn trong trường hợp này là điều chỉnh tối tcp_max_orphansthiểu gấp 4 lần số trẻ mồ côi bạn thường thấy với lưu lượng truy cập cao nhất của mình.

Đừng nghe lời khuyên nào đó đề nghị điều chỉnh tcp_memhoặc tcp_rmemhoặc tcp_wmemtrừ khi bạn thực sự biết những gì bạn đang làm. Những người đưa ra những lời khuyên này thường không. Voodoo của họ thường sai hoặc không phù hợp với môi trường của bạn và sẽ không giải quyết được vấn đề của bạn. Nó thậm chí có thể làm cho nó tồi tệ hơn.


1
Khi điều này xảy ra, thông báo sẽ khác trong dmesg, bạn thấy "quá nhiều ổ cắm mồ côi". Tuy nhiên tôi đồng ý với bạn rằng trẻ mồ côi có thể tiêu tốn một lượng lớn bộ nhớ.
Willy Tarreau

Khi bạn vượt quá số lượng /proc/sys/net/ipv4/tcp_max_orphansbạn sẽ gặp một lỗi khác. Ví dụ, toàn bộ ngăn xếp Stack Exchange có /proc/sys/net/ipv4/tcp_max_orphansở 65536 và /proc/net/sockstatkết quả là TCP: inuse 2996 mồ côi 171 tw 15972 cấp 2998 mem 1621 - một sự khác biệt không thể bỏ qua.
Geoff Dalgas

-4

Chúng tôi điều chỉnh một số các thông số này thường xuyên. Tiêu chuẩn của chúng tôi cho thông lượng cao, nền tảng giao dịch có độ trễ thấp là:

net.ipv4.tcp_rmem = 4096 16777216 33554432
net.ipv4.tcp_wmem = 4096 16777216 33554432
net.ipv4.tcp_mem = 4096 16777216 33554432
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 30000
net.core.netdev_max_backlog = 30000

1
theo toán học của Willy có nghĩa là áp suất bộ nhớ tiêu chuẩn của bạn # (số giữa) là 68 GB?! Lần ba (rmem, wmem, mem) ??
Jeff Atwood

10
Những điều chỉnh này là sai và rất thường xuyên được tìm thấy trong môi trường băng ghế sau đó sao chép một cách mù quáng. Họ sẽ không gặp vấn đề gì chỉ với một vài phiên đồng thời, nhưng ngay cả với 100 socket TCP, bạn sẽ phân bổ 3,2 GB RAM. Chừng nào độ trễ còn thấp, bạn sẽ không nhận thấy điều gì khả nghi. Bạn chỉ cần rút phích cắm của một máy từ xa trong khi chuyển để xem bộ đệm đầu ra điền hoặc đóng băng một tác vụ cục bộ và xem phần đệm bộ đệm đầu vào. Điều này thật điên rồ ...
Willy Tarreau

6
Jeff, đây không phải là ba lần. tcp_mem nằm trong các trang và xác định kích thước toàn cầu. tcp_rmem và tcp_wmem được tính bằng byte và xác định kích thước trên mỗi ổ cắm.
Willy Tarreau

Những điều chỉnh này có vẻ sai, đối với các máy chủ đồng thời có dữ liệu nhỏ mà bạn không muốn dự trữ quá nhiều bộ đệm ổ cắm và tcp_mem hoàn toàn khác với r / wmem, sử dụng cùng một số không thực sự có ý nghĩa, (một là byte cho mỗi Kết nối khác trang trên mỗi hệ thống)
eckes
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.