จำกัด ขนาดของบัฟเฟอร์แคชใน Linux


25

มีวิธีบอกเคอร์เนล Linux ให้ใช้หน่วยความจำเปอร์เซ็นต์หนึ่งสำหรับแคชบัฟเฟอร์หรือไม่? ฉันรู้ว่า/proc/sys/vm/drop_cachesสามารถใช้ล้างแคชชั่วคราวได้ แต่มีการตั้งค่าถาวรใด ๆ ที่ป้องกันไม่ให้เพิ่มขึ้นเป็นมากกว่า 50% ของหน่วยความจำหลักหรือไม่

เหตุผลที่ฉันต้องการทำเช่นนี้คือฉันมีเซิร์ฟเวอร์ที่ใช้ Ceph OSD ซึ่งให้บริการข้อมูลจากดิสก์อย่างต่อเนื่องและจัดการเพื่อใช้หน่วยความจำกายภาพทั้งหมดเป็นบัฟเฟอร์แคชภายในไม่กี่ชั่วโมง ในเวลาเดียวกันฉันจำเป็นต้องเรียกใช้แอปพลิเคชันที่จะจัดสรรหน่วยความจำกายภาพจำนวนมาก (หลาย 10s of GB) ตรงกันข้ามกับความเชื่อที่ได้รับความนิยม (ดูคำแนะนำในเกือบทุกคำถามเกี่ยวกับบัฟเฟอร์แคช) การเพิ่มหน่วยความจำโดยอัตโนมัติโดยการทิ้งรายการแคชสะอาดไม่ได้เกิดขึ้นทันที: การเริ่มต้นแอปพลิเคชันของฉันอาจใช้เวลาหนึ่งนาทีเมื่อบัฟเฟอร์แคชเต็ม *) ในขณะที่หลังจากล้างแคช (โดยใช้echo 3 > /proc/sys/vm/drop_caches) แอปพลิเคชันเดียวกันจะเริ่มต้นขึ้นทันที

(*) ในช่วงนาทีของเวลานี้เริ่มต้นโปรแกรมจะ faulting ในหน่วยความจำใหม่ แต่ใช้จ่าย 100% ของเวลาใน kernel ตาม VTune pageblock_pfn_to_pageในการทำงานที่เรียกว่า ฟังก์ชั่นนี้ดูเหมือนจะเกี่ยวข้องกับการบีบอัดหน่วยความจำที่จำเป็นในการค้นหาหน้าเว็บขนาดใหญ่ซึ่งทำให้ฉันเชื่อว่าการแตกแฟรกเมนต์เป็นปัญหา


1
มีบางสิ่งที่เรียกว่าการแบ่งระดับแคช ceph osd pool set {cachepool} hit_set_count 1 ceph osd pool set {cachepool} hit_set_period 3600 เซ็ตพูล pool ceph osd {cachepool} target_max_bytes 1000000000000 ตามตัวอย่างดู docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.

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

คำตอบ:


14

หากคุณไม่ต้องการขีด จำกัด แบบสัมบูรณ์ แต่เพียงกดปุ่มเคอร์เนลเพื่อล้างบัฟเฟอร์เร็วขึ้นคุณควรดู vm.vfs_cache_pressure

ตัวแปรนี้ควบคุมแนวโน้มของเคอร์เนลเพื่อเรียกคืนหน่วยความจำที่ใช้สำหรับการแคชแคช VFS เปรียบเทียบกับ pagecache และ swap การเพิ่มค่านี้จะเพิ่มอัตราการเรียกคืนแคช VFS

ช่วงจาก 0 ถึง 200 เลื่อนไปทาง 200 เพื่อแรงกดที่สูงขึ้น ค่าเริ่มต้นถูกตั้งไว้ที่ 100 คุณยังสามารถวิเคราะห์การใช้หน่วยความจำของคุณโดยใช้slabtopคำสั่ง ในกรณีของคุณค่าdentryและ*_inode_cacheค่าจะต้องสูง

ถ้าคุณต้องการ จำกัด cgroupsสัมบูรณ์คุณควรมองขึ้น วางเซิร์ฟเวอร์ Ceph OSD ภายใน cgroup และ จำกัด หน่วยความจำสูงสุดที่สามารถใช้ได้โดยการตั้งค่าmemory.limit_in_bytesพารามิเตอร์สำหรับ cgroup

memory.memsw.limit_in_bytesกำหนดจำนวนเงินสูงสุดสำหรับผลรวมของหน่วยความจำและการใช้งานการสลับ หากไม่ได้ระบุหน่วยค่าจะถูกตีความเป็นไบต์ อย่างไรก็ตามมันเป็นไปได้ที่จะใช้คำต่อท้ายเพื่อแสดงหน่วยที่ใหญ่กว่า - k หรือ K สำหรับกิโลไบต์, m หรือ M สำหรับเมกะไบต์, และ g หรือ G สำหรับกิกะไบต์

อ้างอิง:

[1] - ปรับแต่งเคอร์เนล Linux ของ GlusterFS

[2] - คู่มือการจัดการทรัพยากร RHEL 6


1
กลุ่ม cgroup พร้อมlimit_in_bytesชุดดูเหมือนว่าจะทำ ขอบคุณ!
Wim

4
ฉันคิดว่าvfs_cache_pressureจะล้าง Dentry และ inode แคชเท่านั้นและไม่มีอะไรเกี่ยวข้องกับบัฟเฟอร์แคช
kawing-chiu

การเพิ่มvfs_cache_pressureด้านบน100อาจช่วยได้ในกรณีที่คุณมี RAM ไม่เพียงพอสำหรับภาระงานของคุณ มันจะลดการใช้ RAM แต่จะทำให้ประสิทธิภาพ I / O โดยรวมแย่ลง
Mikko Rantalainen

3

ฉันไม่รู้เกี่ยวกับ A% แต่คุณสามารถกำหนดเวลาเพื่อให้มันลดลงหลังจาก x จำนวนนาที

ครั้งแรกในสถานี

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

เพื่อล้างแคชปัจจุบัน

ทำให้มันเป็นcron-job กด Alt-F2, ประเภทgksudo gedit /etc/crontab, แล้วเพิ่มบรรทัดนี้อยู่ด้านล่าง

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

ทำความสะอาดนี้ทุกๆ 15 นาที คุณสามารถตั้งค่าเป็น 1 หรือ 5 นาทีถ้าคุณต้องการด้วยการเปลี่ยนพารามิเตอร์แรกเป็น * หรือ * / 5 แทน * / 15

ในการดู RAM ว่างของคุณยกเว้นแคช:

free -m | sed -n -e '3p' | grep -Po "\d+$

ฉันรู้สึกว่าที่นี่ซ้ำซ้อนเล็กน้อย เท่าที่ฉันรู้3 > drop_cachesรวมถึงพฤติกรรมของsync
andras.tim

1
@ andras.tim no - การซิงค์จะเขียนเพจที่สกปรกไปยังดิสก์ 3 ถึง drop_caches จะเรียกคืน / เพิ่มหน่วยความจำที่ใช้โดยเพจที่ล้างและแคชอื่น ๆ เท่านั้น คุณไม่จำเป็นต้องเรียกใช้การซิงค์ แต่ถ้าคุณทำหน่วยความจำเพิ่มเติมจะสะอาดแทนที่จะสกปรกและหน่วยความจำจะเพิ่มขึ้นเมื่อคุณปล่อยแคช
Daniel S. Sterling

2

ฉันคิดว่าลางสังหรณ์ของคุณในตอนท้ายของคำถามของคุณอยู่ในเส้นทางที่ถูกต้อง ฉันสงสัยว่า A, NUMA- รู้จำการจัดสรรหน่วยความจำหน้าโยกย้ายระหว่างซีพียูหรือ B มีแนวโน้มมากขึ้นรหัส defrag ของ hugepages โปร่งใสพยายามหาภูมิภาคที่ต่อเนื่องกัน

Hugepages และ hugepages แบบโปร่งใสได้รับการระบุสำหรับการปรับปรุงประสิทธิภาพการทำเครื่องหมายในปริมาณงานบางอย่างและรับผิดชอบในการใช้เวลา CPU จำนวนมหาศาลโดยไม่ได้รับประโยชน์มากนัก

มันจะช่วยให้ทราบว่าเคอร์เนลใดที่คุณกำลังทำงานเนื้อหาของ / proc / meminfo (หรืออย่างน้อยค่า HugePages_ *.) และถ้าเป็นไปได้ vtune profiler callgraph ที่อ้างอิงการอ้างอิง pageblock_pfn_to_page ()

นอกจากนี้หากคุณทำตามที่ฉันคาดเดาลองปิดการใช้งาน hugepage defrag ด้วย:

echo 'never'> / sys / kernel / mm / transparent_hugepage / defrag

(อาจเป็นเพราะมันขึ้นอยู่กับเคอร์เนลของคุณ :)

echo 'never'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

สุดท้ายนี้แอพนี้ใช้ ram หลายสิบกิ๊กที่คุณเขียนหรือเปล่า? ภาษาอะไร?

เนื่องจากคุณใช้คำว่า "faulting ในหน้าหน่วยความจำ" ฉันเดาว่าคุณคุ้นเคยกับการออกแบบการใช้งานและหน่วยความจำเสมือน ฉันพยายามจินตนาการถึงสถานการณ์ / แอปพลิเคชันที่อาจเป็นความผิดพลาดอย่างจริงจังที่ไม่ได้อ่าน I / O มากมาย - มักจะมาจากบัฟเฟอร์แคชที่คุณพยายาม จำกัด

(หากคุณสงสัยให้ตรวจสอบการทำเครื่องหมาย mmap (2) เช่น MAP_ANONYMOUS และ MAP_POPULATE และ mincore (2) ซึ่งสามารถใช้เพื่อดูว่าหน้าเสมือนจริงใดที่มีหน้าทางกายภาพที่ถูกแมป)

โชคดี!


2

หาก Ceph OSD เป็นกระบวนการหนึ่งที่แยกจากกันคุณสามารถใช้cgroupsทรัพยากรการควบคุมโดยใช้กระบวนการ:

สร้าง cgroup ชื่อเช่น group1 ที่มีขีด จำกัด หน่วยความจำ (เช่น 50GB, รองรับข้อ จำกัด อื่น ๆ เช่น CPU, ใน CPU ที่กล่าวถึงด้วย):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

จากนั้นหากแอปของคุณกำลังทำงานอยู่ให้นำแอปไปยัง cgroup นี้:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

หรือเรียกใช้แอปของคุณภายในกลุ่มนี้:

cgexec -g memory,cpu:group1 your_app_name

0

tunedเป็น daemon การปรับแต่งระบบแบบไดนามิกที่ปรับแต่งการตั้งค่าระบบแบบไดนามิกขึ้นอยู่กับการใช้งาน

 $ man tuned

ดูเอกสารที่เกี่ยวข้องและไฟล์การกำหนดค่า

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

ข้อมูลเพิ่มเติม

ซิงค์คำสั่งวูบวาบบัฟเฟอร์คือกองกำลังของข้อมูลที่ไม่ได้เขียนไว้ทั้งหมดจะถูกเขียนไปยังดิสก์และสามารถนำมาใช้เมื่ออยากจะแน่ใจว่าทุกอย่างจะถูกเขียนได้อย่างปลอดภัย ในระบบ UNIX แบบดั้งเดิมมีโปรแกรมที่เรียกว่าupdateกำลังทำงานในพื้นหลังซึ่งทำการซิงค์ทุก ๆ 30 วินาทีดังนั้นโดยทั่วไปไม่จำเป็นต้องใช้การซิงค์ Linux มี daemon เพิ่มเติมเพิ่มเติมคือbdflushซึ่งทำการซิงค์ที่ไม่สมบูรณ์มากขึ้นบ่อยขึ้นเพื่อหลีกเลี่ยงการค้างอย่างกะทันหันเนื่องจาก I / O ของดิสก์หนักที่บางครั้งทำให้เกิดการซิงค์

ภายใต้ Linux bdflushเริ่มโดยการอัพเดท โดยทั่วไปจะไม่มีเหตุผลที่จะต้องกังวล แต่ถ้า bdflush เกิดขึ้นด้วยเหตุผลบางอย่างเคอร์เนลจะเตือนเกี่ยวกับสิ่งนี้และคุณควรเริ่มด้วยมือ ( / sbin / update )


1
นี่ไม่ใช่แค่สำหรับรายการที่สกปรกใช่ไหม ฉันไม่คิดว่าเป็นปัญหาในระบบของฉันเพราะทุกอย่างสะอาดหมดจดแล้วความล่าช้าไม่ใช่การเขียนหน้าสกปรก แต่เป็นการจัดเรียงข้อมูลในพื้นที่ด้านซ้ายโดยลบสิ่งที่สะอาดออก
Wim

ใช่นี่เป็นหน้าที่สกปรกฉันคิดว่าคุณสามารถแก้ไขปัญหาด้านประสิทธิภาพอื่น ๆ ได้ด้วยการตั้งค่าปรับเป็นโหมดไดนามิก
Ijaz Ahmad Khan

"ตั้งแต่ Linux 2.6, การเรียกระบบ [the bdflush] เลิกใช้แล้วและไม่ทำอะไรเลยมันน่าจะหายไปโดยสิ้นเชิงในการปล่อยเคอร์เนลในอนาคตทุกวันนี้งานที่ดำเนินการโดย bdflush () ถูกจัดการโดยเคอร์เนลเธรด pdflush" man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.