調べなきゃ寝れない!と調べたら余計に寝れなくなったソケットの話

  • 820
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

課題

最近良く名前を聞くようになったソケット通信が速度が早くて良い的な話をしてたものの、ソケットってそんなに最近出てきたようなことだっけか?と曖昧になったので調べなきゃ寝れない!ということで調べてみた

プロトコルの種類

通信といえばTCP/UDPだろうと再度確認

プロトコル 概要 備考
TCP/IP 信頼性が高い データグラム(電文)が届いたかどうかを誤りチェックしていて、届いていない場合は再送要求をする。
到着順序が保証されていて、到着したデータは並べ替えられる。
それらが失敗した場合はエラーになるようになっている
UDP/IP 基本的な通信 データグラム(電文)は一方的に送信され、相手に届いたかどうかのチェック等はしない。
エラーの検知はしない。変な受信データもただ破棄されるのみのため、その分単純で高速。

ただ、ソケットの話はここでは出てこない

ソケットはどこの話か?

ソケットのタイプ
osi.png

OSI参照モデルではセッション層部分。TCP/UDPより上のレイヤーだった。

あれ?ソケットって普通の通信じゃね?

ソケットにも種類があるのか調べてみた。

ソケット 概要 特定方法 通信箇所
INETドメイン ネットワーク上でマシンを越えてのプロセス間通信 IPアドレス+ポート番号 他マシンと通信可
UNIXドメイン 同じマシン上で動いているプロセスが通信を行うためのソケット。
アドレス・名前空間としてファイルシステムを使用している。
ファイルシステム内のinodeとしてプロセスから参照される。
ファイル名で一致 自マシンのみ

なるほど、最近ソケット通信、ソケット通信と言ってるのはUNIXドメインソケットの事か!

UNIXドメインソケットって何がいいの?

Performance Analysis of Various Mechanisms for Inter-process Communicationに素晴らしい検証があった。

It was hypothesized that pipes would have the highest throughtput due to its limited functionality, since it is half-duplex, but this was not true. For almost all of the data sizes transferred, Unix domain sockets performed better than both TCP sockets and pipes, as can be seen in Figure 1 below.

On some machines, Unix domain sockets reached transfer rates as high as 1500 MB/s.

osnet_cs_binghamton_edu_publications_TR-20070820_pdf-2.png

UNIXドメインソケットは、TCPソケット(INETドメインソケット)よりも遥かにスループットが優れてるらしい。Solaris(UltraSPARC processor)ではアーキテクチャの違いからUNIXドメインソケットのほうが遅いらしい。

よし、これで寝れる

Redis コア開発者 @pnoordhuis のツイート

TIL that "an abstract socket address is distinguished by the fact that sun_path[0] is a null byte ('\0')". Anybody knows why this exists?

えーと、抽象名前空間ソケット??まだ、UNIXドメインソケットにも種類があるのか?

UNIXドメインソケットの種類

unix - sockets for local interprocess communication

種類 概要
ファイルシステムパス名(pathname) きっと一番知られている一般的な手法。bind(2)を使用して、NULL終端(\0)されたファイルシステム上のパスに結びつけることができる。ファイルを使用しているため、パーミッションを調整する必要がある。サーバプロセスが終了するときには、unlink(2)で名前を削除し、場合によってはそれが参照しているファイルも削除するのがお作法。
無名(unnamed) bind(2)を使ってパス名に結び付けることができないストリーム型のソケットは名前を持たない。socketpair(2)を使うと、名前のついていない CONNECTED なソケットのペアが生成される。fork してファイルディスクリプターを繋ぎ直してあげれば、pipe で実現するのと同じような双方向のプロセス間通信ができる。
抽象名前空間(abstract) sun_pathにファイルシステムのパスではなく、NULLバイト(\0)であることで区別される。NULLバイト以降に名前(文字列)を渡すが、ファイルパス名とは関係ない。ファイルシステムと紐付いていないので、 ファイルシステムのパーミッションなどに関係なくソケット通信できてしまう。Linuxでのみ利用可能。unlink(2)で終了する必要がない。

どのUNIXドメインかを見極めるには

$netstat -al --protocol=unix で確認する

ファイルシステムパス名

I-Node path部分にファイルパス名が表示されている

Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     STREAM     LISTENING     154823 /var/lib/mysql/mysql.sock

無名

I-Nodeは割り振られるが、pathは表示されない

Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node Path
unix  3      [ ]         STREAM     CONNECTED     175322

抽象名前空間

I-Node path部分に@がついた名前が表示される

Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     STREAM     LISTENING     6653   @/com/ubuntu/upstart

UNIXドメインソケットをサポートしているサービス

ミドルウェア 概要 種類 使用方法 連携ミドルウェア
Nginx web server pathname server divective unicorn, gunicorn, php-fpm, etc...
Unicorn ap server pathname Public Instance Methods
Mysql db server pathname
Redis KVS pathname How fast is Redis?
Memcached KVS pathname Using memcached
upstart deamon abstract
sytemd deamon abstract
OS? kernelプロセス? unnamed

まとめ

ソケット通信は今度からUNIXドメインソケット通信と言うこと(どのマニュアルにもちゃんと書いてあったけど笑)。TCPで接続することばっかりやってきたので、気にもしてなかったがKVSとかの接続はUNIXドメインソケット通信にしたらもう少し効率よく使えるのではないかと。まだまだ、調べたらいろいろありそうなので継続調査。

もう寝ます笑