समस्या का अवलोकन #
घटित घटना:
- बड़ी संख्या में नॉलेज दस्तावेज़ों को इंडेक्स करने पर, प्लगइन डेमॉन (plugin_daemon) असंख्य थ्रेड्स बनाता रहता है और अंततः “लगभग 30,000” पर नए थ्रेड नहीं बन पाते।
- कंटेनर लॉग में
can't start new threadएरर आती है और सेवा फ़्रीज़ हो जाती है।
अनुमानित कारण:
- कंटेनर/cgroup v2 का pids.max (प्रोसेस+थ्रेड अपर लिमिट) 29958 (लगभग 30,000) पर सेट है, और इससे अधिक होने पर थ्रेड निर्माण विफल हो जाता है।
- प्लगइन डेमॉन साइड में थ्रेड लीक, या बड़े पैमाने पर समवर्ती प्रोसेसिंग के कारण कम समय में थ्रेड संख्या बढ़ती है।
परीक्षण और त्रुटि:
- Docker Compose या कंटेनर के भीतर pids_limit: 0 या ulimit को समायोजित करने पर भी, होस्ट का cgroup 29958 पर फिक्स्ड होने के कारण प्रभाव नहीं पड़ा।
/sys/fs/cgroup/system.slice/docker-के वास्तविक मान की पुष्टि करने पर यह 29958 था।.scope/pids.max
मूल समाधान #
- प्लगइन डेमॉन साइड में थ्रेड लीक को ठीक करना (अपडेट या पैच लागू करना)।
- एक बार में प्रोसेस किए जाने वाले दस्तावेज़ों की संख्या को विभाजित करना, ताकि थ्रेड बहुत अधिक न बढ़ें।
अस्थायी वर्कअराउंड #
- होस्ट की cgroup सेटिंग को बदलना और pids.max को max (असीमित) या बड़े मान में बढ़ाना।
- साथ ही systemd की slice यूनिट (system.slice आदि) में TasksMax=infinity सेट करना ताकि रीस्टार्ट के बाद भी यह वापस न लौटे।
वर्कअराउंड प्रक्रिया (चरण-दर-चरण) #
STEP 1. कंटेनर की “होस्ट साइड PID” से cgroup पथ की पहचान #
कंटेनर ID की पुष्टि करें:
docker ps
प्लगइन डेमॉन 998eb0c50703 जैसी ID है।
docker top <कंटेनर ID> से, होस्ट पर PID प्राप्त करें:
docker top 998eb0c50703
उदाहरण: /app/main प्रोसेस 1012512 (होस्ट PID) आदि है।
/proc/<होस्ट PID>/cgroup देखें:
cat /proc/1012512/cgroup
आउटपुट उदाहरण: 0::/system.slice/docker-998eb0c5070321...scope
STEP 2. वास्तविक अपर लिमिट (pids.max) को बदलें #
संबंधित डायरेक्टरी में जाएं और pids.max की पुष्टि करें:
cd /sys/fs/cgroup/system.slice/docker-998eb0c5070321...scope
cat pids.max
यदि मान 29958 जैसी संख्या है तो प्रतिबंध है, max होने पर असीमित है।
असीमित में बदलें:
echo max | sudo tee pids.max
इससे “उस समय” प्रतिबंध हट जाता है, लेकिन रीस्टार्ट या कंटेनर पुनर्निर्माण पर वापस लौटने की संभावना अधिक है।
STEP 3. systemd की सेटिंग से TasksMax को स्थायी रूप से असीमित करें #
cgroup की सेटिंग रीसेट न हो, इसके लिए systemd की slice यूनिट (system.slice) में TasksMax को ओवरराइड करें:
3-1. ओवरराइड फ़ाइल बनाएं: #
sudo systemctl edit --force --full system.slice
एडिटर खुलने पर, निम्नानुसार [Slice] सेक्शन जोड़ें और सेव करें:
[Slice]
TasksMax=infinity
3-2. डेमॉन रीलोड और रीस्टार्ट: #
sudo systemctl daemon-reload
sudo systemctl restart docker
docker-compose उपयोग करने पर, एक बार docker-compose down && docker-compose up -d आदि से कंटेनर को रीस्टार्ट करें।
नए कंटेनर बनते समय, TasksMax=infinity लागू होगा।
3-3. प्रतिबिंब की पुष्टि: #
systemctl show system.slice -p TasksMax
# => TasksMax=infinity होने पर OK
cat /sys/fs/cgroup/system.slice/pids.max
# => max होने पर OK
इसके अलावा कंटेनर चालू होने पर पुनः “STEP 1~2” की विधि से /sys/fs/cgroup/system.slice/docker- की जांच करें, और max है या नहीं देखें।
STEP 4. (आवश्यकतानुसार) कर्नेल पैरामीटर आदि की जांच #
कर्नेल की थ्रेड/PID अपर लिमिट:
sysctl kernel.threads-max
sysctl kernel.pid_max
यदि छोटा मान (30,000~60,000 के आसपास) है, तो इसे और बढ़ाने की आवश्यकता है।
sudo sysctl -w kernel.threads-max=200000
स्थायी बनाने के लिए /etc/sysctl.conf में kernel.threads-max=200000 आदि जोड़ें।
systemd संपूर्ण की डिफ़ॉल्ट TasksMax:
cat /etc/systemd/system.conf
यदि /etc/systemd/system.conf में DefaultTasksMax=65535 जैसा विवरण है, तो सभी सेवाओं पर लागू हो सकता है।
इसे infinity में बदलकर रीस्टार्ट करने पर अधिक निश्चित रूप से काम करता है।
सारांश #
- समस्या का कारण: cgroup v2 का pids.max लगभग 30000 पर फिक्स्ड है, और प्लगइन डेमॉन बड़ी संख्या में थ्रेड बनाता है जिससे लिमिट तक पहुंच जाता है।
- वर्कअराउंड:
/sys/fs/cgroup/system.slice/docker-को max में बदलकर प्रतिबंध को ढीला करें। इसके अलावा systemd slice में TasksMax=infinity सेट करें ताकि रीस्टार्ट पर भी वापस न लौटे।.scope/pids.max - पूरक: थ्रेड संख्या असामान्य रूप से बढ़ने का मूल कारण (ऐप का थ्रेड लीक) ठीक न करने पर, अंततः मेमोरी की कमी जैसी अन्य समस्याएं हो सकती हैं। यदि संभव हो तो सॉफ़्टवेयर अपडेट या बैच विभाजित प्रोसेसिंग आदि से मूल उपचार करें।
उपरोक्त चरणों से “लगभग 29958 की अपर लिमिट तक पहुंचकर फ़्रीज़ होने की समस्या” से बचा जा सकता है।