استخدام ذاكرة البناء في Ember-cli يخاطر بالفشل (OOM) على الحد الأدنى لحجم المثيل

أثناء الترقية، كان أكبر ضغط على الذاكرة (RAM + swap) هو عندما تعمل عملية ‘ember’. أعتقد أن كل مرة أقوم فيها بتحديث، يكون أكبر من ذي قبل، وهو يقترب من عدم القدرة على العمل على أجهزة ذات الحد الأدنى الموصى به.

قد يكون من الجيد النظر في هذا قبل أن يفشل بالفعل. (نأمل، لأسباب تتعلق بالتكلفة، أن لا يكون الحل هو زيادة الحد الأدنى الموصى به. زيادة مساحة التبديل (swap) ستساعد، إذا سمحت مساحة القرص بذلك. من حيث المبدأ، يمكن للمرء مؤقتًا الانتقال إلى مثيل أكبر ذاكرة وصول عشوائي (RAM) وأكثر تكلفة.)

أقوم بتشغيل منتديين متوسطي الحجم على مثيلات صغيرة - كلاهما ضمن الحد الأدنى الموصى به، على ما أعتقد. في كلتا الحالتين، ذاكرة الوصول العشوائي + مساحة التبديل = 3 جيجابايت. في إحدى الحالات، مثيل Digital Ocean بذاكرة وصول عشوائي (RAM) 1 جيجابايت ومساحة تبديل (swap) 2 جيجابايت، وفي الحالة الأخرى، مثيل Hetzner بذاكرة وصول عشوائي (RAM) 2 جيجابايت ومساحة تبديل (swap) 1 جيجابايت.

إليك ثلاث لقطات لعملية ember، على جهاز DO، باستخدام ps auxc

USER       PID %CPU %MEM      VSZ    RSS TTY   STAT START   TIME COMMAND
1000     10342 87.7 65.1 32930460 657936 ?     Rl   16:57   2:23 ember

USER       PID %CPU %MEM      VSZ    RSS TTY   STAT START   TIME COMMAND
1000     10342 84.9 60.7 43572204 612668 ?     Rl   16:57   2:57 ember

USER       PID %CPU %MEM      VSZ    RSS TTY   STAT START   TIME COMMAND
1000     10342 81.2 55.2 43405220 557128 ?     Rl   16:57   3:40 ember

من الواضح أن حجم العملية البالغ 43 جيجابايت ليس كله موجودًا في الذاكرة الافتراضية حيث لدينا 3 جيجابايت فقط متاحة. استخدام 65٪ من حجم ذاكرة الوصول العشوائي (RAM) لـ RSS مثير للإعجاب، ولكنه ليس مشكلة بحد ذاته. كمية الذاكرة الحرة ومساحة التبديل الحرة تظهر أن الجهاز قريب من حالة نفاد الذاكرة (OOM)، مما سيؤدي على الأرجح إلى إنهاء بعض العمليات وانتهاء غير مرتب للترقية.

إليك free كلقطة في نقطة زمنية:

# free
              total        used        free      shared  buff/cache   available
Mem:        1009140      863552       72768        6224       72820       34868
Swap:       2097144     1160628      936516

لمحاولة التقاط الوضع الأقرب إلى الفشل، استخدمت vmstat 5

# vmstat 5 5
procs -----------memory----------    ---swap-- -----io----  -system-- ------cpu-----\
 r  b   swpd    free   buff  cache    si    so    bi    bo   in    cs us sy id wa st\
 3  0 1392140  61200  11632  76432    41    32   117    93    0     1  2  1 97  0  0\
 1  1 1467220  63416    324  67284  8786 20499 13178 20567 2539  8924 77 13  0 10  0\
 0  2 1593340  57916   1096  53832 24262 46868 29986 46889 5377 18534 44 22  0 34  0\
 4  0 1155632 120680   2772  86280 39111 35424 54768 37824 6987 25174 38 27  0 35  0\
 3  0 1102988  74096   2852  85276 11261   246 12610   271 1879  6365 86  6  0  8  0\

ستلاحظ الكثير من تبديلات السياق (cs) والكثير من نشاط القرص (bi، bo) والكثير من نشاط التبديل (si، so)، ولكن أهم شيء هو استخدام التبديل حتى 1.6 جيجابايت مع انخفاض الذاكرة الحرة إلى 60 ميجابايت و 54 ميجابايت فقط من استخدام المخزن المؤقت. هذا يعني أن حوالي 2.6 جيجابايت من الـ 3 جيجابايت المتاحة من الذاكرة الافتراضية قيد الاستخدام. هذا 87٪ من السعة. (قد يكون أسوأ قليلاً، حيث أننا نأخذ عينات كل 5 ثوانٍ.)

لاحظ أن الوضع كان مقلقًا (حوالي 2 جيجابايت مستخدمة، لذا لم يكن قريبًا من الأزمة كما هو اليوم) عندما قمت بالتحديث في أغسطس:

# vmstat 5 5
procs -----------memory----------    ---swap-- -----io----  -system-- ------cpu-----\
 r  b    swpd   free   buff  cache    si    so    bi    bo   in    cs us sy id wa st\
 3  0  700404  62740   1956  48748    35    29   108    92    3     8  2  1 96  0  1\
 1  0  741000  65996   1880  44360  3708 11190  3982 11191  643  1437 92  4  0  3  1\
 1  0  834836  70452   1480  53856   528 18969  4274 18974  532  1575 93  6  0  1  0\
 4  1 1010144  82192   4644  44400 30065 38803 35455 39946 4432 19267 28 26  0 39  7\
 1  0  644116 307764   1644  55348 24406 21154 27724 21945 2551  8672 52 22  0 21  6\
4 إعجابات

مرحباً @Ed_S - ما هو إصدار Discourse الذي كنت تستخدمه لهذه الاختبارات؟ نقوم بتحديث ember-cli والإضافات الخاصة به بانتظام، لذا أريد فقط التأكد من أننا ننظر إلى نفس الشيء.

أيضًا، كم عدد نوى وحدة المعالجة المركزية التي تحتوي عليها أجهزتك الافتراضية؟ 1؟ (يمكنك التحقق عن طريق تشغيل lscpu في الطرفية)

حتى نعمل جميعًا بنفس البيانات، هل يمكنك محاولة تشغيل:

/var/discourse/launcher enter app
cd /var/www/discourse/app/assets/javascripts/discourse
apt-get update && apt-get install time
NODE_OPTIONS='--max-old-space-size=2048' /usr/bin/time -v yarn ember build -prod

على قطرة الاختبار الخاصة بي (1 وحدة معالجة مركزية، 1 جيجابايت من ذاكرة الوصول العشوائي، 2 جيجابايت من التبديل)، أرى هذا:

Command being timed: "yarn ember build -prod"
	User time (seconds): 369.74
	System time (seconds): 22.62
	Percent of CPU this job got: 81%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 8:02.73
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 774912
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 253770
	Minor (reclaiming a frame) page faults: 1158920
	Voluntary context switches: 519269
	Involuntary context switches: 383328
	Swaps: 0
	File system inputs: 7521784
	File system outputs: 316304
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0

نحن نستخدم أدوات ember قياسية جدًا هنا، لذا لست متأكدًا من وجود الكثير الذي يمكننا فعله من حيث التكوين لتقليل استخدام الذاكرة. هدفنا طويل الأجل هو الانتقال إلى استخدام Embroider، والذي قد يمنحنا المزيد من الخيارات.

إعجاب واحد (1)

شكراً @david - أقدر أن Ember كيان قائم بذاته.

لقد قمت للتو بتنفيذ تلك الأوامر.

# /var/discourse/launcher enter app
تم اكتشاف بنية x86_64.

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

2.0.20220720-0049: سحب من discourse/base
Digest: sha256:7ff397003c78b64c9131726756014710e2e67568fbc88daad846d2b368a02364
الحالة: تم تنزيل صورة أحدث لـ discourse/base:2.0.20220720-0049
docker.io/discourse/base:2.0.20220720-0049

هذا تثبيت إنتاجي، لذلك، اعتبارًا من الأمس، كان محدثًا. حاليًا يبلغ:

مثبت 2.9.0.beta12 (8f5936871c)

إنها نسخة بمعالج واحد، مثل نسختك، تحتوي على 1 جيجابايت من ذاكرة الوصول العشوائي و 2 جيجابايت من مساحة المبادلة.

كانت نتيجة الأمر time هي

تم الانتهاء في 303.21 ثانية.

الأمر الذي يتم توقيته: "yarn ember build -prod"
وقت المستخدم (بالثواني): 222.71
وقت النظام (بالثواني): 17.17
نسبة وحدة المعالجة المركزية التي حصلت عليها هذه المهمة: 78٪
الوقت المنقضي (الساعة العادية) (س:د:ث أو د:ث): 5:04.15
متوسط حجم النص المشترك (كيلوبايت): 0
متوسط حجم البيانات غير المشتركة (كيلوبايت): 0
متوسط حجم المكدس (كيلوبايت): 0
متوسط الحجم الإجمالي (كيلوبايت): 0
أقصى حجم مقيم (كيلوبايت): 702292
متوسط حجم مقيم (كيلوبايت): 0
أخطاء الصفحة الرئيسية (تتطلب إدخال/إخراج): 348190
أخطاء الصفحة الثانوية (استعادة إطار): 1152689
تبديلات السياق الطوعية: 617736
تبديلات السياق اللاإرادية: 774189
المبادلات: 0
مدخلات نظام الملفات: 5001936
مخرجات نظام الملفات: 318280
رسائل المقبس المرسلة: 0
رسائل المقبس المستلمة: 0
الإشارات المسلمة: 0
حجم الصفحة (بايت): 4096
حالة الخروج: 0

مباشرة قبل ذلك، كنت قد قمت بتحديث المضيف وأعدت التشغيل، لذلك كان كل شيء في الحاوية قد تمت إعادة تشغيله حديثًا.

أسوأ استخدام للذاكرة كما هو مبلغ عنه بواسطة vmstat يعمل في نافذة أخرى:

# vmstat 1
r  b    swpd   free   buff  cache    si     so    bi     bo    in    cs us sy id wa st
 2  0  704000 136044  24136 158144  1517   3503  8256   4377   886  3564 43  8 43  6  0
...
 5  0 1451436  71604   1248  50196 55016 110236 73204 121060 13152 45971 29 60  0 10  1
إعجابَين (2)

يبدو أننا قمنا بزيادة ذاكرة الكومة المسموح بها لـ Node بشكل صريح من 500 ميجابايت إلى 2 جيجابايت - ربما تكون هذه خطوة مفرطة، وربما يكون 1.5 جيجابايت أفضل:

تجدر الإشارة إلى أن Ember ليست الشيء الوحيد الذي يعمل على الجهاز، ونحن نواجه الحد العالمي للذاكرة العشوائية + الذاكرة الافتراضية. لذلك، يأخذ تاريخ الجهاز واحتياجات جميع العمليات الأخرى قيد التشغيل في الاعتبار. قد يكون إعادة التشغيل الخاصة بي قد ساعدت هنا في الوصول إلى علامة مرتفعة أقل مقارنة بالأمس.

تمت الإشارة إلى طلب السحب أعلاه في
فشل ترقية مثيل Discourse إلى 15 فبراير 2022
حيث لاحظنا أيضًا أن شخصًا ما كان يعاني من نقص في الذاكرة تم حله عن طريق إعادة التشغيل.

من المؤسف أن الأمر time لا يبلغ عن ذروة استخدام الذاكرة. ربما، على جهاز يحتوي على 3 جيجابايت على الأقل من الذاكرة العشوائية ولا توجد ذاكرة افتراضية، فإن عدد RSS سيخبرنا بذروة استخدام Ember. أو ربما يمكننا استخدام تكتيك آخر - تم تحديد العديد منها هنا وهناك بعض الأفكار هنا أيضًا.

ما هو المربك هو أننا مهتمون حقًا باستخدام الذاكرة هنا، بينما في العديد من الحالات يكون الناس مهتمين باستخدام الذاكرة العشوائية، وهو سؤال مختلف.

3 إعجابات

السبب في أننا أضفنا هذا العلم هو أن قاتل نفاد الذاكرة (OOM killer) الخاص بـ Node كان يقتل البناء - 500 ميجابايت لم تكن كافية. يسعدني أن أجرب تعديله إلى 1.5 جيجابايت - لقد جربته للتو على القطرة الخاصة بي ويبدو أنه يعمل بشكل جيد. في الواقع، يبدو أن 1.0 جيجابايت كافية.

لقد حاولت تتبع استخدام الذاكرة بأحجام ذاكرة قصوى مختلفة:

(while(true); do (free -m -t | grep Total | awk '{print $3}') && sleep 0.5; done) | tee 1000mb.csv

يعرض هذا الاستخدام أثناء البناء:

كان هناك فرق ضئيل جدًا في وقت البناء، ولكن حدود 1 جيجابايت و 1.5 جيجابايت تنتج بوضوح استخدامًا إجماليًا أقل. كما هو متوقع، يُظهر خرج time عددًا أقل بكثير من “الأخطاء الرئيسية في الصفحات” عندما يكون حد Node أقل.

من الغريب أن الفرق بين 1.5 جيجابايت و 1 جيجابايت صغير جدًا… :face_with_monocle:

على أي حال، أتفق على أن تقليل الحد هو فكرة جيدة. للتأكد من أنه لا يؤثر على أداء البناء على الأجهزة ذات المواصفات الأعلى، أعتقد أنه يجب علينا تجاوز الحد فقط عندما نعرف أنه منخفض جدًا. بخلاف ذلك، يمكننا السماح لـ Node باستخدام الإعداد الافتراضي الخاص به.

إليك طلب سحب (PR) - سنحاول دمجه قريبًا. شكرًا لك على طرح هذا @Ed_S!

4 إعجابات

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.