एक नेटवर्क में एक फाइल के लिए डेल्टा ट्रांसफर का उपयोग करके rsync क्यों नहीं है?


15

मैंने इस प्रश्न और इस प्रश्न को देखा है , लेकिन वे उन लक्षणों को संबोधित नहीं करते हैं जो मैं देख रहा हूं।

मेरे पास एक बड़ी लॉग फ़ाइल (लगभग 600 एमबी) है जिसे मैं एक सेलुलर नेटवर्क में स्थानांतरित करने की कोशिश कर रहा हूं। क्योंकि यह यह सिर्फ करने के लिए जोड़ा जाता है एक लॉग फ़ाइल है (हालांकि यह केवल सम्मिलित करें के साथ एक SQLite डेटाबेस में वास्तव में है किया जा रहा है, तो यह नहीं है काफी है कि के रूप में सरल रूप में, लेकिन पिछले 4k पेज के अपवाद के साथ (या शायद एक कुछ) फ़ाइल हर बार समान होती है। यह महत्वपूर्ण है कि केवल परिवर्तन (और जो भी चेकसम को प्रेषित करने की आवश्यकता है) वास्तव में भेजे जाएं, क्योंकि डेटा कनेक्शन पैमाइश है।

फिर भी जब मैं एक अनमीटर्ड कनेक्शन (उदाहरण के लिए फ्री वाईफाई हॉटस्पॉट) पर एक परीक्षण करता हूं, तो मुझे स्पीड-अप या कम किए गए डेटा ट्रांसफर को देखा या रिपोर्ट नहीं किया जाता है। एक धीमे वाईफाई कनेक्शन पर मैं 1MB / s या उससे कम के आदेश पर देखता हूं, रिपोर्ट करता है कि स्थानांतरण में लगभग 20 मिनट लगने वाले हैं। एक तेज वाईफाई कनेक्शन पर मुझे एक समान तेज गति दिखाई देती है, लेकिन स्पीडअप की कोई रिपोर्ट नहीं है, और स्थानांतरण का दूसरा प्रयास (जो अब तेज होना चाहिए क्योंकि दो फाइलें समान हैं) अब कोई अंतर नहीं दिखाती हैं।

मेरे द्वारा उपयोग की जा रही संवेदनशील जानकारी को हटाने के लिए (sanitized) कमांड है:

rsync 'ssh -p 9999' --progress LogFile michael@my.host.zzz:/home/michael/logs/LogFile

अंत में मुझे जो आउटपुट मिलता है वह इस तरह दिखता है:

LogFile
    640,856,064 100%   21.25MB/s   0:00:28 (xfr$1, to-chk=0/1)

इसमें किसी भी तरह के स्पीडअप का जिक्र नहीं है।

मुझे संदेह है कि समस्या निम्नलिखित में से एक हो सकती है:

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

मैंने निम्नलिखित को खारिज कर दिया है:

  • डेल्टा स्थानान्तरण एक स्थानीय नेटवर्क पर नहीं किया जाता है। खारिज कर दिया क्योंकि मैं इंटरनेट पर स्थानांतरण करने की कोशिश कर रहा हूं
  • चेकसम गणना के कारण ओवरहेड। मैंने इस व्यवहार को एक तेज़ और धीमे वाईफ़ाई कनेक्शन पर देखा है और अंतरण दर बाध्य नहीं लगती है।

1
but with the exception of the last 4k page (or maybe a few) the file is identical each time. क्या आपने वास्तव में इसके साथ सत्यापन किया था cmp? या बेहतर, के साथ xdeltaया कुछ और? यदि आप वास्तव में स्थानांतरण आकार को कम से कम करना चाहते हैं, तो पुराने और नए संस्करणों को स्थानीय रूप से रखें, ताकि आप स्थानीय रूप से (rsync के अलावा किसी अन्य चीज़ के साथ) कम से कम द्विआधारी अंतर की गणना कर सकें और केवल यह सुनिश्चित कर सकें कि पैमाइश के संबंध में चेकसम को भेजना नहीं है। द्विआधारी-फ़ाइल स्तर के बजाय डेटाबेस-रिकॉर्ड स्तर पर ऐसा करना शायद बेहतर भी है, जैसा कि अपमानजनक सुझाव देता है।
पीटर कॉर्ड्स

1
इसके अलावा, आप rsync --statsभी इस्तेमाल कर सकते हैं , और भी -v -vअधिक वर्बोज़ आँकड़े प्राप्त करने के लिए। Rsync आपको बताएगा कि वहाँ कितना बेजोड़ डेटा था।
पीटर कॉर्डेस

जवाबों:


27

सारांश

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

एक बेहतर तरीका शायद नए रिकॉर्ड्स को SQL डंप के रूप में डंप करना, इसे संपीड़ित करना और इसे स्थानांतरित करना है। वैकल्पिक रूप से, SQLite के लिए कई प्रतिकृति समाधान प्रतीत होते हैं, आप उनमें से किसी एक का उपयोग कर सकते हैं।

roaima एक न्यूनतम न्यूनतम पर सुझाव देता है कि आप शायद एक पूर्ण एसक्यूएल डंप कर सकते हैं gzip --rsyncable, इसका उपयोग करके संपीड़ित कर सकते हैं , और फिर rsync कि। एक परीक्षण के लायक है, मुझे लगता है, यह देखने के लिए कि क्या यह एक छोटा पर्याप्त डेल्टा है।

विवरण

आप जो कोशिश कर रहे हैं वह काम करना चाहिए । मैं व्यक्तिगत रूप --partialसे आपके rsync विकल्पों में जोड़ दूंगा, बस अगर यह किसी तरह से आंशिक स्थानांतरण के रूप में बढ़ती फ़ाइल का पता लगा रहा है। आप इसके साथ बेहतर ट्रांसफर आँकड़े भी प्राप्त कर सकते हैं--stats

जाँच करने के लिए दूसरी बात यह है कि अगर SQLite वास्तव में केवल कुछ पृष्ठों को छू रहा है - ईमानदारी से, मुझे आश्चर्य नहीं होगा अगर यह पूरी फ़ाइल में पृष्ठ लिख रहा है। जांच करने का एक त्वरित तरीका cmp -lदो संस्करणों पर उपयोग करना होगा - देखें कि क्या अंतिम कुछ के अलावा अन्य पृष्ठों में परिवर्तन हैं। याद रखें कि rsync"पृष्ठ" / ब्लॉक का विचार SQLite से भिन्न है; आप rsync के माध्यम से बदल सकते हैं --block-size। इसे कम करने से मदद मिल सकती है।

संपादित करें: मैंने SQLite के साथ एक त्वरित परीक्षण किया। यहां तक ​​कि 32k पृष्ठों के साथ, लॉग प्रविष्टियों का एक गुच्छा जोड़कर हर पृष्ठ पर स्क्रिबल किया गया । नीचे दिए गए विवरण।

संपादित करें 2 : यह वाल मोड में बेहतर प्रतीत होता है, हालांकि आप अभी भी ओवरहेड की एक बड़ी मात्रा लेते हैं, शायद चेकपॉइंट से।

संपादित करें 3 : यह भी बेहतर है कि आप जिस डेटा को प्रति स्थानांतरण में जोड़ रहे हैं - मुझे लगता है कि यह शायद कुछ ब्लॉकों को बार-बार खंगालता है। तो आप चाहे वह एक बार या सौ बार लिखी हो, चाहे वह ब्लॉकों का एक ही सेट स्थानांतरित कर रहा हो।

BTW: स्थानांतरण को कम करने के लिए, आप शायद rsync से बहुत बेहतर कर सकते हैं। उदाहरण के लिए, पिछले हस्तांतरण के माध्यम से xz --best(या यहां तक ​​कि gzip) चलाने के बाद से नए रिकॉर्ड का एक एसक्यूएल डंप शायद एक छोटा सा होगा।

क्विक SQLite टेस्ट

स्कीमा:

CREATE TABLE log (id integer primary key not null, ts integer not null, app text not null, message text not null);
CREATE INDEX log_ts_idx on log(ts);
CREATE INDEX log_app_idx on log(app);

पर्ल कार्यक्रम:

use 5.022;
use DBI;

my $DBH = DBI->connect('dbi:SQLite:test.db', '', '', {RaiseError => 1, AutoCommit => 0})
    or die "connect...";

my @apps = (
    '[kthreadd]',        '[ksoftirqd/0]',
     # there were 191 of these
    '[kworker/5:0H]',
);

my @messages = <DATA>;

(my $curr_time) = $DBH->selectrow_array(<<QUERY);
    SELECT COALESCE(MAX(ts),978307200) FROM log
QUERY

my $n_apps = @apps;
my $n_msgs = @messages;
say "Apps: $n_apps";
say "Messages: $n_msgs";
say 'Start time: ', scalar gmtime($curr_time), ' UTC';

my $sth = $DBH->prepare(<<QUERY);
    INSERT INTO log(ts, app, message) VALUES (?, ?, ?)
QUERY

for (my $i = 0; $i < 10_000; ++$i) {
    $sth->execute(int($curr_time), $apps[int rand $n_apps], $messages[int rand $n_msgs]);
    $curr_time += rand 0.1;
}
$DBH->commit;

__DATA__
microcode: CPU0 microcode updated early to revision 0x19, date = 2013-06-21
Linux version 4.5.0-2-amd64 (debian-kernel@lists.debian.org) (gcc version 5.3.1 20160528 (Debian 5.3.1-21) ) #1 SMP Debian 4.5.5-1 (2016-05-29)

बहुत अधिक उदाहरण लॉग संदेश (2076) थे।

किन पृष्ठों के लिए जाँच की जा रही है:

cp test.db test.db.old
perl test.pl
cmp -l test.db.old test.db | perl -n -E '/^\s*(\d+) / or die "wtf"; $bucket{int $1/32768} = 1; END { say join "\n", sort( { $a <=> $b } keys %bucket) }'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.