ablog

不器用で落着きのない技術者のメモ

sysbench で MySQL に負荷をかける

export HOST=rds-mysql-57-22.******.ap-northeast-1.rds.amazonaws.com
export PASSWD=******

nohup sysbench /usr/local/share/sysbench/oltp_read_write.lua \
 --db-driver=mysql \
 --table-size=1000000 \
 --mysql-host=${HOST} \
 --mysql-user=awsuser \
 --mysql-password=${PASSWD} \
 --mysql-db=mydb \
 --db-ps-mode=disable \
 prepare > sysbench_prepare.log 2>&1
  • 負荷をかける
nohup sysbench /usr/local/share/sysbench/oltp_read_write.lua \
 --db-driver=mysql \
 --table-size=1000000 \
 --mysql-db=mydb \
 --mysql-host=${HOST} \
 --mysql-user=awsuser \
 --mysql-password=${PASSWD} \
 --time=300 \
 --db-ps-mode=disable \
 --threads=32 \
 run > sysbench_run.log 2>&1
  • 実行結果A
sysbench 1.1.0-805825f (using bundled LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 16
Initializing random number generator from current time


Initializing worker threads...

Threads started!

SQL statistics:
    queries performed:
        read:                            1126972
        write:                           311196
        other:                           157263
        total:                           1595431
    transactions:                        76765  (639.54 per sec.)
    queries:                             1595431 (13291.74 per sec.)
    ignored errors:                      3733   (31.10 per sec.)
    reconnects:                          0      (0.00 per sec.)

Throughput:
    events/s (eps):                      639.5390
    time elapsed:                        120.0318s
    total number of events:              76765

Latency (ms):
         min:                                   11.71
         avg:                                   25.01
         max:                                  160.56
         95th percentile:                       50.11
         sum:                              1919887.30
  • 実行結果X
sysbench 1.1.0-805825f (using bundled LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 16
Initializing random number generator from current time


Initializing worker threads...

Threads started!

SQL statistics:
    queries performed:
        read:                            1781374
        write:                           497103
        other:                           250324
        total:                           2528801
    transactions:                        123083 (1025.57 per sec.)
    queries:                             2528801 (21070.85 per sec.)
    ignored errors:                      4158   (34.65 per sec.)
    reconnects:                          0      (0.00 per sec.)

Throughput:
    events/s (eps):                      1025.5703
    time elapsed:                        120.0142s
    total number of events:              123083

Latency (ms):
         min:                                    6.99
         avg:                                   15.60
         max:                                  148.99
         95th percentile:                       28.67
         sum:                              1919663.71

Threads fairness:
    events (avg/stddev):           7692.6875/38.11
    execution time (avg/stddev):   119.9790/0.00

Amazon Linux 2 に sysbench をインストールしようとすると、libmysqlclient_r.so.16 とlibmysqlclient_r.so.16 が必要と怒られる

yumAmazon Linux 2 に sysbench をインストールしようとすると、libmysqlclient_r.so.16 とlibmysqlclient_r.so.16 が必要と怒られる。

事象

  • コマンド
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench
  • エラー
Error: Package: sysbench-1.0.181.el6.x86_64 (akopytov_sysbench)
 Requires: libmysqlclient_r.so.16()(64bit)
Error: Package: sysbench-1.0.181.el6.x86_64 (akopytov_sysbench)
 Requires: libmysqlclient_r.so.16(libmysqlclient_16)(64bit)
 You could try using — skip-broken to work around the problem
 You could try running: rpm -Va — nofiles — nodigest

解決策

  • 以下の手順でインストールに成功した。
sudo yum -y install git gcc make automake libtool openssl-devel ncurses-compat-libs
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm
sudo yum -y update
sudo yum -y install mysql-community-devel mysql-community-client mysql-community-common
git clone https://github.com/akopytov/sysbench
cd sysbench
./autogen.sh
./configure
make
sudo make install
  • sysbench のバージョンを確認
$ sysbench --version
sysbench 1.1.0-805825f

環境

$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
$ uname -r
4.14.173-137.229.amzn2.x86_64
$ curl http://169.254.169.254/latest/meta-data/ami-id
ami-0f310fced6141e627

Amazon S3 のプレフィックスはオブジェクトか?

$ dd if=/dev/urandom of=origin.dat count=100 bs=1M
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.568612 s, 184 MB/s
$ aws s3 mb s3://ponkotsu-jp
make_bucket: ponkotsu-jp
$ aws s3api put-object --bucket ponkotsu-jp --key 2017/ ★ 2017 はプレフィックスだけ先に作成
{
    "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\""
}
$ aws s3 cp origin.dat s3://ponkotsu-jp/2017/AZ
upload: ./origin.dat to s3://ponkotsu-jp/2017/AZ
$ aws s3 cp origin.dat s3://ponkotsu-jp/2017/Horiba
upload: ./origin.dat to s3://ponkotsu-jp/2017/Horiba
$ aws s3 cp origin.dat s3://ponkotsu-jp/2018/FujitaV ★ 2018 はオブジェクト作成時にプレフィックスをつける
upload: ./origin.dat to s3://ponkotsu-jp/2018/FujitaV
$ aws s3 ls --recursive s3://ponkotsu-jp/
2020-05-26 13:18:49          0 2017/ ★2017 は単体でオブジェクトとして存在する
2020-05-26 13:19:29  104857600 2017/AZ
2020-05-26 13:19:48  104857600 2017/Horiba
2020-05-26 13:20:07  104857600 2018/FujitaV ★2018は単体でオブジェクトとして存在しない

追記

$ aws s3api put-object --bucket ponkotsu-jp --key 2019/ --body origin.dat
{
    "ETag": "\"e37b9bbd310ef9eb352e771cb3764608\""
}
$ aws s3 ls --human-readable --recursive s3://ponkotsu-jp/
2020-05-26 13:18:49    0 Bytes 2017/
2020-05-26 13:19:29  100.0 MiB 2017/AZ
2020-05-26 13:19:48  100.0 MiB 2017/Horiba
2020-05-26 13:20:07  100.0 MiB 2018/FujitaV
2020-05-26 14:38:57  100.0 MiB 2019/ ★100MBのプレフィックスなオブジェクト氏

もうちょっと追記

$ aws s3 rm s3://ponkotsu-jp/2017/AZ
delete: s3://ponkotsu-jp/2017/AZ
$ aws s3 rm s3://ponkotsu-jp/2017/Horiba
delete: s3://ponkotsu-jp/2017/Horiba
$ aws s3 rm s3://ponkotsu-jp/2018/FujitaV
delete: s3://ponkotsu-jp/2018/FujitaV
$ aws s3 ls --human-readable --recursive s3://ponkotsu-jp/
2020-05-26 13:18:49    0 Bytes 2017/
2020-05-26 14:38:57  100.0 MiB 2019/

Github で fork する

Github にログインした状態で fork したいリポジトリに移動して [Fork] をクリックする。
f:id:yohei-a:20200526185029p:plain

参考

リポジトリのフォークは、2 つのステップからなるシンプルなプロセスです。 練習用のリポジトリを用意しましたので、ぜひお使いください。

  1. GitHub で、octocat/Spoon-Knife リポジトリに移動します。
  2. ページの右上にある [Fork] をクリックします。
リポジトリをフォークする - GitHub ヘルプ

Python データ処理チートシート

Gropu By

Multiple functions can also be applied at once. For instance, say we’d like to see how tip amount differs by day of the week - agg() allows you to pass a dictionary to your grouped DataFrame, indicating which functions to apply to specific columns.

SELECT day, AVG(tip), COUNT(*)
FROM tips
GROUP BY day;
/*
Fri   2.734737   19
Sat   2.993103   87
Sun   3.255132   76
Thur  2.771452   62
*/
In [21]: tips.groupby('day').agg({'tip': np.mean, 'day': np.size})
Out[21]: 
           tip  day
day                
Fri   2.734737   19
Sat   2.993103   87
Sun   3.255132   76
Comparison with SQL — pandas 1.0.3 documentation

日付でまるめる

Series.dt.round()に渡す第一引数を”D”にします。

df['datetime'] = df['datetime'].dt.round("D")
print(df)

結果

    datetime
0 2018-04-02
1 2019-05-01
[python] pandasのdatetimeを日、時間、週などに丸める方法

ユニークな値をカウントする

df = pd.DataFrame({'A': [1, 2, 3], 'B': [1, 1, 1]})
df.nunique()
A    3
B    1
dtype: int64
df.nunique(axis=1)
0    1
1    2
2    2
dtype: int64
pandas.DataFrame.nunique — pandas 1.0.3 documentation

ピボットテーブルでユニーク値をカウントする

  • コード
import pandas as pd
pv=df.pivot_table( values ='id',index = ['date'], columns = ['serviceId'], aggfunc = lambda x:x.nunique() )
  • 実行結果

f:id:yohei-a:20200525133628p:plain

ピボットテーブルを折れ線グラフで表示する

  • コード
pv=df.pivot_table( values ='id',index = ['date'], columns = ['serviceId'], aggfunc = lambda x:x.nunique() )
pv.plot(figsize=(10,10), title="Title")
plt.ylabel("count")
plt.show()
  • 実行結果

f:id:yohei-a:20200525141723p:plain

numpy の random.choice で重み付けをする
  • コード
df = pd.DataFrame(np.random.choice(['A','B','C','D'],p=[0.7, 0.1, 0.1, 0.1], size=(10)))
  • 実行結果

f:id:yohei-a:20200525144514p:plain

グラフで階層軸ラベルを表現する

pandas で csv_read すると "Unnamed: 1" といったカラムが追加される

事象

  • pandas で csv_read すると "Unnamed: 1" といったカラムが追加される

f:id:yohei-a:20200524115953p:plain

原因

  • よく見るとヘッダにタブが 2 つ入っていたので、1 つに修正したらお直った。
# hostname  と date の間に 2 つタブが入っている
hostname		date	timestamp	kbmemfree	kbmemused	%memused	kbbuffers	kbcached	kbcommit	%commit

sar を Jupyter Notebook でグラフ化してみる

  • sar をテキストに出力して加工する。
export LANG=C
ls *.dat|while read LINE
do
    ARR=(${LINE//_/ })
    sar -u -f ${LINE}|perl -slane '/(\d{2}\/\d{2}\/\d{2})/ and $d=$1;if($#F==7 and !/%user/){printf(qq/%s\t%s\t%s\n/,$node,$d,join(qq/\t/,@F))}' -- -node=${ARR[0]} >> sar-u.tsv
    sar -r -f ${LINE}|perl -slane '/(\d{2}\/\d{2}\/\d{2})/ and $d=$1;if($#F==7 and !/kbmemfree/){printf(qq/%s\t%s\t%s\n/,$node,$d,join(qq/\t/,@F))}' -- -node=${ARR[0]} >> sar-r.tsv    
    sar -d -f ${LINE}|perl -slane '/(\d{2}\/\d{2}\/\d{2})/ and $d=$1;if($#F==9 and !/DEV/){printf(qq/%s\t%s\t%s\n/,$node,$d,join(qq/\t/,@F))}' -- -node=${ARR[0]} >> sar-d.tsv
done
  • sar-u.tsv にヘッダをつける
hostname	date	timestamp	CPU	%user	%nice	%system	%iowait	%steal	%idle
  • sar-r.tsv にヘッダをつける
hostname	date	timestamp	kbmemfree	kbmemused	%memused	kbbuffers	kbcached	kbcommit	%commit
  • sar-d.tsv にヘッダをつける
hostname	date	timestamp	DEV	tps	rd_sec/s	wr_sec/s	avgrq-sz	avgqu-sz	await	svctm	%util
  • ファイルを S3 にアップロードする。
  • sar -u をグラフ化
import pandas as pd
import matplotlib.pyplot as plt
df_sar_u = pd.read_csv("s3n://yohei-a-file/sar/sar-u.tsv", sep="\t")
df_sar_u_host01 = df_sar_u.query('hostname == "host01" & date == "05/01/20"')
df_sar_u_host01.plot(x='timestamp', y=['%user', '%nice', '%system', '%iowait', '%steal', '%idle'], kind='area', stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

f:id:yohei-a:20200524082207p:plain

  • sar -r をグラフ化
import pandas as pd
import matplotlib.pyplot as plt
df_sar_r = pd.read_csv("s3n://yohei-a-files/sar/sar-r.tsv", sep="\t")
df_sar_r_host01 = df_sar_r.query('hostname == "host01" & date == "05/01/20"')
df_sar_r_host01.plot(x='timestamp', y=['kbmemfree', 'kbmemused', 'kbbuffers', 'kbcached'], kind='area', stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

f:id:yohei-a:20200524083326p:plain

  • sar -d をグラフ化
import pandas as pd
import matplotlib.pyplot as plt
df_sar_r = pd.read_csv("s3n://yohei-a-files/sar/sar-d.tsv", sep="\t")
df_sar_r_host01 = df_sar_r.query('hostname == "host01" & date == "05/15/20"')
df_sar_r_host01.plot(x='timestamp', y=['await', 'svctm'], stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

f:id:yohei-a:20200524102501p:plain

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df_sar_d = pd.read_csv("s3n://yohei-a-files/sar/sar-d.tsv", sep="\t")
df_sar_d_host01 = df_sar_d.query('hostname == "host01" & date == "05/15/20"')
sns.jointplot(x="tps", y="await", data=df_sar_d_host01)

f:id:yohei-a:20200524110159p:plain

  • まとめ
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df_sar_u = pd.read_csv("s3n://aws-yohei-a-files/sar/sar-u.tsv", sep="\t")
df_sar_u_host01 = df_sar_u.query('hostname == "host01" & date == "05/15/20"')
df_sar_u_host01.plot(x='timestamp', y=['%user', '%nice', '%system', '%iowait', '%steal', '%idle'], kind='area', stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

df_sar_r = pd.read_csv("s3n://aws-yohei-a-files/sar/sar-r.tsv", sep="\t")
df_sar_r_host01 = df_sar_r.query('hostname == "host01" & date == "05/15/20"')
df_sar_r_host01.plot(x='timestamp', y=['kbmemfree', 'kbmemused', 'kbbuffers', 'kbcached'], kind='area', stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

df_sar_d = pd.read_csv("s3n://aws-yohei-a-files/sar/sar-d.tsv", sep="\t")
df_sar_d_host01 = df_sar_d.query('hostname == "host01" & date == "05/15/20"')
df_sar_d_host01.plot(x='timestamp', y='await', stacked=True, alpha=0.4, figsize=(20,10))
plt.show()

sns.jointplot(x="tps", y="await", data=df_sar_d_host01)

f:id:yohei-a:20200524115331p:plain