きっかけ
Linuxエンジニアとしての基礎力のなさを見抜かれ、これ読んでみるといいよとおすすめされたのがきっかけ。
大変お恥ずかしい話だが、自分はエンジニア7年目にして初めてLinuxについての本を読んだ。それまではなにか上手くいかないことがあればブログやQiitaを参考にコピペしてその場しのぎしていただけだった。
目次
第1章 コンピュータシステムの概要 第2章 ユーザモードで実現する機能 第3章 プロセス管理 第4章 プロセススケジューラ 第5章 メモリ管理 第6章 記憶階層 第7章 ファイルシステム 第8章 ストレージデバイス
おもしろかったところ
メモリ管理
- プログラムは直接物理メモリにはアクセスしない。仮想メモリを通して物理メモリにアクセスする
- メモリ枯渇には仮想メモリ枯渇と物理メモリ枯渇がある。現在のx64アーキテクチャで仮想アドレス空間が128TBあるため仮想メモリ不足はなかなかおこるものではない。
- スワップアウトは物理メモリが枯渇した際、カーネルは使用中の物理メモリの一部をストレージに移動して物理メモリに空き領域を作成する。このときコピーされる領域はカーネルが「近いうちに使わないであろうもの」を所定のアルゴリズムに基づいて選定する
記憶階層
- キャッシュメモリの制御はハードウェア内で完結(基本的には)。チューニングできる部分ではない?
- プロセスがファイルを読み出す場合、ページキャッシュ(カーネルのメモリ領域)に一度コピーしてからプロセスのメモリにコピーされる。再読み出しが発生した場合、ストレージにアクセスするよりもページキャッシュにアクセスしたほうが何倍も早いため。そのかわりメモリを2倍消費する?
- 処理時間の大半はデータ転送が占める。実際の計算は大抵すぐにおわる。ハイパースレッドはコアを論理CPUという単位に分割、一方の処理がデータ転送待ちの時間を別の処理の計算時間にあてることでスループットが上がる。ただし全ての処理にハイパースレッドが有効なわけではない。
ファイルシステム
- ファイルシステムは
ファイル名
,ストレージの位置
,ファイルサイズ
を管理する。プロセスはファイルシステムにファイル名を渡すだけでストレージに保管されたファイルにアクセスできる - ファイルシステムが異なっても、プロセス側でファイルシステムの違いを意識する必要はない。プロセスは共通のシステムコールである
creat()
,open()
,close()
などを使えばよいため。システムコールをファイルシステムが処理、デバイスドライバを通してストレージ・デバイスへアクセスする df
コマンドのストレージ使用量はメタデータのサイズも含まれてい- すべてのデバイス(NICを除く)は
/dev
にてファイルシステム上で管理されている。デバイスはキャラクタデバイス、ブロックデバイスに分かれている - tmpfsはメモリ上に作成したファイルシステム。揮発性だがストレージへのアクセスが発生しないので高速
- procfsはプロセスの情報をまとめてくれる。
/proc/[pid]/
にプロセスの情報が配置されている。メモリマップ、コマンドライン引数、CPU使用状況など。ps, sarコマンドなどはここの情報を引っ張ってきてる
ストレージデバイス
- HDDはデータをセクタ単位で保管する
- メモリへのアクセスは電気的な処理だけなのに対して、HDDはプラッタの回転、スイングアームの移動が物理的な処理となるためレイテンシが大きい
- でもランダムアクセスではなくシーケンシャルなアクセスならそこそこ性能はでる
- ファイルシステム、デバイスファイルを介した処理はブロックデバイス層でまとめられ、各デバイスドライバへアクセスされる。
- 空間的局所性の特徴から、ブロックデバイス層では先読みを行っている
- 直前にアクセスした領域の後続に連続する領域は直近でアクセスされる可能性が高い
- SSDは物理的な処理がなく、電気処理だけで完結。よってHDDよりも高速に読み書きができる
感想
エンジニア一年目でこの本読んでおけばなと大後悔時代。Linuxの知識はコンテナやサーバレスの文脈でも引き続き活用できると思う。特にパラメータチューニングを金の弾丸以外で解決するならなおさらこの辺の知識が役に立つんじゃないかなーと思った。このブログ記事をまとめながらメモと本を読み返していると、全然理解が足りていないなと実感。これからもまた読み返すんだろうなと思いました。