偏った言語信者の垂れ流し

2014-04-11

[]Funkloadのテストコードの書き方について

fl-run-benchコマンドで実行するテストコードの書き方についてメモ。

  • Cyclesの値はCU(ConcurrentUser)の数
  • durationに設定した秒数の間、テストを繰り返し実行する
  • レポートにでるSUCCESSやERRORの数はテストを繰り返し実行したときの結果を集計したもの

デモのコードだとレポートが思ったとおりに出なかった。

HTTPで1回リクエストして、ステータスコードが200だった場合に成功、それ以外の場合に失敗というような試験で負荷をかけるならば、テストケースクラスのメソッド内でforループを使って繰り返しGETやPOSTを行うのはダメ。

forループで繰り返しリクエストしてしまうと、ループ内のすべてが成功しないとSUCCESSにならなくてレポートが読みづらいものになってしまってた。

以下のようなコードになるのが適当かな。

# coding: utf8
import unittest
from funkload.FunkLoadTestCase import FunkLoadTestCase


class Simple(FunkLoadTestCase):
    def setUp(self):
        self.server_url = 'http://localhost:5000/'

    def test_simple(self):
        server_url = self.server_url
        ret = self.get(server_url, description='Get url')
        # ステータスコードが200以外なら失敗とする
        self.assertEqual(ret.code, 200)


if __name__ in ('main', '__main__'):
    unittest.main()

これだと綺麗に結果が出た。

f:id:nullpobug:20140411133423p:image

2014-04-08

[]FunkLoadでJSONをPOSTする

FunkLoadJSONをPOSTする方法を調べたのでメモ。

FunkLoadでJSONを送信するテストコード

funkload.utils.Dataを使うと、Content-Typeを指定してデータ列を送信できる。

test_Simple.py
# coding: utf8
import unittest
import json
from funkload.FunkLoadTestCase import FunkLoadTestCase
from funkload.utils import Data


class Simple(FunkLoadTestCase):
    def setUp(self):
        self.server_url = 'http://localhost:5000/'

    def test_simple(self):
        """Content-Type: application/jsonでJSONをPOSTする例
        """
        server_url = self.server_url
        json_data = Data(
            'application/json',
            json.dumps({
                'spam': 123,
                'egg': [1, 2, 3]}))
        ret = self.post(
            server_url,
            json_data,
            description='Get url')
        print ret.body


if __name__ in ('main', '__main__'):
    unittest.main()

サーバー

テスト対象のサーバー側はFlaskで送信されたJSONを返すぐらいのものを用意した。

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/', methods=['POST'])
def hello():
    print request.json
    return jsonify(result=request.json)

if __name__ == '__main__':
    app.run()

実行結果

$ python test_Simple.py
test_simple: Starting -----------------------------------
        Access 20 times the main url
test_simple: POST: http://localhost:5000/ [User data application/json]
        Page 1: Get url ...
test_simple:  Done in 0.006s
{
  "result": {
    "egg": [
      1, 
      2, 
      3
    ], 
    "spam": 123
  }
}
.
----------------------------------------------------------------------
Ran 1 test in 0.008s

OK

参考

2014-04-07

[][]PythonでParquetフォーマットを扱ってみたいので調べていた

ParquetフォーマットをPythonから扱ってみたいので調べていた。

jcrobak/parquet-python ? GitHub

githubにあったものを見つけたけど、まだバグが結構あるっぽい。書き込みなども実装されてないようなので、実用は無理そう。

Parquetフォーマットの仕様は公開されてるから、モジュールを自作しないとダメっぽいかな。

試すだけ試してみた。

インストール

snappy圧縮を扱うためにpython-snappyを入れておく。libsnappy-devを入れておかないとインストールでこける。

$ aptitude install libsnappy-dev
$ git clone https://github.com/jcrobak/parquet-python.git
$ mkvirtualenv parquet
(parquet)$ pip install parquet-python
(parquet)$ pip install python-snappy

ImpalaでParquetフォーマットのテーブルを作ってデータを入れておく

impala-shellでParquetフォーマットのテーブルを作ってデータを入れておく。insert一回につき1つのParquetフォーマットファイルがHDFS上に作られてる。デフォルトでSnappy圧縮なのかな。

[slave1.hadoop.nullpobug.com:21000] > create table table1_parquet (c1 INT, c2 STRING) STORED AS PARQUET;
Query: create table table1_parquet (c1 INT, c2 STRING) STORED AS PARQUET

Returned 0 row(s) in 1.30s
[slave1.hadoop.nullpobug.com:21000] > insert into table1_parquet values (12345, "spam");
Query: insert into table1_parquet values (12345, "spam")
Inserted 1 rows in 7.84s
[slave1.hadoop.nullpobug.com:21000] > insert into table1_parquet values (54321, "egg");
Query: insert into table1_parquet values (54321, "egg")
Inserted 1 rows in 0.59s
[slave1.hadoop.nullpobug.com:21000] > select * from table1_parquet;
Query: select * from table1_parquet
+-------+------+
| c1    | c2   |
+-------+------+
| 12345 | spam |
| 54321 | egg  |
+-------+------+
Returned 2 row(s) in 1.10s

HDFSNFSマウントしてparquet-pythonで見てみる

HDFSからファイルをgetで手元に持ってきてもいいんだけど、面倒だったのでNFSマウントして読み込んでみた。

(parquet)$ sudo mount -t nfs -o vers=3,nolock 192.168.11.111:/ /mnt
(parquet)$ /mnt/user/hive/warehouse/table1_parquet
(parquet)$ ls
(parquet)$ python -m parquet 23424a1c672030c0-328d0d142b02beb7_168138759_data.0 --metadata
File Metadata: 23424a1c672030c0-328d0d142b02beb7_168138759_data.0
  Version: 1
  Num Rows: 1
  k/v metadata: 
    (none)
  schema: 
    schema (None): length=None, repetition=None, children=2, converted_type=None
    c1 (INT32): length=None, repetition=OPTIONAL, children=None, converted_type=None
    c2 (BYTE_ARRAY): length=None, repetition=OPTIONAL, children=None, converted_type=None
c1      c2
12345   spam
(parquet)$ python -m parquet ce4693f4d1c5ba92-bbae6347a1a25b93_1955015047_data.0 --metadata
File Metadata: ce4693f4d1c5ba92-bbae6347a1a25b93_1955015047_data.0
  Version: 1
  Num Rows: 1
  k/v metadata: 
    (none)
  schema: 
    schema (None): length=None, repetition=None, children=2, converted_type=None
    c1 (INT32): length=None, repetition=OPTIONAL, children=None, converted_type=None
    c2 (BYTE_ARRAY): length=None, repetition=OPTIONAL, children=None, converted_type=None
c1      c2
54321   egg

読み込みは大丈夫そう。書き込みがないのでここまでか。

参考

2014-04-06

[]HDFSNFS Gatewayを試してみた

CDH5.0がリリースされていたのでHDFSのNFSGatewayを試した。

ClouderaManagerからnfsgatewayを追加して起動するだけ。

nfsgatewayを動かすホストでportmapサービスが動いていないと起動に失敗した。

CentOS6.5だと、portmapサービスはrpcbindで起動できる。

[root@master1 ~]# service rpcbind start
Starting rpcbind:                                          [  OK  ]

マウントする

別のCentOSのホストからマウントする。nfs-utilsを入れてrpcbindを起動しておく。

[tokibito@centos ~]$ sudo yum install nfs-utils
[tokibito@centos ~]$ sudo service rpcbind start
[tokibito@centos ~]$ sudo mount -t nfs -o vers=3,proto=tcp,nolock 192.168.11.111:/ /mnt/
[tokibito@centos ~]$ ls /mnt/
tmp
[tokibito@centos ~]$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  1.1G   16G   7% /
tmpfs                 496M     0  496M   0% /dev/shm
/dev/xvda1            485M   75M  385M  17% /boot
192.168.11.111:/       47G   17G   30G  36% /mnt

最初に試した時マウントがうまくいかなくて、nfsgatewayを再起動したりしてたらうまくいった。詳細まで調べてない。

NFSでマウントできるとLinuxのコマンドツールで操作できたり、MacOSXではFinderから操作できるのがうれしいですね。

参考

2014-03-29

[]Pythonの研修サービスを始めました

勤務先でPythonの研修サービスを始めることになりました。

BeProud Python Training (Pythonプログラミング研修)

私も講師の一人です。受託開発の業務でも5年以上Pythonを使っているので、ノウハウは蓄積されてます。

よろしくお願いします!