ضبط خيارات Linux Kernel لتحسين PostgreSQL

ضبط خيارات Linux Kernel لتحسين PostgreSQL يعتمد أداء PostgreSQL الأمثل على إعدادات نظام التشغيل المحددة بشكل صحيح. يمكن أن تؤدي معلمات نواة نظام التشغيل سيئة التكوين إلى بطء أداء خادم قاعدة البيانات. لذلك ، من الضروري أن يتم تكوين هذه الإعدادات وفقًا لخادم قاعدة البيانات وحجم العمل الخاص به. في هذا المنشور ، سنناقش بعض معلمات Linux kernel المهمة التي يمكن أن تؤثر على أداء خادم قاعدة البيانات وكيفية ضبطها.

شمكس / شمول

شمكس هي معلمة kernel تُستخدم لتحديد الحجم الأقصى لمقطع ذاكرة مشتركة واحدة يمكن لعملية Linux تخصيصها. قبل الإصدار 9.2 ، استخدمت PostgreSQL النظام الخامس (SysV) ، والذي يتطلب إعداد SHMMAX. بعد 9.2 ، تحولت PostgreSQL إلى ذاكرة POSIX المشتركة. لذا ، يلزم الآن عدد وحدات بايت أقل من الذاكرة المشتركة للنظام الخامس.

قبل الإصدار 9.3 ، كان SHMMAX أهم معلمة kernel. يتم إعطاء قيمة SHMMAX بالبايت.

وبالمثل، شمل هي معلمة kernel أخرى تستخدم لتحديد
إجمالي حجم نظام صفحات الذاكرة المشتركة. لعرض قيم SHMMAX أو SHMALL أو SHMMIN الحالية ، استخدم الأمر ipcs.

SHM * التفاصيل - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

SHM * التفاصيل - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

يستخدم PostgreSQL ملفات نظام V IPC لتخصيص ذاكرة مشتركة. يعد هذا الإعداد أحد أهم خيارات kernel. كلما تلقيت رسائل الخطأ التالية ، فهذا يعني أن لديك إصدارًا أقدم من PostgreSQL ولديك قيمة SHMMAX منخفضة جدًا. من المتوقع أن يقوم المستخدمون بضبط القيمة وزيادتها وفقًا للذاكرة المشتركة التي ينوون استخدامها.

أخطاء التكوين الخاطئة المحتملة

إذا تم تكوين SHMMAX بشكل غير صحيح ، فقد تحصل على خطأ عند محاولة تهيئة مجموعة PostgreSQL باستخدام الأمر initdb.

فشل initdb
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

وبالمثل ، قد تحصل على خطأ عند بدء تشغيل خادم PostgreSQL باستخدام الأمر pg_ctl.

فشل pg_ctl
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

فهم الاختلافات في التعريفات

يختلف تعريف خيارات SHMMAX / SHMALL قليلاً في Linux و MacOS X:

  • لينكس: kernel.shmmax ، kernel.shmall
  • نظام التشغيل MacOS X: kern.sysv.shmmax ، kern.sysv.shmall

فريق sysctl يمكن استخدامها لتغيير القيمة مؤقتًا. لتعيين قيم ثابتة ، قم بإضافة إدخال إلى /etc/sysctl.conf. التفاصيل أدناه.

تغيير خيارات Kernel على نظام MacOS X.

# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kern.sysv.shmall 
kern.sysv.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216

تغيير خيارات Kernel على Linux

# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216

لا تنسى: لإجراء تغييرات دائمة ، أضف هذه القيم إلى /etc/sysctl.conf

صفحات ضخمة

إعدادات Linux الافتراضية هي 4 كيلو بايت صفحات ، أما BSD الافتراضية فهي الصفحات الممتازة، وعلى نظام التشغيل Windows صفحات كبيرة. الصفحة هي جزء من ذاكرة الوصول العشوائي المخصصة لعملية. يمكن أن تحتوي العملية على صفحات متعددة حسب متطلبات الذاكرة. كلما زادت مساحة الذاكرة التي تحتاجها العملية ، زاد عدد الصفحات المخصصة لها. يحتفظ نظام التشغيل بجدول تخصيص الصفحات للعمليات. كلما كان حجم الصفحة أصغر ، زاد حجم الجدول ، كلما استغرق البحث عن صفحة في جدول الصفحات هذا وقتًا أطول. لذلك ، تسمح الصفحات الكبيرة باستخدام قدر كبير من الذاكرة مع تقليل الحمل ؛ عدد مشاهدات أقل للصفحة ، أخطاء أقل في الصفحات ، عمليات قراءة / كتابة أسرع من خلال مخازن مؤقتة أكبر. والنتيجة هي تحسين الأداء.

تدعم PostgreSQL الصفحات الكبيرة فقط على نظام Linux. بشكل افتراضي ، يستخدم Linux 4 كيلوبايت من صفحات الذاكرة ، لذلك في الحالات التي يوجد فيها عدد كبير جدًا من عمليات الذاكرة ، من الضروري تثبيت صفحات أكبر. هناك زيادة في الأداء عند استخدام صفحات كبيرة بحجم 2 ميجابايت وحتى 1 جيجابايت. يمكن ضبط حجم الصفحة الكبير في وقت التحميل. يمكنك بسهولة التحقق من خيارات الصفحات الكبيرة واستخدامها على جهاز Linux الخاص بك باستخدام الأمر cat / proc / meminfo | grep -i ضخم.

الحصول على معلومات حول الصفحات الكبيرة (Linux فقط)

Note: This is only for Linux, for other OS this operation is ignored$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

في هذا المثال ، على الرغم من ضبط حجم الصفحة الكبير على 2048 (2 ميجابايت) ، فإن العدد الإجمالي للصفحات الكبيرة هو 0. وهذا يعني أن الصفحات الكبيرة معطلة.

برنامج نصي لتحديد عدد الصفحات الكبيرة

يقوم هذا البرنامج النصي البسيط بإرجاع العدد المطلوب من الصفحات الكبيرة. قم بتشغيل البرنامج النصي على خادم Linux أثناء تشغيل PostgreSQL. تأكد من ضبط متغير البيئة على PGDATA دولار تم تحديد دليل بيانات PostgreSQL.

الحصول على عدد الصفحات الكبيرة المطلوبة

#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid:            $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak:            $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize:   $hps kB"
hp=$((peak/hps))
echo Set Huge Pages:     $hp

يبدو إخراج البرنامج النصي كما يلي:

إخراج البرنامج النصي

Pid:            12737
VmPeak:         180932 kB
Hugepagesize:   2048 kB
Set Huge Pages: 88

القيمة الموصى بها للصفحات الكبيرة هي 88 ، لذا يجب تعيينها على 88.

تركيب الصفحات الكبيرة

sysctl -w vm.nr_hugepages=88

تحقق من الصفحات الكبيرة الآن ، سترى أنه لم يتم استخدام صفحات كبيرة (HugePages_Free = HugePages_Total).

معلومات الصفحة الكبيرة مرة أخرى (Linux فقط)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       88
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

الآن قم بتعيين خيار huge_pages على "تشغيل" في $ PGDATA / postgresql.conf وأعد تشغيل الخادم.

معلومات الصفحة الكبيرة مرة أخرى (على Linux فقط)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       81
HugePages_Rsvd:       64
HugePages_Surp:        0
Hugepagesize:       2048 kB

الآن يمكنك أن ترى أنه يتم استخدام عدد قليل جدًا من الصفحات الكبيرة. دعنا الآن نحاول إضافة بعض البيانات إلى قاعدة البيانات.

بعض عمليات قاعدة البيانات لإعادة استخدام الصفحات الكبيرة

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

دعنا نرى ما إذا كنا نستخدم صفحات كبيرة الآن أكثر مما اعتدنا عليه.

مزيد من المعلومات حول الصفحات الكبيرة (Linux فقط)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       18
HugePages_Rsvd:        1
HugePages_Surp:        0
Hugepagesize:       2048 kB

الآن يمكنك أن ترى أن معظم الصفحات الكبيرة قيد الاستخدام.

ملاحظة: قيمة المثال لـ HugePages المستخدمة هنا منخفضة جدًا ، وهو أمر غير طبيعي لآلة الإنتاج. يرجى تقدير عدد الصفحات المطلوب لنظامك وتعيينها وفقًا للحمل والموارد.

vm.swappiness

vm.swappiness هو إعداد kernel آخر يمكن أن يؤثر على أداء قاعدة البيانات. يستخدم هذا الإعداد للتحكم في سلوك المبادلة (ترحيل الصفحات داخل وخارج الذاكرة) على Linux. تتراوح القيمة من 0 إلى 100. وهي تحدد مقدار الذاكرة التي سيتم ترحيلها أو تفريغها. صفر يعني عدم المشاركة ، و 100 يعني مشاركة قوية.

يمكنك الحصول على أداء جيد من خلال تحديد قيم أقل.

يمكن أن يؤدي تعيينه على 0 على نواة أحدث إلى قتل OOM Killer (عملية تنظيف ذاكرة Linux). لذلك من الآمن تعيين القيمة على 1 إذا كنت تريد تقليل الترحيل. القيمة الافتراضية في Linux هي 60. تؤدي القيمة الأعلى إلى استخدام MMU (وحدة إدارة الذاكرة) لمساحة مبادلة أكبر من ذاكرة الوصول العشوائي ، بينما تحتفظ القيمة الأقل بمزيد من البيانات / التعليمات البرمجية في الذاكرة.

تعتبر القيمة الأقل رهانًا جيدًا لتحسين الأداء في PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

تكتسب التطبيقات الذاكرة وتحررها عندما لا تكون هناك حاجة إليها. لكن في بعض الحالات ، يحصل التطبيق على الكثير من الذاكرة ولا يحررها. هذا قد يؤدي إلى قاتل OOM. فيما يلي قيم المعلمات الممكنة vm.overcommit_memory مع وصف لكل:

  1. الإفراط في الإرشاد (افتراضي) ؛ الكشف عن مجريات الأمور المستندة إلى النواة
  2. السماح بالإفراط في الالتزام على أي حال
  3. لا تفرط في ذلك ، لا تتجاوز نسبة الالتزام المفرط.

الرابط: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio - نسبة ذاكرة الوصول العشوائي المتاحة للتحميل الزائد. يمكن لقيمة 50 ٪ على نظام به ذاكرة وصول عشوائي سعتها 2 جيجابايت تخصيص ما يصل إلى 3 جيجابايت من ذاكرة الوصول العشوائي.

يوفر تعيين vm.overcommit_memory على 2 أفضل أداء لـ PostgreSQL. تعمل هذه القيمة على زيادة استخدام ذاكرة الوصول العشوائي (RAM) لعملية الخادم دون أي خطر كبير بالتعرض للقتل من خلال عملية OOM القاتلة. سيكون التطبيق قادرًا على إعادة التشغيل ، ولكن فقط في حدود التجاوز ، مما يقلل من خطر أن يقتل قاتل OOM العملية. لذلك ، تعطي القيمة 2 أداءً أفضل من القيمة الافتراضية 0. ومع ذلك ، يمكن تحسين الموثوقية من خلال ضمان عدم تحميل الذاكرة الموجودة خارج النطاق المسموح به بشكل زائد. هذا يزيل خطر العملية التي تم قتلها من قبل OOM- القاتل.

في الأنظمة التي لا تستخدم الترحيل ، قد تكون هناك مشكلة في ضبط vm.overcommit_memory على 2.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_ratio / vm.dirty_background_bytes

vm.dirty_background_ratio هي النسبة المئوية للذاكرة المليئة بالصفحات المتسخة التي يجب كتابتها على القرص. يتم التنظيف على القرص في الخلفية. تتراوح قيمة هذه المعلمة من 0 إلى 100 ؛ ومع ذلك ، قد لا تكون القيمة الأقل من 5 فعالة وبعض النوى لا تدعمها. 10 هي القيمة الافتراضية في معظم أنظمة Linux. يمكنك تحسين أداء عمليات الكتابة المكثفة بعامل أصغر ، مما يعني أن Linux سوف يقوم بمسح الصفحات المتسخة في الخلفية.

تحتاج إلى تحديد القيمة vm.dirty_background_bytes حسب سرعة القرص الخاص بك.

لا توجد قيم "جيدة" لهاتين المعلمتين ، حيث يعتمد كلاهما على الأجهزة. ومع ذلك ، فإن ضبط vm.dirty_background_ratio على 5 و vm.dirty_background_bytes على 25٪ من سرعة القرص يحسن الأداء بنسبة تصل إلى 25٪ تقريبًا في معظم الحالات.

vm.dirty_ratio/dirty_bytes

هذا هو نفس vm.dirty_background_ratio/dirty_background_bytes، باستثناء أن إعادة التعيين تتم في جلسة عمل ، مما يؤدي إلى حظر التطبيق. لذلك يجب أن تكون قيمة vm.dirty_ratio أعلى من vm.dirty_background_ratio. هذا يضمن أن عمليات الخلفية تبدأ في وقت مبكر لتجنب حظر التطبيق قدر الإمكان. يمكنك ضبط الفرق بين هاتين النسبتين بناءً على تحميل القرص I / O.

مجموع

يمكنك تعديل الإعدادات الأخرى لتحسين الأداء ، لكن التحسينات ستكون ضئيلة ولن تحصل على فائدة كبيرة. يجب أن نتذكر أنه لا تنطبق جميع الخيارات على جميع أنواع التطبيقات. تعمل بعض التطبيقات بشكل أفضل عندما نقوم بتعديل بعض الإعدادات والبعض الآخر لا يعمل. يجب أن تجد التوازن الصحيح بين تكوينات هذه الإعدادات لحمل العمل المتوقع ونوع التطبيق ، ويجب أن يؤخذ سلوك نظام التشغيل في الاعتبار عند التكوين. ضبط معلمات kernel ليس سهلاً مثل تكوين معلمات قاعدة البيانات: من الصعب تقديم توصيات هنا.

المصدر: www.habr.com

إضافة تعليق