AWS IoTのレイテンシーを測ってみた（１）

AWS IoTの特性を理解するために、デバイスから見たPublish/Subscribeのレイテンシーを調べてみました。
<img width="240" alt="PubSubTestEnv.png" src="https://qiita-image-store.s3.amazonaws.com/0/70819/4844356c-a45c-ed94-82da-8bd0981502e2.png">

# 1. nodejs版SDKをAmazonLinuxに導入
## AmazonLinuxインスタンスを用意
ap-northeast-1にt2.microインスタンスを作成
## nodebrewとnodejsを導入

参考：[nodebrewでNode.js( io.js )を管理する](http://qiita.com/sawapi/items/adfc11465d034f4f2cf9)

```bash:shell
$ curl -L git.io/nodebrew | perl - setup
```
.bashrcへのパスの追加

```bash:.bashrc
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
```bash:shell
$ source ~/.bashrc
```
```bash:shell
$ nodebrew install-binary v0.12.7
```
## AWS IoT device sdkを導入
- 事前準備

```bash:bash
$ sudo yum install gcc-c++
$ sudo yum install git
```
```bash:shell
$ git clone https://github.com/aws/aws-iot-device-sdk-js.git
$ cd aws-iot-device-sdk-js
$ npm install mqtt
$ npm install blessed
$ npm install blessed-contrib
$ npm install minimist
```
## 証明書を配置

AWS IoT のコンソールで、Thingを作成し、証明書と鍵を作成＆配置
２つのデバイス情報をそれぞれ、~/certs1配下と~/certs2配下に配置する。

```bash
$ ls -l /home/ec2-user/certs1
合計 20
-rw------- 1 ec2-user ec2-user 1758 10月 18 10:59 aws-iot-rootCA.crt
-rw------- 1 ec2-user ec2-user 1220 10月 18 10:59 certificate.pem.crt
-rw------- 1 ec2-user ec2-user 1675 10月 18 10:59 private.pem.key
-rw------- 1 ec2-user ec2-user  451 10月 18 10:59 public.pem.key
-rw------- 1 ec2-user ec2-user 1758 10月 18 10:59 root-CA.crt
```
# 2. サンプルの動作確認
以下のサンプルで、２つのデバイス間でAWS IoTを介したPublish/Subscribeが行われます。

- コンソール１

```bash
$ cd ~/aws-iot-device-sdk-js/examples/
$ node device-example.js -f ~/certs1 -g ap-northeast-1 -t 1
connect
message topic_1 {"count":1,"pub_time":"13:27:16.751"}
message topic_1 {"count":2,"pub_time":"13:27:20.753"}
message topic_1 {"count":3,"pub_time":"13:27:24.755"}
```
- コンソール２

```bash
$ cd ~/aws-iot-device-sdk-js/examples/
$ node device-example.js -f ~/certs2 -g ap-northeast-1 -t 2
connect
message topic_2 {"count":1,"pub_time":"13:28:34.259"}
message topic_2 {"count":2,"pub_time":"13:28:38.260"}
message topic_2 {"count":3,"pub_time":"13:28:42.261"}
```
# 3. Publish/Subscribe のレイテンシを計測してみる
レイテンシ計測用に、サンプルを修正

```javascript:diff-device-test2.js 
$ diff device-example.js device-test2.js 
23a24,34
> function time_text(){
>      d = new Date();
>      t = ("00" + (d.getMonth()+1)).substr(-2) + "/";
>      t += ("00" + (d.getDate())).substr(-2) + " ";
>      t += ("00" + d.getHours()).substr(-2) + ":";
>      t += ("00" + d.getMinutes()).substr(-2) + ":";
>      t += ("00" + d.getSeconds()).substr(-2) + ".";
>      t += ("000" + d.getMilliseconds()).substr(-3);
>      return t
> }
> 
53c64
<     console.log('connect');
---
>     console.log(time_text() + ' connect');
64c75
<         console.log( 'substituting '+ minimumDelay + 'ms delay for ' + args.delay + 'ms...' );
---
>         console.log( time_text() + ' substituting '+ minimumDelay + 'ms delay for ' + args.delay + 'ms...' );
72c83
<             mode_1_process: count }));
---
>           count: count, pub_time: time_text() }));
77c88
<             mode_2_process: count }));
---
>           count: count, pub_time: time_text() }));
83c94
<     console.log('close');
---
>     console.log(time_text() + ' close');
89c100
<     console.log('reconnect');
---
>     console.log(time_text() + ' reconnect');
93c104
<     console.log('offline');
---
>     console.log(time_text() + ' offline');
99c110
<     console.log('error', error);
---
>     console.log(time_text() + ' error', error);
105c116,117
<     console.log('message', topic, payload.toString());
---
>     msg = JSON.parse(payload.toString());
>     console.log(msg.pub_time, time_text(), topic, msg.count);
```
実行例

```
$ node device-test2.js -f ~/certs1 -g ap-northeast-1 -t 1
connect
10/18 12:30:26.841 10/18 12:30:26.882 topic_1 1
10/18 12:30:30.844 10/18 12:30:30.884 topic_1 2
10/18 12:30:34.847 10/18 12:30:34.884 topic_1 3
 :
```
```
$ node device-test2.js -f ~/certs2 -g ap-northeast-1 -t 2
connect
10/18 12:30:24.730 10/18 12:30:24.766 topic_2 1
10/18 12:30:28.733 10/18 12:30:28.761 topic_2 2
10/18 12:30:32.736 10/18 12:30:32.765 topic_2 3
```
Publish/Subscribeの **平均レイテンシは22msでした。速い!**

- 計測条件
実行間隔 4秒
実行回数 200回 x 2

- Publish/Subscribe レイテンシー

| |レイテンシー(Sec)|
|:-----------|------------:|
| 平均 | 0.022 |
| 90パーセンタイル | 0.032 |

![image](https://qiita-image-store.s3.amazonaws.com/0/70819/3e38ad30-c48e-16e8-a4a1-3e84391aed9f.png)

**その後の長期間の計測で、顕著な変動が見られたので、以下の記事を投稿しました。**
[続報：AWS IoTのレイテンシーを測ってみた（２）](http://qiita.com/okapin/items/ffcb70e2bfbf8989225b)