การปรับพารามิเตอร์การกำหนดเส้นทาง Linux IP - secret_interval และ tcp_mem


30

เราประสบปัญหาการขัดข้องเล็กน้อยกับหนึ่งใน HAProxy VMs ของเราวันนี้ เมื่อเราขุดลงไปเราจะพบสิ่งนี้:

26 มกราคม 07:41:45 เคอร์เนล haproxy2: [226818.070059] ratratit: 10 ระงับการโทรกลับ
26 มกราคม 07:41:45 เคอร์เนล haproxy2: [226818.070064] ออกจากหน่วยความจำซ็อกเก็ต
26 มกราคม 07:41:47 เคอร์เนล haproxy2: [226819.560048] ออกจากหน่วยความจำซ็อกเก็ต
26 มกราคม 07:41:49 เคอร์เนล haproxy2: [226822.030044] ออกจากหน่วยความจำซ็อกเก็ต

ซึ่งต่อลิงก์นี้net.ipv4.tcp_memเห็นได้ชัดว่าจะทำอย่างไรกับการตั้งค่าเริ่มต้นต่ำ ดังนั้นเราจึงเพิ่มพวกมันขึ้น 4 เท่าจากค่าเริ่มต้น (นี่คือเซิร์ฟเวอร์ Ubuntu ไม่แน่ใจว่ารสชาติของ Linux มีความสำคัญ):

ค่าปัจจุบันคือ: 45984 61312 91968
ค่าใหม่คือ: 183936 245248 367872

หลังจากนั้นเราเริ่มเห็นข้อความแสดงข้อผิดพลาดที่แปลกประหลาด:

26 มกราคม 08:18:49 เคอร์เนล haproxy1: [2291.579726] เส้นทางแฮชเชนยาวเกินไป!
26 มกราคม 08:18:49 เคอร์เนล haproxy1: [2291.579732] ปรับ secret_interval ของคุณ!

Shh .. มันเป็นความลับ !!

เห็นได้ชัดว่าสิ่งนี้เกี่ยวข้องกับ/proc/sys/net/ipv4/route/secret_intervalค่าเริ่มต้นที่ 600 และควบคุมการล้างแคชเส้นทางเป็นระยะ

secret_intervalสั่งเคอร์เนลวิธีการที่มักจะพัดไปทุกรายการเส้นทางกัญชาโดยไม่คำนึงถึงวิธีการใหม่ / เก่าที่พวกเขามี ในสภาพแวดล้อมของเรานี้โดยทั่วไปจะไม่ดี CPU จะกำลังสร้างรายการหลายพันรายการต่อวินาทีทุกครั้งที่มีการล้างแคช อย่างไรก็ตามเราตั้งค่านี้ให้ทำงานวันละครั้งเพื่อป้องกันการรั่วไหลของหน่วยความจำ (แม้ว่าเราไม่เคยมี)

ในขณะที่เรามีความสุขที่จะลดสิ่งนี้ดูเหมือนว่าแปลกที่จะแนะนำให้วางแคชเส้นทางทั้งหมดในช่วงเวลาปกติแทนที่จะเพียงผลักค่าเก่าออกจากแคชเส้นทางเร็วขึ้น

หลังจากการตรวจสอบเราพบ/proc/sys/net/ipv4/route/gc_elasticityว่ามีตัวเลือกที่ดีกว่าในการตรวจสอบขนาดตารางเส้นทางในการตรวจสอบ:

gc_elasticityสามารถอธิบายได้ดีที่สุดเนื่องจากความลึกของที่เก็บข้อมูลโดยเฉลี่ยเคอร์เนลจะยอมรับก่อนที่จะเริ่มหมดอายุรายการแฮชของเส้นทาง สิ่งนี้จะช่วยรักษาขีด จำกัด บนของเส้นทางที่ใช้งานอยู่

เราปรับความยืดหยุ่นจาก 8 เป็น 4 ด้วยความหวังว่าแคชเส้นทางจะตัดแต่งตัวเองอย่างจริงจังมากขึ้น ความsecret_intervalรู้สึกไม่ถูกต้องกับเรา แต่มีการตั้งค่ามากมายและไม่มีความชัดเจนซึ่งเป็นวิธีที่เหมาะสมในการไปที่นี่

  • / proc / sys / net / ipv4 / เส้นทาง / gc_elasticity (8)
  • / proc / sys / net / ipv4 / เส้นทาง / gc_interval (60)
  • / proc / sys / net / ipv4 / เส้นทาง / gc_min_interval (0)
  • / proc / sys / net / ipv4 / เส้นทาง / gc_timeout (300)
  • / proc / sys / net / ipv4 / เส้นทาง / secret_interval (600)
  • / proc / sys / net / ipv4 / เส้นทาง / gc_thresh (?)
  • rhash_entries (พารามิเตอร์เคอร์เนลไม่ทราบค่าเริ่มต้น?)

เราไม่ต้องการทำให้เส้นทาง Linux แย่ลงดังนั้นเราจึงกลัวที่จะยุ่งกับการตั้งค่าเหล่านี้

มีใครบ้างที่สามารถแนะนำพารามิเตอร์การกำหนดเส้นทางที่ดีที่สุดในการปรับแต่งสำหรับอินสแตนซ์ HAProxy ที่มีปริมาณการใช้งานสูง

คำตอบ:


28

ฉันไม่เคยเจอปัญหานี้เลย อย่างไรก็ตามคุณควรเพิ่มความกว้างของตารางแฮชเพื่อลดความลึก เมื่อใช้ "dmesg" คุณจะเห็นจำนวนรายการที่คุณมีอยู่ในปัจจุบัน:

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

rhash_entriesคุณสามารถเปลี่ยนค่านี้กับบูตเคอร์เนลพารามิเตอร์บรรทัดคำสั่ง ความพยายามครั้งแรกด้วยมือแล้วเพิ่มที่คุณหรือlilo.confgrub.conf

ตัวอย่างเช่น: kernel vmlinux rhash_entries=131072

เป็นไปได้ว่าคุณมีตารางแฮชที่ จำกัด มากเนื่องจากคุณได้กำหนดหน่วยความจำเล็กน้อยให้กับ HAProxy VM ของคุณ (ขนาดแฮชเส้นทางจะถูกปรับขึ้นอยู่กับ RAM ทั้งหมด)

เกี่ยวกับtcp_memระวัง การตั้งค่าเริ่มต้นของคุณทำให้ฉันคิดว่าคุณใช้ RAM 1 GB ซึ่งสามารถจัดสรรให้กับซ็อกเก็ต TCP ได้ 1/3 ตอนนี้คุณได้จัดสรร 367872 * 4096 ไบต์ = RAM 1.5 GB ไปยังซ็อกเก็ต TCP คุณควรระมัดระวังไม่ให้หน่วยความจำหมด กฎของหัวแม่มือคือการจัดสรร 1/3 ของหน่วยความจำให้กับ HAProxy และอีก 1/3 ของสแต็ก TCP และ 1/3 สุดท้ายกับส่วนที่เหลือของระบบ

ฉันสงสัยว่า "ออกจากหน่วยความจำซ็อกเก็ต" ของคุณข้อความมาจากการตั้งค่าเริ่มต้นในและtcp_rmem tcp_wmemโดยค่าเริ่มต้นคุณจะได้รับการจัดสรร 64 kB สำหรับเอาต์พุตสำหรับแต่ละซ็อกเก็ตและ 87 kB สำหรับอินพุต ซึ่งหมายถึงจำนวน 300 kB สำหรับการเชื่อมต่อพร็อกซีสำหรับซ็อกเก็ตบัฟเฟอร์ เพิ่มไปที่ 16 หรือ 32 kB สำหรับ HAProxy และคุณจะเห็นว่าด้วย RAM ขนาด 1 GB คุณจะรองรับการเชื่อมต่อได้ 3,000 ครั้งเท่านั้น

ด้วยการเปลี่ยนการตั้งค่าเริ่มต้นของtcp_rmemและtcp_wmem(พารามิเตอร์กลาง) คุณจะได้รับความจำที่ลดลงมาก ฉันได้รับผลลัพธ์ที่ดีด้วยค่าต่ำสุดที่ 4096 สำหรับบัฟเฟอร์การเขียนและ 7300 หรือ 16060 ในtcp_rmem(เซ็กเมนต์ TCP 5 หรือ 11) คุณสามารถเปลี่ยนการตั้งค่าเหล่านั้นได้โดยไม่ต้องเริ่มต้นใหม่ แต่การตั้งค่าเหล่านั้นจะใช้กับการเชื่อมต่อใหม่เท่านั้น

หากคุณไม่ต้องการสัมผัสsysctlsของคุณมากเกินไป HAProxy ล่าสุด, 1.4-dev8 ช่วยให้คุณสามารถปรับแต่งพารามิเตอร์เหล่านั้นจากการกำหนดค่าทั่วโลกและต่อด้าน (ไคลเอนต์หรือเซิร์ฟเวอร์)

ฉันหวังว่านี่จะช่วยได้!


8

Out of socket memory errorมักจะเป็นความเข้าใจผิด ส่วนใหญ่แล้วบนเซิร์ฟเวอร์ที่เผชิญกับอินเทอร์เน็ตก็ไม่ได้บ่งบอกถึงปัญหาใด ๆ ที่เกี่ยวข้องกับหน่วยความจำไม่เพียงพอ ดังที่ฉันอธิบายรายละเอียดในบล็อกโพสต์เหตุผลที่พบบ่อยที่สุดคือจำนวนซ็อกเก็ตเด็กกำพร้า ซ็อกเก็ตเด็กกำพร้าเป็นซ็อกเก็ตที่ไม่เกี่ยวข้องกับตัวให้คำอธิบายไฟล์ ในบางสถานการณ์เคอร์เนลจะออกOut of socket memory errorแม้ในขณะที่คุณอยู่ห่างจากขีด จำกัด ( /proc/sys/net/ipv4/tcp_max_orphans) หรือ 2x สิ่งนี้เกิดขึ้นบ่อยครั้งในบริการที่เข้ากับอินเทอร์เน็ตและเป็นเรื่องปกติอย่างสมบูรณ์ การดำเนินการที่ถูกต้องในกรณีนี้คือการปรับtcp_max_orphansจำนวนเด็กกำพร้าอย่างน้อย 4x ตามปกติที่คุณเห็นด้วยปริมาณการใช้งานสูงสุด

ไม่ฟังคำแนะนำที่แนะนำการปรับแต่งใด ๆtcp_memหรือtcp_rmemหรือtcp_wmemจนกว่าคุณจริงๆจะรู้ว่าสิ่งที่คุณทำ ผู้ที่ให้คำแนะนำเหล่านี้โดยทั่วไปไม่ได้ วูดูของพวกเขามักจะผิดหรือไม่เหมาะสมกับสภาพแวดล้อมของคุณและจะไม่แก้ปัญหาของคุณ มันอาจทำให้แย่ลง


1
เมื่อสิ่งนี้เกิดขึ้นข้อความจะแตกต่างกันใน dmesg คุณจะเห็น "ซ็อกเก็ตเด็กกำพร้ามากเกินไป" อย่างไรก็ตามฉันเห็นด้วยกับคุณว่าเด็กกำพร้าสามารถใช้หน่วยความจำจำนวนมากได้
Willy Tarreau

เมื่อคุณเกินจำนวน/proc/sys/net/ipv4/tcp_max_orphansคุณจะพบข้อผิดพลาดที่แตกต่างกัน สแต็ก Exchange Stack ทั้งหมดเช่นมี/proc/sys/net/ipv4/tcp_max_orphansที่ 65536 และ/proc/net/sockstatผลลัพธ์ใน TCP: inuse 2996 orphan 171 tw 15972 จัดสรร 2998 mem 1621 - ความแตกต่างที่ไม่สามารถละเว้นได้
Geoff Dalgas

-4

เราปรับพารามิเตอร์เหล่านี้บางส่วนเป็นประจำ มาตรฐานของเราสำหรับปริมาณงานสูงและแพลตฟอร์มการซื้อขายแฝงต่ำคือ:

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
ต่อคณิตศาสตร์ของ Willy นั่นหมายถึงความดันหน่วยความจำมาตรฐานของคุณ # (หมายเลขกลาง) คือ 68 GB! คูณสาม (rmem, wmem, mem)?
Jeff Atwood

10
tunables เหล่านี้ผิดและพบได้บ่อยมากในสภาพแวดล้อมแบบตั้งโต๊ะจากนั้นจึงคัดลอกวาง พวกเขาจะไม่มีปัญหาใด ๆ กับเซสชันที่เกิดขึ้นพร้อมกันเพียงไม่กี่ครั้ง แต่แม้จะมีซ็อกเก็ต 100 TCP คุณจะจัดสรร RAM 3.2 GB ตราบใดที่เวลาแฝงอยู่ในระดับต่ำคุณจะไม่สังเกตเห็นสิ่งที่น่าสงสัย คุณเพียงแค่ต้องถอดปลั๊กเครื่องรีโมตระหว่างการถ่ายโอนเพื่อดูบัฟเฟอร์เอาต์พุตเต็มหรือตรึงภารกิจโลคัลและดูอินพุตบัฟเฟอร์เติม นี่มันบ้า ...
Willy Tarreau

6
Jeff นี่ไม่ใช่สามครั้ง tcp_mem อยู่ในหน้าและกำหนดขนาดโกลบอล tcp_rmem และ tcp_wmem อยู่ในหน่วยไบต์และกำหนดขนาดต่อซ็อกเก็ต
Willy Tarreau

สำหรับเซิร์ฟเวอร์พร้อมกันที่มีข้อมูลขนาดเล็กคุณไม่ต้องการจองซ็อกเก็ตบัฟเฟอร์จำนวนมากและ tcp_mem นั้นแตกต่างจาก r / wmem โดยใช้หมายเลขเดียวกันไม่สมเหตุสมผล (หนึ่งต่อไบต์ต่อการเชื่อมต่ออื่น ๆ หน้าต่อระบบ)
eckes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.