डिस्क / डिस्क कॉपी धीमी करें


28

क्या लिनक्स पर कॉपी प्रक्रिया को धीमा करने का एक तरीका है?

मेरे पास एक बड़ी फ़ाइल है, 10GB का कहना है, और मैं इसे दूसरी निर्देशिका में कॉपी करना चाहूंगा, लेकिन मैं इसे पूरी गति के साथ कॉपी नहीं करना चाहता। मान लीजिए कि मैं इसे 1mb / s की गति के साथ कॉपी करना चाहता हूं, तेज नहीं। मैं एक मानक लिनक्स cpकमांड का उपयोग करना चाहता हूं ।

क्या यह संभव है? (यदि हाँ, तो कैसे?)

संपादित करें : इसलिए, मैं जो भी हासिल करने की कोशिश कर रहा हूं, उसमें अधिक संदर्भ जोड़ूंगा।

USB पर बड़ी फ़ाइलों (एक पेनड्राइव, USB डिस्क, आदि) की नकल करते समय मुझे ArchLinux सिस्टम पर समस्या होती है। यूएसबी बफर कैश भरने के बाद, मेरा सिस्टम प्रतिक्रिया देना बंद कर देता है (यहां तक ​​कि माउस भी बंद हो जाता है; यह केवल छिटपुट रूप से चलता है)। प्रतिलिपि कार्रवाई अभी भी जारी है, लेकिन यह बॉक्स के 100% संसाधन लेता है। जब कॉपी ऑपरेशन खत्म हो जाता है, तो सब कुछ सामान्य हो जाता है - सब कुछ फिर से पूरी तरह से उत्तरदायी है।

शायद यह एक हार्डवेयर त्रुटि है, मुझे नहीं पता, लेकिन मुझे पता है कि मेरे पास इस समस्या के साथ दो मशीनें हैं (दोनों ArchLinux पर हैं, एक डेस्कटॉप बॉक्स है, दूसरा लैपटॉप है)।

इसके लिए सबसे आसान और सबसे तेज़ "समाधान" (मैं मानता हूं कि यह 'वास्तविक' समाधान नहीं है, बस एक बदसूरत 'हैक') इस बफर को USB ड्राइव की औसत लिखने की गति के साथ फ़ाइल को कॉपी करके भरने से रोकने के लिए होगा, के लिए मुझे वह काफी होगा।


7
यदि आप सिस्टम में अन्य I / O- बाध्य प्रक्रियाओं के लिए "अच्छा" होने के प्रयास में डिस्क-टू-डिस्क कॉपी गति को सीमित करना चाहते हैं, तो आप शायद I / O शेड्यूलिंग को कर्नेल की क्षमता का लाभ उठाने से बेहतर हैं। बजाय। विशेष रूप से, ioniceयह सुनिश्चित करने के लिए उपयोग किया जा सकता है कि आपकी डिस्क-टू-डिस्क कॉपी प्रक्रिया नियमित प्रक्रियाओं की तुलना में कम प्राथमिकता पर I / O निर्धारित है।
स्टीवन मंडे

3
यह एक क्लासिक XY समस्या प्रश्न है। इसके बजाय आपको इस बारे में पूछना चाहिए कि जब आप USB डिवाइस में फ़ाइलों को कॉपी करते हैं तो आपका डेस्कटॉप अप्रतिसादी क्यों हो जाता है।
माइकल हैम्पटन

4
लिनक्स वास्तव में इन दिनों बड़े आई / ओ बफ़र्स का हास्यास्पद है। रैम साइज़ तेजी से बढ़े हैं कि मास स्टोरेज स्पीड। हो सकता है कि आप dd (1) और सिंक का उपयोग करके प्रतिलिपि बना सकें, ताकि यह बफर होने के बजाय समय-समय पर सिंक हो सके? और पाइप व्यूअर (pv) में रेट लिमिटिंग विकल्प है। कुछ इस तरह cat file | pv -L 3k > outfile। न तो cp (1) का उपयोग करने के समान हैं, हालांकि।
18

@ मायकिल हैम्पटन, आर्चलिनक्स के मंच पर इस मुद्दे पर कई अनसुलझे विषय हैं, इसलिए मुझे लगा कि मैं इसे एक अलग तरीके से सामना करने की कोशिश करूंगा, बस इसे काम करने के लिए।
एंटोनोन

@antonone लेकिन Unix.SE ArchLinux के फोरम नहीं हैं। यहां किसी के पास समाधान हो सकता है।
इजाकाता

जवाबों:


23

आप एक पाइप को थ्रॉटल कर सकते हैं pv -qL(या cstream -tसमान कार्यक्षमता प्रदान करता है)

tar -cf - . | pv -q -L 8192 | tar -C /your/usb -xvf -

-q stderr प्रगति रिपोर्टिंग निकालता है।

-Lसीमा बाइट्स में है।

--rate-limit/-Lसे ध्वज के बारे में अधिक man pv:

-L RATE, --rate-limit RATE

    Limit the transfer to a maximum of RATE bytes per second.
    A suffix of "k", "m", "g", or "t" can be added to denote
    kilobytes (*1024), megabytes, and so on.

यह उत्तर मूल रूप से इंगित करता है, throttleलेकिन यह परियोजना अब उपलब्ध नहीं है इसलिए कुछ पैकेज सिस्टम से फिसल गया है।


यदि cpधीमा नहीं किया जा सकता है, तो एक कस्टम कमांड का उपयोग करना एकमात्र विकल्प है जो मुझे लगता है।
एंटोनोन

1
तुलना में बहुत जटिल लगता हैrsync
LinuxSecurityFreak

मेरे लिए अधिक जटिल लेकिन अधिक उपयोगी लगता है। एक फ़ाइल लॉकिंगचैनिज्म का परीक्षण करने की आवश्यकता है और कुछ बाइट्स / एस को कॉपी करना धीमा करना पड़ता है जो कि rsync के साथ संभव नहीं है। बीमार इसे एक कोशिश दे और 'बिल्ली' को थ्रॉटल पाइप के माध्यम से एक फाइल
क्लजेक

कहने के लिए दुख की बात है लेकिन परियोजना मृत है bugs.debian.org/cgi-bin/bugreport.cgi?bug=426891
cljk

1
@cljk को अपडेट किया गया pv। धन्यवाद।
मैट

23

इसके बजाय cp -a /foo /barआप rsyncबैंडविड्थ का उपयोग और सीमित कर सकते हैं जैसे आपको ज़रूरत है।

से rsync'मार्गदर्शन है:

--bwlimit=KBPS

सीमा I / O बैंडविड्थ; प्रति सेकंड केबीटी

तो, एक्चुअल कमांड, जो प्रगति भी दिखा रहा है, इस तरह दिखेगा:

rsync -av --bwlimit=100 --progress /foo /bar

यह पुराने ड्राइव को कॉपी करने के लिए एक अच्छा विचार है जो मुझे मारना नहीं चाहिए।
jeremyjjbrown

से पढ़ने के लिए काम नहीं करता है /dev/zeroया/dev/random
cdosborn

rsync -a --bwlimit=1500 /source /destination1,5 एमबी / एस की गति पर विशालकाय फोल्डर की नकल करने के लिए पूरी तरह से काम करता है (जो किसी भी सर्वर को धीमा करने और बहुत अधिक समय नहीं लेने से बचने के बीच एक अच्छा व्यापार है)
लुआफ़ेरारियो

सिडेनोट: भले ही मैन पेज यह कह सकता है कि आप इकाइयों के लिए अक्षरों का उपयोग कर सकते हैं, उदाहरण के लिए 20m, यह सभी प्लेटफार्मों पर समर्थित नहीं है, इसलिए केबीटीस अंकन से बेहतर है।
ह्यूबर्ट ग्रेज्सकोविआक

मेरा दिन बचाया! cgroup cgexec -g ... cp /in /outहर समय काम नहीं कर रहा था (टर्मिनल से कुछ समय काम किया, स्क्रिप्ट से कभी नहीं) और मुझे पता नहीं क्यों ...
कुंभ पावर

13

मुझे लगता है कि आप अन्य गतिविधि को बाधित नहीं करने की कोशिश कर रहे हैं। लिनक्स के हाल के संस्करणों में शामिल हैं ioniceजो आपको IO के शेड्यूलिंग को नियंत्रित करने की अनुमति देता है।

विभिन्न प्राथमिकताओं की अनुमति देने के अलावा, डिस्क को अन्यथा निष्क्रिय होने पर IO को सीमित करने का एक अतिरिक्त विकल्प है। कमांड man ioniceप्रलेखन प्रदर्शित करेगा।

जैसे कमांड का उपयोग करके फ़ाइल को कॉपी करने का प्रयास करें:

ionice -c 3 cp largefile /new/directory

यदि दो निर्देशिकाएं एक ही डिवाइस पर हैं, तो आपको फ़ाइल को लिंक करना मिल सकता है जो आप चाहते हैं। यदि आप बैकअप प्रयोजनों के लिए कॉपी कर रहे हैं, तो इस विकल्प का उपयोग न करें। lnफ़ाइल को कॉपी नहीं किया जाता है क्योंकि यह बहुत तेज़ है। प्रयत्न:

ln largefile /new/directory

या यदि आप किसी भिन्न डिवाइस पर निर्देशिका से इसे एक्सेस करना चाहते हैं, तो कोशिश करें:

ln -s largefile /new/directory

आयनों में अच्छी तरह से काम करता है? मैं इसे सिर्फ "अनुकरण" काम पढ़ता हूं और कोई वास्तविक अंतर नहीं है? लिंक के लिए +1
निक

1
@ जब मैंने इसका उपयोग किया है, तो यह अपेक्षा के अनुरूप व्यवहार किया है। जिस प्रक्रिया से मैंने आयनिस लागू किया, वह काफी धीमी हो गई, एक अन्य प्रक्रिया जिसकी मुझे I / O की आवश्यकता थी, अपेक्षा के अनुरूप प्रदर्शन करने में सक्षम थी। अन्य प्रक्रियाओं से एक मध्यम I / O भार के साथ, मैं अधिकतम रूप से अधिकतम 'आला' लागू करके एक उच्च I / O प्रक्रिया को प्रभावी ढंग से निलंबित करने में सक्षम था। एक बार जब कोई प्रतिस्पर्धा आई / ओ नहीं थी, तो आयनित प्रक्रिया सामान्य रूप से प्रदर्शन करती थी।
BillThor

400MB फ़ाइल के साथ मैं एक से कॉपी कर रहा था HD एक SSD के लिए, प्रारंभिक 10s यह पूरी तरह से काम किया, तो अचानक मैंने देखा कि मैं उच्च IO लोड है और 1minute मशीन की तरह जमे हुए इंतजार करना पड़ा: /। मुझे cgroup लिखने में io throttle की समान समस्या है जहाँ यह कभी-कभी काम करता है और दूसरों को यह बिल्कुल काम नहीं आता।
कुंभ पावर

7

यदि ioniceसमाधान पर्याप्त नहीं है (जो भी) और आप वास्तव में I / O को एक पूर्ण मूल्य तक सीमित करना चाहते हैं तो कई संभावनाएं हैं:

  1. शायद सबसे आसान ssh:। इसमें एक अंतर्निहित बैंडविड्थ सीमा है। आप उदाहरण के लिए tar( cpया के बजाय ) का उपयोग करेंगे scp(यदि यह काफी अच्छा है; मुझे नहीं पता कि यह कैसे सहानुभूति और हार्ड लिंक को संभालता है) या rsync। ये कमांड उनके डेटा को पाइप कर सकते हैं sshtarआप के मामले में /dev/stdout(या -) और sshग्राहक tarको "दूरस्थ" पक्ष पर एक और निष्पादित करने वाले पाइप में लिखें ।

  2. सुरुचिपूर्ण लेकिन वेनिला कर्नेल में नहीं (AFAIK): डिवाइस मैपर लक्ष्य ioband। यह, निश्चित रूप से, केवल तभी काम करता है जब आप स्रोत या लक्ष्य मात्रा को umount कर सकते हैं।

  3. कुछ स्व-लिखित मज़ा: grep "^write_bytes: " /proc/$PID/ioआपको डेटा की एक प्रक्रिया लिखी गई राशि देता है। आप एक स्क्रिप्ट लिख सकते हैं, जो cpपृष्ठभूमि में शुरू होती है, उदाहरण के लिए सोती है 1/10 वीं सेकंड, पृष्ठभूमि cpप्रक्रिया को रोकती है ( kill -STOP $PID), उस राशि की जांच करती है जो लिखी गई है (और इस मामले में उसी मूल्य के बारे में), कितनी देर तक गणना करता है? cpऔसत हस्तांतरण दर को निर्धारित मूल्य तक ले जाने के लिए रुकना चाहिए, उस समय के लिए सोता है, उठता है cp( kill -CONT $PID), और इसी तरह।


हाँ, आम तौर पर मैं सिर्फ lftp का उपयोग करके scp के माध्यम से लोकलहोस्ट से जुड़ने के लिए, और वहाँ से बैंडविच को सीमित करता हूँ।
एंटोनोन

5

आपकी समस्या शायद आपके कंप्यूटर के साथ नहीं है, प्रति से, यह शायद ठीक है। लेकिन उस USB फ्लैश ट्रांस्फ़ॉर्मेशन लेयर का अपना एक प्रोसेसर होता है जिसे 90% दोषपूर्ण फ़्लैश चिप जितना हो सकता है उसकी भरपाई करने के लिए आपके सभी राइट्स को मैप करना होगा, कौन जानता है? आप इसे बाढ़ते हैं फिर आप अपने बफ़र्स को बाढ़ते हैं फिर आप पूरी बस में बाढ़ करते हैं, फिर आप फंस जाते हैं, आदमी - आखिरकार, यह वह जगह है जहां आपका सारा सामान है। यह काउंटर-सहज ज्ञान युक्त लग सकता है लेकिन आपको वास्तव में I / O को अवरुद्ध करने की आवश्यकता है - आपको एफटीएल को गति सेट करने की आवश्यकता है और फिर बस ऊपर रखें।

(हैकिंग पर एफटीएल माइक्रोकंट्रोलर: http://www.bunniestudios.com/blog/?p=3554 )

उपरोक्त सभी उत्तर काम करने चाहिए, इसलिए यह "मुझे भी!" किसी और चीज़ की तुलना में: मैं पूरी तरह से वहाँ रहा हूँ, यार। मैंने rsync --bwlimit arg (2.5mbs को सिंगल, एरर-फ्री रन - कुछ भी और मैं राइट- प्रोटेक्ट एरर के साथ वाइंड अप करता हूं) के लिए स्वीट स्पॉट लगता है। rsync मेरे उद्देश्य के लिए विशेष रूप से अनुकूल था क्योंकि मैं पूरे फाइल सिस्टम के साथ काम कर रहा था - इसलिए बहुत सारी फाइलें थीं - और बस rsync चलाने से दूसरी बार पहली बार चलने वाली सभी समस्याओं को ठीक कर देगा (जो जरूरी था जब मैं अधीर हो जाऊंगा और कोशिश करूंगा पिछले 2.5mbs रैंप के लिए)।

फिर भी, मुझे लगता है कि एक फ़ाइल के लिए यह उतना व्यावहारिक नहीं है। आपके मामले में आप सिर्फ dd को रॉ-राइट करने के लिए सेट कर सकते हैं - आप इस तरह से किसी भी इनपुट को संभाल सकते हैं, लेकिन एक समय में केवल एक ही लक्ष्य फ़ाइल (हालांकि वह एकल फ़ाइल संपूर्ण ब्लॉक डिवाइस हो सकती है)।

## OBTAIN OPTIMAL IO VALUE FOR TARGET HOST DEV ##
## IT'S IMPORTANT THAT YOUR "bs" VALUE IS A MULTIPLE ##
## OF YOUR TARGET DEV'S SECTOR SIZE (USUALLY 512b) ##
% bs=$(blockdev --getoptio /local/target/dev)

## START LISTENING; PIPE OUT ON INPUT ##
% nc -l -p $PORT | lz4 |\ 
## PIPE THROUGH DECOMPRESSOR TO DD ## 
>    dd bs=$bs of=/mnt/local/target.file \
## AND BE SURE DD'S FLAGS DECLARE RAW IO ##
>        conv=fsync oflag=direct,sync,nocache

## OUR RECEIVER'S WAITING; DIAL REMOTE TO BEGIN ##
% ssh user@remote.host <<-REMOTECMD
## JUST REVERSED; NO RAW IO FLAGS NEEDED HERE, THOUGH ## 
>    dd if=/remote/source.file bs=$bs |\
>    lz4 -9 | nc local.target.domain $PORT
> REMOTECMD  

यदि आप इसे शॉट देते हैं, तो आप डेटा ट्रांसपोर्ट के लिए ssh से थोड़ा तेज़ हो सकते हैं। वैसे भी, दूसरे विचार पहले ही ले लिए गए थे, इसलिए क्यों नहीं?

[संपादित करें]: मैंने अन्य पोस्ट में lftp, scp और ssh के उल्लेखों पर ध्यान दिया और सोचा कि हम एक दूरस्थ प्रतिलिपि के बारे में बात कर रहे थे। स्थानीय बहुत आसान है:

% bs=$(blockdev --getoptio /local/target/dev)
% dd if=/src/fi.le bs=$bs iflag=fullblock of=/tgt/fi.le \
>    conv=fsync oflag=direct,sync,nocache

[EDIT2]: क्रेडिट जहां यह कारण है: अभी देखा कि ptman ने टिप्पणी में पांच घंटे की तरह मुझे इसे हराया।

निश्चित रूप से आप एक गुणक के साथ यहां प्रदर्शन के लिए $ bs को ट्यून कर सकते हैं - लेकिन कुछ फाइल सिस्टम को लक्ष्य एफएस के सेक्टराइज के एक से अधिक होने की आवश्यकता हो सकती है इसलिए इसे ध्यान में रखें।


मेरी मशीन पर, झंडा है --getioopt, नहीं--getoptio
माइकल मिओर

2

समस्या यह है कि प्रतिलिपि आपकी मेमोरी को ब्लॉक में भर रही है "उड़ान में," उपयोगी "डेटा को क्राउडिंग"। लिनक्स कर्नेल हैंडलिंग I / O में धीमी डिवाइसों (इस मामले में USB) के लिए एक ज्ञात (और बहुत मुश्किल) बग।

शायद आप किसी स्क्रिप्ट की नकल करके पार्सल को पार करने की कोशिश कर सकते हैं, जैसे कि स्क्रिप्ट (प्रूफ-ऑफ-कॉन्सेप्ट स्केच, पूरी तरह से अप्रयुक्त!):

while true do
  dd if=infile of=outfile bs=4096 count=... seek=... skip=...
  sleep 5
done

समायोजन seekऔर प्रत्येक दौर skipद्वारा count। धुन करने की आवश्यकता है countताकि यह (बहुत अधिक) मेमोरी को न भरे, और 5इसे नाली की अनुमति देने के लिए।


2

गंदे पृष्ठ की सीमा कम करें। डिफ़ॉल्ट सीमा पागल है।

/Etc/sysctl.d/99-sysctl.conf बनाएं:

vm.dirty_background_ratio = 3
vm.dirty_ratio = 10

फिर sysctl -p या रिबूट चलाएं।

क्या हो रहा है कि गंतव्य डिस्क पर लिखा जा सकता है की तुलना में डेटा तेजी से पढ़ा जा रहा है। जब लिनक्स फाइलों को कॉपी करता है, तो यह क्या करता है उन्हें रैम में पढ़ा जाता है, फिर गंतव्य पर लिखने के लिए पृष्ठों को गंदे के रूप में चिह्नित करें। गंदे पृष्ठों की अदला-बदली नहीं की जा सकती। इसलिए यदि स्रोत डिस्क गंतव्य डिस्क की तुलना में तेज़ है और आप अधिक डेटा कॉपी कर रहे हैं, तो आपके पास निःशुल्क रैम है, तो कॉपी ऑपरेशन सभी उपलब्ध रैम को खाएगा (या कम से कम जो भी गंदा पृष्ठ सीमा है, जो इससे अधिक हो सकता है) उपलब्ध रैम) और भुखमरी का कारण बनता है क्योंकि गंदे पन्नों की अदला-बदली नहीं की जा सकती है और स्वच्छ पन्नों का उपयोग किया जाता है और गंदे चिह्नित किए जाते हैं क्योंकि वे मुक्त हो जाते हैं।

ध्यान दें कि उसकी समस्या को पूरी तरह से हल नहीं करेगा ... गंदे पृष्ठों के निर्माण में मध्यस्थता करने के लिए वास्तव में क्या कुछ आवश्यक है ताकि एक बड़ा हस्तांतरण हो सके सभी उपलब्ध रैम / सभी अनुमत गंदे पृष्ठों को न खाएं।


0

इस समस्या का हार्डवेयर या सॉफ़्टवेयर में त्रुटियों या दोषों से कोई लेना-देना नहीं है, यह सिर्फ आपका कर्नेल है जो आपके लिए अच्छा है और अपनी प्रॉम्प्ट बैक और कॉपी बैकग्राउंड में दे (यह इन-कर्नेल कैश का उपयोग करता है: अधिक RAM, अधिक कैश, लेकिन आप इसे कहीं भी / proc में लिखकर सीमित कर सकते हैं - हालांकि दोबारा नहीं)। फ्लैश ड्राइव बहुत धीमी है और जब कर्नेल इस पर लिखता है, तो अन्य IO ऑपरेशन पर्याप्त तेजी से नहीं किए जा सकते हैं। ioniceअन्य उत्तर में कई बार उल्लेख ठीक है। लेकिन क्या आपने -o syncOS बफ़रिंग से बचने के लिए ड्राइव को माउंट करने की कोशिश की है ? यह शायद वहाँ सबसे सरल समाधान है।


-O सिंक को इनेबल करने के बाद, मेरा इंटरनेट इस USB ड्राइव पर लिखने की गति से तेज है। मुझे समझ में नहीं आता है कि कर्नेल यह ट्रैक नहीं करता है कि कैश पेज कितनी जल्दी फ्लश हो रहे हैं, और उस पर आधारित भविष्य के फ्लश शेड्यूल करें। यह ऐसा है जैसे यह हमेशा पूरी गति से चलता है, भले ही यह खराब ड्राइव गति के साथ नहीं रख सकता है। लेकिन मुझे लगता है कि एक और सवाल के लिए एक विषय है।
एंटोनोन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.