क्यों नाम से फ़ाइलों को हटाने के दर्द को धीमा और असाधारण तेजी से भी है?


11

अशुद्ध पेस: "तेज" विधि जिसका मैं नीचे उल्लेख करता हूं, वह धीमी गति से 60 गुना तेज नहीं है। यह 30 गुना तेज है। मैं घंटे पर गलती को दोष दूँगा (3AM स्पष्ट सोच के लिए दिन का मेरा सबसे अच्छा समय नहीं है :) ।।

अद्यतन: मैंने परीक्षण समय का सारांश (नीचे) जोड़ा है।
गति कारक से जुड़े दो मुद्दे प्रतीत होते हैं:

  • उपयोग की गई कमांड का विकल्प (नीचे दिखाया गया समय तुलना)
  • एक निर्देशिका में बड़ी संख्या में फ़ाइलों की प्रकृति ... ऐसा लगता है कि "बड़ा बुरा है"। संख्या बढ़ने के साथ चीजें बहुत धीमी हो जाती हैं।

सभी परीक्षण 1 मिलियन फाइलों के साथ किए गए हैं।
(वास्तविक, उपयोगकर्ता और sys बार परीक्षण स्क्रिप्ट में हैं)
परीक्षण स्क्रिप्ट paste.ubuntu.com पर देखे जा सकते हैं

#
# 1 million files           
# ===============
#
#  |time   |new dir   |Files added in  ASCENDING order  
#  +----   +-------   +------------------------------------------------- 
#   real    01m 33s    Add files only (ASCENDING order) ...just for ref.
#   real    02m 04s    Add files, and make 'rm' source (ASCENDING order) 
#                      Add files, and make 'rm' source (DESCENDING order) 
#   real    00m 01s    Count of filenames
#   real    00m 01s    List of filenames, one per line
#   ----    -------    ------
#   real    01m 34s    'rm -rf dir'
#   real    01m 33s    'rm filename' via rm1000filesPerCall   (1000 files per 'rm' call)
#   real    01m 40s    'rm filename' via  ASCENDING algorithm (1000 files per 'rm' call)
#   real    01m 46s    'rm filename' via DESCENDING algorithm (1000 files per 'rm' call)
#   real    21m 14s    'rm -r dir'
#   real    21m 27s    'find  dir -name "hello*" -print0 | xargs -0 -n 1000 rm'
#   real    21m 56s    'find  dir -name "hello*" -delete'
#   real    23m 09s    'find  dir -name "hello*" -print0 | xargs -0 -P 0 rm'
#   real    39m 44s    'rm filename' (one file per rm call) ASCENDING
#   real    47m 26s    'rm filename' (one file per rm call) UNSORTED
#                                                       

मैंने हाल ही में 10 मिलियन खाली परीक्षण फ़ाइलों को बनाया और हटा दिया है । नाम के आधार (नाम rm filename) के आधार पर फ़ाइलों को हटाना , मुझे यह पता चला है कि 2 अलग-अलग तरीकों के बीच बहुत बड़ा समय अंतर है ...

दोनों विधियाँ सटीक समान rm filenameकमांड का उपयोग करती हैं ।

अपडेट: जैसा कि यह पता चला है, कमांड बिल्कुल समान नहीं थे ... उनमें से एक एक समय में 1000 फ़ाइलनामों को 'आरएम' भेज रहा था ... यह एक शेल ब्रेस-एक्सपेंशन मुद्दा था जहां मुझे लगा कि प्रत्येक फ़ाइल नाम लिखा जा रहा है फीडर फ़ाइल की अपनी लाइन पर, लेकिन वास्तव में यह 1000 प्रति लाइन थी

Filnames एक में एक 'फीडर फ़ाइल' के माध्यम से प्रदान कर रहे हैं while readपाश ..
फीडर फ़ाइल का आउटपुट है ls -1 -f
तरीकों सभी reaspects में समान हैं, एक बात को छोड़कर:

  • धीमी गति से विधि से प्रत्यक्ष अवर्गीकृत फीडर फ़ाइल का उपयोग करता हैls -1 -f
  • तेजी से विधि है कि एक ही अवर्गीकृत फ़ाइल की एक क्रमबद्ध संस्करण का उपयोग करता

मुझे यकीन नहीं है कि क्या छांटना ths मुद्दा है, या यह है कि शायद हल किया हुआ फीडर फ़ाइल सिर्फ उस अनुक्रम से मेल खाने के लिए होता है जिसमें फाइलें बनाई गई थीं (मैंने एक सरल आरोही पूर्णांक एल्गोरिदम का उपयोग किया था)

1 मिलियन फ़ाइलों के लिए, फास्ट rm filename विधि धीमी विधि की तुलना में 60 गुना तेज है ... फिर से, मुझे नहीं पता कि क्या यह "छँटाई" मुद्दा है, या एक पीछे-हैश टेबल इश्यू ... मुझे संदेह है यह एक साधारण छंटनी का मुद्दा नहीं है, क्योंकि जानबूझकर मुझे फ़िल्मी नामों के एक नए सिरे से जोड़े गए "क्रमबद्ध" अनुक्रम की एक अंतहीन सूची दी जाएगी ... ls -1 -f

मैं सोच रहा हूँ कि यहाँ क्या हो रहा है, इसलिए अगली 10 मिलियन फ़ाइलों को हटाने के लिए मुझे दिन (हाँ दिन) नहीं लगते हैं :) .... मैं कहता हूँ "दिन" क्योंकि मैंने बहुत सारे विकल्पों की कोशिश की, और कई बार शामिल नंबर फ़ाइल में असमानता बढ़ जाती है .. इसलिए मैंने केवल 1 मिलियन का विस्तार से परीक्षण किया है

बीटीडब्ल्यू: नामों की "सॉर्ट की गई सूची" के माध्यम से फ़ाइलों को हटाना वास्तव rm -rfमें 2 के कारक से तेज है
और: rm -r"सॉर्ट की गई सूची" विधि की तुलना में 30 गुना धीमा था।

... लेकिन यहाँ "" हल किया गया है? या यह हैशिंग (या जो कुछ भी) ext4 द्वारा उपयोग की जाने वाली विधि से संबंधित है?

जो चीज मुझे काफी अचंभित करती है, वह यह है कि प्रत्येक कॉल rm filenameपिछले एक से संबंधित नहीं है .. (ठीक है, कम से कम यह 'बैश' के नजरिए से ऐसा है)

मैं Ubuntu / bash / 'ext4' / SATA II ड्राइव का उपयोग कर रहा हूं।


1
आप यह गलत कर रहे है! (tm) कभी सुना है find -delete?
एलेक्स

आपके 2 परीक्षण असमान स्थितियों में शुरू होते हैं (मैं यह दिखावा नहीं करता कि वास्तव में यह महत्वपूर्ण है): एक फ़ाइल से फ़ाइलनाम पढ़ता है, और दूसरा एक फ़ाइल से फ़ाइल नाम पढ़ता है जो परीक्षण से तुरंत पहले बनाया (सॉर्ट किया गया) है। यह हो सकता है कि 2 के मामले में कैश की जा रही फ़ाइल कुछ (या शायद नहीं, कौन जानता है) खेलता है। परीक्षणों के लिए और अधिक समान परिस्थितियों में होना चाहिए, शायद आपको cat1 टेस्ट से पहले एक ताजा फ़ाइल के लिए एक सरल करना चाहिए - sort2 वें परीक्षण से पहले।
इम्ज़ - इवान ज़खरीशेव

और मैं आपको अपनी टिप्पणियों और आपके प्रश्न को अधिक स्पष्ट तरीके से प्रस्तुत करने की सलाह देता हूं। कृपया, एक समय में एक बात: एक प्रश्न में सिर्फ 2 मामलों की तुलना करें, दो महत्वपूर्ण मामलों को फोरग्राउंड में लाएं, बाकी सभी पृष्ठभूमि की जानकारी हैं; कृपया इसे स्पष्ट करें। कृपया एक पोस्टिंग में कई टिप्पणियों का मिश्रण न करें।
इम्ज़ - इवान ज़खरीशेव

पेश प्रणाली और उपयोगकर्ता के अंतरिक्ष समय अपने पराक्रम से भी पहेली को सुलझाने के लिए महत्वपूर्ण हो, इसलिए उन्हें अपने प्रश्न में शामिल करें। उनमें से कौन सा आपके परीक्षणों में बड़ा बदलाव करता है?
इम्ज़ - इवान ज़खरीशेव

1
सभी बुराईयो की जड़ समयपूर्व इष्टतमीकरण है। :) आप कभी भी 10 मिलियन फ़ाइलों को कब हटाएंगे? 100 000 प्रति सेकंड मुझे काफी तेज लगता है (आपके सिस्टम को बर्बाद करने के लिए)।
उपयोगकर्ता अज्ञात

जवाबों:


2

rm -r को इसके पुनरावर्ती के रूप में धीमा होने की उम्मीद है। डायरेक्टरी स्ट्रक्चर पर एक गहरा पहला ट्रैवर्सल बनाया जाना है।

अब आपने 10 मिलियन फाइलें कैसे बनाईं? क्या आपने कुछ स्क्रिप्ट का उपयोग किया है जो कुछ ऑर्डर पर लूप करता है? 1.txt, 2.txt, 3.txt ... यदि हाँ, तो उन फ़ाइलों को भी उसी क्रम में hdd.so में सन्निहित ब्लॉकों में आवंटित किया जा सकता है।

"ls -f" -aU को सक्षम करेगा जो निर्देशिका क्रम में सूचीबद्ध करता है जो फिर से पुनरावर्ती है।


1
McAlot: मैं यह नहीं देख सकता कि इस मामले में 'पुनरावर्ती' कैसे मायने रखता है , क्योंकि इसमें कोई उप-निर्देशिका शामिल नहीं है ... हाँ मैंने "1.txt, 2.txt, 3.txt 'का उपयोग किया है। शायद कई हैं। बातचीत करना: उदाहरण के लिए, 1 मिलियन फ़ाइलों को बनाने में केवल 1min 30s क्यों लगता है, लेकिन 2 मिलियन बनाने के लिए 7m 10s लगते हैं और उन्हें हटाने के बाद, 1 मिलियन को पुनः प्राप्त करने में अधिक समय लगता है (9m 30s) इसकी अजीब; धीरे-धीरे अचानक। यह पहले भी खुश है। मुझे लगता है कि (?) निर्देशिका को हटाने के लिए इसे ठीक कर दिया गया है। क्या कोई फ़ाइल डेमॉन शामिल है (नॉटिलस; पता लगाएं) हो सकता है? जारी रखा जा सके ...
पीटर

सामान्य तौर पर, एक ही निर्देशिका में बड़ी संख्या में फ़ाइलों से निपटने के लिए फाइल सिस्टम को अनुकूलित नहीं किया जाता है। मैं विशेष रूप से ext4 से परिचित नहीं हूं, लेकिन अन्य प्रारूपों के लिए निर्देशिका प्रविष्टियों को अप्रयुक्त के रूप में चिह्नित किया गया था जब फाइलें हटा दी गई थीं। इसका मतलब है कि निर्देशिका में संचालन करते समय उन्हें अभी भी छोड़ दिया जाना चाहिए। यह उस व्यवहार की व्याख्या करेगा जो आप देख रहे हैं।
कीथबी

1
मैंने 'अब धीमी' निर्देशिका को हटा दिया, और एक नई निर्देशिका के लिए एक अलग नाम का उपयोग किया। 1 मिलियन फ़ाइलों को बनाने का समय अब ​​1m 33s (बनाम 9 मी 30 के दशक में वापस हो जाता है) जब निर्देशिका में "2 मिलियन हटाई गई फ़ाइलें होती हैं, पहले मिलियन में नए नाम के साथ 1 मिलियन का नाम होता है) ... दिलचस्प, और यह अपने "... बस अप्रयुक्त" टिप्पणी के रूप में चिह्नित ... वहाँ हो रही है; यह समझ में आने लगा है :)
Peter.O

@ fred.bear मेरा बुरा, मैं वास्तव में वास्तविक पदानुक्रम नहीं जानता था और मेरा जवाब अनुमान था। साथ ही आपका परीक्षण वास्तव में मेटाडेटा पर जोर देता है, लेकिन वास्तविक फ़ाइलों पर नहीं क्योंकि वे खाली फाइलें हैं। इस तरह के मुद्दे को बेंचमार्क करने का सबसे अच्छा तरीका वेब सर्वर के / var या कैश से फाइलें लेना है। वैसे भी आपका परीक्षण बहुत ही अटपटा लगता है, क्या आप अलग-अलग निर्देशिकाओं में दो सूचीबद्ध तरीकों से हटाने की कोशिश कर सकते हैं..जैसे /sample1/1.txt,2.txt ... और /sample2/1.txt,2.txt ..
rajaganesh87

@ Mr.Confused.A.Lot ... आपकी मदद के लिए धन्यवाद। आपके स्पष्टीकरण ने मुझे फाइलसिस्टम और इसके कुछ तरीकों के बारे में और अधिक समझने में मदद की ... मुझे अब एक उचित समझ मिली है कि अलग-अलग गति के मुद्दों का कारण क्या था ... कुछ बस बैश कमांड का विकल्प थे, और अन्य बस फाइल सिस्टम के मुद्दे थे ( मैं एक नए आदर्श वाक्य के साथ छोड़ दिया गया हूं: निर्देशिकाओं के लिए "बड़ा बुरा है" ... (कुछ कार्यों के लिए, कम से कम) ...
पीटरओ।

2

आपको फिलास्ट्रक्चर का अनुकूलन करना चाहिए। इसलिए इसके बजाय

for i in $(seq 1 1000); do touch file.$i; done

कुछ होशियार की तरह (bash मान लिया):

function bucklocate() 
{ 
    hash=$(echo -n "$1"|md5sum|cut -f1); 
    echo -n "${hash:1:1}/${hash:7:1}/${hash:9:2}/$1"; 
}

hexdig="{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f}"
eval mkdir -p $hexdig/$hexdig/$hexdig$hexdig


for i in $(seq 1 1000); do touch $(bucklocate file.$i); done

अब यह उदाहरण md5sum [1] के उपयोग के कारण धीमा है, बहुत तेजी से प्रतिक्रिया के लिए निम्नलिखित की तरह कुछ का उपयोग करें, जब तक आपको किसी विशेष फ़ाइल नाम की आवश्यकता नहीं है, डुप्लिकेट को कोई चिंता नहीं है और इसके लिए कोई आवश्यकता नहीं है एक निश्चित नाम का दोहराव वाला हैश :)

mkdir -pv {0,1,2,3,4,5,6}/{0,1,2,3,4,5,6,7,8,9,10,12}
for  a in $(seq 1 100); do i=$RANDOM; echo touch "$(($i%7))/$(($i%13))/file.$i"; done

बेशक यह सभी हैशटैब से अवधारणाओं को धीरे-धीरे उधार लेना है


मुझे लगता है कि आप कह रहे हैं "छोटी निर्देशिकाओं का उपयोग करें" ... यह एक अंतर विचार है; एक घर में विकसित DBMS जो 'ट्री-लेस' ग्रुप ऑफ फाइल्स से एक ट्री बनाता है। कुछ इसे आगे की प्लानिंग कह सकते हैं :) ... अगर यह काम करता है (और यह शायद करता है), तो यह एक अच्छा विचार है ! :) ... मैं यह विचार करना शुरू कर रहा हूं कि 'बड़ा खराब है' wnen यह एक निर्देशिका में फ़ाइलों की संख्या (ext4 कम से कम) के लिए आता है ... आपने एक प्रीमेक्टिव वर्कअराउंड (+1) और I 'प्रस्तुत किया है मी धीरे-धीरे इस बात का अंदाजा लगा रहा है कि किसी भी निर्देशिका में कुछ हटाने की विधियाँ दूसरों की तुलना में तेज़ क्यों हैं? छोटा या बड़ा ... धन्यवाद
पीटर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.