بلاگ/انتقال آرشیو Tar بین سرورها بدون ذخیره‌سازی محلی
به‌روز شده

انتقال آرشیو Tar بین سرورها بدون ذخیره‌سازی محلی

1405/06/030 بازدید
انتقال آرشیو Tar بین سرورها بدون ذخیره‌سازی محلی

انتقال آرشیو Tar بین سرورها بدون ذخیره‌سازی محلی

دو سرور که با یک اتصال SSH مستقیم داده جابه‌جا می‌کنند وقتی باید حجم زیادی فایل از یک سرور به سرور دیگر منتقل کنید، روش معمول این است که ابتدا یک آرشیو بسازید، آن را دانلود کنید، و بعد روی سرور مقصد آپلود و استخراج کنید. این روش برای فایل‌های بزرگ دو مشکل دارد: به فضای خالی اضافی روی هر دو سرور و ماشین واسط نیاز دارد، و زمان انتقال تقریباً دو برابر می‌شود.

با ترکیب tar و ssh می‌توان داده را مستقیم بین دو سرور جابه‌جا کرد، بدون این‌که هیچ‌وقت یک فایل آرشیو کامل روی دیسک نوشته شود. این راهنما دستورهای لازم برای این کار، مانیتور کردن پیشرفت، رمزنگاری داده حین انتقال و رفع مشکلات رایج را پوشش می‌دهد.

این الگو برای انتقال یک‌باره مناسب‌ترین گزینه است. اگر قرار است هم‌گام‌سازی به‌صورت مرتب و فقط برای تغییرات جدید انجام شود، ابزار rsync معمولاً کارآمدتر است چون به‌جای کل داده، تنها بخش‌های تغییرکرده را منتقل می‌کند.

مبانی: چطور tar می‌تواند مستقیم استریم کند

دستور tar می‌تواند به‌جای نوشتن آرشیو در یک فایل، آن را روی خروجی استاندارد (stdout) بنویسد. با علامت - به‌جای نام فایل، این رفتار فعال می‌شود:

tar cf - -C /path/to/source . | tar xf - -C /path/to/destination

نکتهٔ مهم استفاده از -C است: این گزینه قبل از فشرده‌سازی وارد آن مسیر می‌شود، پس مسیرهای داخل آرشیو نسبی می‌مانند و بعد از استخراج، ساختار پوشه‌ای اضافه و ناخواسته (مثل کل مسیر کامل /path/to/source/...) ساخته نمی‌شود.

انتقال مستقیم بین دو سرور با SSH

همان الگو را می‌توان با یک تونل SSH ترکیب کرد تا داده مستقیم از یک سرور به سرور دیگر برود، بدون این‌که از ماشین شما (یا هر جای دیگری) عبور کند و روی دیسک نوشته شود:

ssh user@source-server "tar cf - -C /path/to/source ." | ssh user@destination-server "tar xf - -C /path/to/destination"

سرور مبدأ آرشیو را روی stdout می‌نویسد، این خروجی از طریق pipe به دستور دوم SSH فرستاده می‌شود، و سرور مقصد همان جریان را مستقیم استخراج می‌کند. کل عملیات از رایانهٔ شما عبور می‌کند (چون هر دو اتصال SSH را شما برقرار کرده‌اید)، اما هیچ‌وقت روی دیسک محلی شما نوشته نمی‌شود.

عبور از یک سرور واسط با ProxyJump

اگر سرور مبدأ یا مقصد فقط از پشت یک bastion/jump host در دسترس است، -J همان مسیر ورودی SSH را از طریق آن سرور واسط برقرار می‌کند:

ssh -J user@bastion-host user@source-server "tar cf - -C /path/to/source ." | ssh -J user@bastion-host user@destination-server "tar xf - -C /path/to/destination"

از آنجا که bastion host معمولاً از اینترنت عمومی هم در دسترس است، تقویت امنیت آن اهمیت بیشتری پیدا می‌کند؛ ابزاری مثل Fail2ban تلاش‌های مکرر ورود ناموفق به SSH را مسدود می‌کند.

مانیتور کردن پیشرفت انتقال با pv

tar به‌خودی‌خود درصد پیشرفت یا سرعت انتقال را نشان نمی‌دهد. ابزار pv (Pipe Viewer) را می‌توان وسط pipe قرار داد تا حجم منتقل‌شده و سرعت لحظه‌ای را ببینید:

ssh user@source-server "tar cf - -C /path/to/source ." | pv | ssh user@destination-server "tar xf - -C /path/to/destination"

روی اکثر توزیع‌های لینوکس با apt install pv یا yum install pv نصب می‌شود. برای انتقال‌های چند ده گیگابایتی که ممکن است چند ساعت طول بکشند، داشتن این تخمین سرعت کمک زیادی به برنامه‌ریزی می‌کند. اگر پهنای باند خود سرور محدودیت اصلی سرعت است، سرور مجازی با پهنای باند بالا این تنگنا را از ابتدا کم‌اثر می‌کند.

رمزنگاری جریان داده حین انتقال

اتصال SSH خودش رمزنگاری‌شده است، پس در بیشتر موقعیت‌ها لایهٔ رمزنگاری اضافه لازم نیست. اما اگر داده باید از یک نقطهٔ میانی غیرقابل‌اعتماد عبور کند یا سیاست امنیتی سازمان رمزنگاری end-to-end جدا از SSH را الزامی کرده باشد، می‌توان جریان را قبل از عبور از pipe رمزنگاری کرد.

با OpenSSL:

ssh user@source-server "tar cf - -C /path/to/source . | openssl enc -aes-256-cbc -pbkdf2 -salt -pass pass:yourpassword" | ssh user@destination-server "openssl enc -d -aes-256-cbc -pbkdf2 -pass pass:yourpassword | tar xf - -C /path/to/destination"

با GPG:

ssh user@source-server "tar cf - -C /path/to/source . | gpg --encrypt --recipient your-key-identifier" | ssh user@destination-server "gpg --decrypt | tar xf - -C /path/to/destination"

گذاشتن رمز عبور مستقیم در دستور (مثل نمونهٔ بالا) در تاریخچهٔ shell باقی می‌ماند؛ برای استفادهٔ واقعی بهتر است رمز را از یک متغیر محیطی یا فایل با دسترسی محدود بخوانید.

مثال واقعی: مهاجرت یک اپلیکیشن وب

فرض کنید باید محتوای /var/www/html را از یک سرور قدیمی به یک سرور جدید منتقل کنید، بدون توقف طولانی و بدون نیاز به فضای موقت اضافه روی هیچ‌کدام از دو سرور:

ssh user@old-server "tar cf - -C /var/www/html ." | pv | ssh user@new-server "tar xf - -C /var/www/html"

مانیتور کردن سرعت و پیشرفت انتقال فایل با ابزار pv در ترمینال

برای پایگاه‌داده معمولاً باید جدا از فایل‌ها با ابزار مخصوص همان دیتابیس (مثل mysqldump یا pg_dump) عمل کرد؛ همان الگوی pipe روی خروجی این ابزارها هم قابل استفاده است.

فشرده‌سازی و بهینه‌سازی کارایی

اگر پهنای باند بین دو سرور محدودتر از توان پردازندهٔ آن‌هاست، فشرده‌سازی حین انتقال می‌تواند سرعت کلی را بالا ببرد؛ اگر برعکس، CPU محدودتر است، فشرده‌سازی می‌تواند کندتر هم بکند. جدول زیر گزینه‌های رایج را مقایسه می‌کند:

روشفلگ‌های tarنسبت فشرده‌سازیمصرف CPU
بدون فشرده‌سازیcf / xfنداردکم
gzipczf / xzfمتوسطکم تا متوسط
bzip2cjf / xjfبالاتر از gzipمتوسط تا بالا
xzcJf / xJfبالاترینبالا

نمونهٔ دستور با gzip:

ssh user@source-server "tar czf - -C /path/to/source ." | ssh user@destination-server "tar xzf - -C /path/to/destination"

برای شبکهٔ داخلی سریع (مثلاً بین دو سرور در یک دیتاسنتر) معمولاً بهتر است اصلاً فشرده‌سازی نکنید، چون پردازنده تنگنای واقعی می‌شود؛ برای انتقال بین دو دیتاسنتر یا از راه دور، gzip معمولاً تعادل خوبی بین سرعت و حجم می‌دهد.

رفع مشکلات رایج

  • خطای دسترسی (Permission denied): کاربری که با آن SSH می‌زنید باید هم روی مبدأ اجازهٔ خواندن فایل‌ها و هم روی مقصد اجازهٔ نوشتن در مسیر مقصد را داشته باشد. برای فایل‌های سیستمی معمولاً باید با کاربری با دسترسی sudo یا root اجرا کنید. برای تنظیم درست این سطح دسترسی‌ها و بستن حفره‌های امنیتی رایج، مروری بر افزایش امنیت سرور لینوکس مفید است.
  • قطع شدن اتصال وسط انتقال: برای انتقال‌های طولانی، دستور را داخل screen یا tmux روی ماشین واسط اجرا کنید تا اگر اتصال شما قطع شد، عملیات روی سرور ادامه پیدا کند.
  • اطمینان از صحت آرشیو: بعد از انتقال، می‌توانید با find . -type f -exec md5sum {} \; روی هر دو سمت چک‌سام فایل‌ها را بگیرید و مقایسه کنید تا مطمئن شوید چیزی خراب یا ناقص منتقل نشده است.

جمع‌بندی

ترکیب tar و ssh راهی سریع و بدون نیاز به فضای موقت برای جابه‌جایی فایل بین دو سرور است، از یک پوشهٔ کوچک تا مهاجرت کامل یک اپلیکیشن وب. اگر برای مهاجرت به سمت یک زیرساخت پایدارتر با پهنای باند و I/O بهتر آماده‌اید، می‌توانید سرور مجازی آریانت را متناسب با حجم داده و تعداد بازدید سایت خود انتخاب کنید.