Linux
AWS
gcp
Linuxコマンド

ドケチへ送るサーバーのディスク&メモリ節約のための7つ道具


はじめに


  • 「レンタルサーバーは無料枠・エコノミープランでしか使わん( ^ω^)」

  • 「今使っているサーバーの容量とかギリギリだけど、増設は面倒(:3 」∠ )

  • 「クラウドのディスク容量課金・転送量課金をケチりたい('A`).」

と常日頃考えている私が、同じような志を持つ初心者の為に、10年前のLinux初心者だった私へ伝えたいと思う7つのコトをまとめてみました。


前提など


  • 「初心者向け & 忘記録」な内容

  • クラウドのレンタルサーバー(低スペ、SSH可、sudo不要)を想定

  • Linuxの一般的なディストリビューションで、追加インストール等なしでできること

もっといろんな工夫はあると思いますが、今回はとりあえずパッと思い付いた7つだけを紹介します。


1. 標準入力

基本中の基本ですが、データを逐次的に処理する場合であれば、全データをメモリ上に載せる必要はありません。

たとえば、以下のようなことは安易にやってはいけません。


fi = open('x00.csv', encoding='utf-8').readlines()
for line in fi:
print('\t'.join(line.strip().split(',')))

Pythonで上記のように書くと、データx00.csvをメモリ上にすべて展開してしまいます。

数GBオーバーのデータを扱おうとした場合、明らかに問題です。

無論、データ全体をメモリ上に載せる必要がある場合もありますが、基本的にはfor文などで逐次的に処理していくことがほとんどです。

色々と回避する手段はありますが、標準入力(Pythonではsys.stdin)を使うのが汎用性が高くおすすめです。

# シェル

cat x00.csv | python test.py

# python

import sys

for line in sys.stdin:
print(line.strip().split(','))


2. ファイル圧縮 gzip -c

さて、処理したデータをどのように保存するのが良いでしょうか?

通常は標準出力を使って以下のように保存することが多いでしょう。


cat x00.csv | python test.py > y00.tsv

しかし、ディスク容量を少しでもケチるのであれば、標準出力されたデータを圧縮しながら保存しましょう。


cat x00.csv | python test.py | gzip -c > y00.tsv.gz

ファイル圧縮のコマンドには、gzipbzip2xzなどがあり、この3つのコマンドであれば-cオプションをつけることで、パイプラインでデータを受け取り、圧縮結果を標準出力として書き出すことができます。

よく使用されるのはgzipであり、ほとんどのシステムで圧縮・解凍ができるため、安定性があります。

gzipは上記の3つ中では最も圧縮率が低いですが、それでもかなりファイルサイズを圧縮できます(圧縮率がデフォルトで、おおよそ半分くらい)。

基本的には圧縮率が高いほど圧縮や展開に時間がかかるため、必要に応じてオプションやコマンドを変更しましょう。

なお参考に、オプションを与えず圧縮した場合、容量は以下のようになりました。

ls -lh

338M x00.csv
142M x00.csv.gz
97M x00.csv.bz2
92M xcsv.xz


3. 圧縮したファイルの読み込み zcat

上記でデータを圧縮しましたが、使用するために以下のように展開していては、まったくの無駄です。


gzip -d y00.csv.gz

そこで、展開しながら中身を標準出力で吐き出すzcatなどのコマンドを活用しましょう。

たとえば、以下のように処理をすることで、常に圧縮した状態でデータを扱うことができます。


zcat y00.csv.gz | python hoge.py | gzip -c > z00.txt.gz

なお、.bz2に対応するコマンドはbzcat.xzに対応するコマンドはxzactになります。


4. ファイル分割 split

1つのファイルのサイズが大きくなると、様々な不都合が生じます。

たとえば、数10GBのファイルを処理しているときに、アクシデントやエラーによって途中で中断してしまった場合、また最初から処理をやり直さなければならない状況になりえます。

特に、処理時間が長くなりがちな低スペマシンでは致命的ともいえるでしょう。

また進行状況も把握しにくく、精神衛生上もよくありません。

本当に精神衛生上よくありません。

そこで、大きすぎるファイルは以下のように分割して扱います。


mkdir x_dir; cd x_dir
split -l 10000 ../x00.csv -d

上記コマンドでは、x00.csvを10000行ずつのファイルに分割して保存します(データサイズでの分割も可能です)。

なお、圧縮後のファイルでも問題なく分割できます。


5. ディレクトリを圧縮 tar -zcvf

さて上記のように分割すると、特定のディレクトリに複数のファイルが存在することになりますが、このディレクトリ全体を圧縮したい場合が出てきます。

そのような場合tarコマンドを使用します。パッケージをダウンロードすると、よく.tar.gzなどの拡張子がついていますが、要するにあの形式に落とし込みます。

tarでは.gz.bz2xzなどで圧縮することができます。


tar -zcvf x_dir.tar.gz x_dir
tar -jcvf x_dir.tar.bz2 x_dir
tar -Jcvf x_dir.tar.xz x_dir

なお、以下の方法で解凍することができます。


tar -zxvf x_dir.tar.gz
tar -jxvf x_dir.tar.bz2
tar -Jxvf x_dir.tar.xz


6. 圧縮しながら転送する rsync -az

AWSなどの多くのクラウドのレンタルサーバーでは、データの転送量に課金が発生します。

そこで転送量を抑えるために、サーバー間のデータ転送にscpではなく、より高機能なrsyncを利用します。

rsync -az --progress x_dir.tar.gz aws:~/

-z オプションを指定してやることで、圧縮しながら転送してくれます。

また、帯域を制限したり、更新のあったファイルのみアップロードしたりするなど、便利な機能が多数存在します。

なお豆知識ですが、同サーバー内のコピーでもrsyncを使用できます。


7. 同じデータを作らない ln -s

安易にcpコマンドを使わないようにしましょう。

まったく同じデータを複数作ってもほぼ無駄ですし、コピーしすぎると元が何のデータであったかわからなくなるデメリットも生じます。

ファイルの場所を参照するln -sを使用して、実態を減らしましょう。

ln -s original_path symble_path

なお、rsyncで-aオプション(正確には-l-aには-lが含まれている)をつけていれば、シンボリックリンクをシンボリックリンクとしてコピーできます(scpだと、実ファイルがコピーされる)。


おわりに

この記事では初心者の人にぜひ知っておいてほしい、ディスク&メモリ節約の7つ道具について紹介しました。

今からでもすぐにできることばかりだと思いますので、早速実践してみてはいかがでしょうか?