Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Python で rsocket で通信が爆速でやばい.

More than 5 years have passed since last update.

漢なら RDMA でデータ送りたいですね!

とりあえず手っ取り早く rsocket http://syoyo.wordpress.com/2012/12/06/rsocket-new-way-of-rdma-aware-programming/ を使い, 既存の python スクリプトで高速転送を実現してみましょう.

構成

        IPoIB        1 GbE
Server: 172.24.0.1  192.168.11.1
Client: 172.24.0.2  192.168.11.2

Server と Client は InfiniBand QDR と, 1 GbE で物理的に繋がっています.
InfiniBand のレイヤは IPoIB で繋がっているものとします.

テストスクリプト

Client から 1GB のデータを送り, Server 側はそれを受け取るだけというスクリプトです(単方向データ通信).

# server.py
import socket

import itertools

HOST = ''                 
PORT = 8081               
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
ret = []
while 1:
    #print "recv"
    data = conn.recv(1024*1024*1024)
    #print "len:%d", len(data)
    if not data: break
    #ret.append(data)

conn.close()
print "done"
# client.py
import socket
from datetime import datetime
from datetime import timedelta

def millis(s, e):
    dt = e - s
    ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0
    return ms

HOST = '192.168.11.1'    # GbE remote host
#HOST = '172.24.0.1'    # IPoIB remote host
PORT = 8081             
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
d = "a" * 1024*1024*1024
print "sending..."
start_ms = datetime.now()
s.sendall(d)
end_ms = datetime.now()
print "sent"
s.close()
print "elap: %d [ms]" % millis(start_ms, end_ms)

1 GbE での接続では...

# server 側で実行
$ python server.py

# client 側で実行
$ python clientpy

elap: 9109 [ms]

1GbE だと理論上限が 100MB/s くらいですから期待通りですね.

IPoIB だと…

elap: 23711 [ms]

あらなんだか IPoIB そのままだと 40 MB/s くらいと遅いですね.
1GB のデータなので少なくとも 10000 ms(10 secs, 100MB/s) くらいで転送してもらいたいところ.

rsocket をつかう.

LD_PRELOAD で dll 差し替えにより, 既存 socket プログラムでも RDMA を使うことができるようになります.
(必ずしも全てではないが, iperf なども動きます)

また, RDMA が使える物理的経路(InfiniBand, etc)が IPoIB で見えている必要があります.

今回はこの LD_PRELOAD による方法を使います.
使った rsocket(librdmacm) のバージョンは 1.0.18 です.

# Server
$ LD_PRELOAD=/usr/local/lib/rsocket/librspreload.so python server.py
# Client
$ LD_PRELOAD=/usr/local/lib/rsocket/librspreload.so python client.py

elap: 695 [ms]

Super cool! 1GB のデータが 0.7 秒 で送れました. 1.4 GB/s ほど. これだと python で GB 単位のデータの処理(バイト配列処理)をするほうが時間かかってしまうレベルですね.

TODO

  • バッファに mmap を使ってより python 側の処理を軽くできないか検討してみる.

まとめ

rsocket すばらしい.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away