見出し画像

Analyticsのデータを読み出してみる

こんにちは、辻村です。今回は、Analyticsのデータを REST APIを使って読み出してみるという内容です。RESTful APIを ZFS Storageで使ってみる例は、以前書かせて頂いた記事が役に立つと思います。今回のお話は、2回に分かれます。今回は読み出してみるところまで、次回はそのデータをどう加工するかについて検討してみるという内容です。

はじめに

今回は、RESTful APIの利用方法はご存知であるという前提で、以下のことについてお話しします。

・データセットとワークシートの関係
・今回の次回の記事の目標
・データセットのデータの読みだし
・作業の中で見つかった問題点

最後の問題点については、解決されていないこともあります。解決されていないことはそのまま書いてあります。

データセットとワークシートの関係

ZFS Storageでは、統計データのことを「データセット」と呼びます。ZFSにも同じ用語がありますが、全く関連はありません。あくまでもデータの集合の意味の data-set です。例えば、NFSの一秒あたりのコマンドの処理数とかディスク装置の一秒あたりの I/Oというのは、それぞれデータセットです。

これに対して、ワークシートは、複数のデータセットの情報を同時にプロットしたものです。例えば、先ほどの例で言えば、NFS一秒あたりのコマンドの処理数のグラフと、ディスク装置一秒あたりのI/Oを同時に表示することができます。また、ワークシートは保存しておき、必要なときに開くことができます。

今回の記事と次回の記事の目標

標準の機能では、ワークシートの各々のグラフは別々に表示されます。残念ながら重ね合わせて表示することはできません。もし、重ね合わせたり、数値として加工できると、いろいろな解析ができそうですよね?この2回の記事では、複数のグラフを重ねてみようというのが目標です。

今回については、データを読み出すところまでです。Python のコードもサンプルとしてご提供します。

データセットのデータの読みだし

まず、単一のデータを読み出すにはどうするかを明確にするために、データセットの読み出すには、どうすれば良いかについてお話しします。実は、RESTful API経由でワークシートを作成することもできますが、今回の記事では触れることはしません。

データセットを読み出すには、以下のステップを RESTful APIでふむ必要があります。コードを書かずに色々試してみるには、RESTのクライアントを使うのが良いかと思います。

①クライアントを認証する。
②データセットの一覧を出力する。(目的のデータセットのパス取得のため)
③データセットに含まれるデータを読み出す。

①クライアントを認証する。

ZFS Storage の RESTful API は、https://<ZFSSAのIPアドレス>:215/からアクセスができます。この URL に普通にアクセスすると、Browser User Interface (BUI)と呼ばれる管理画面が出てきます。このあとに /apiで始まるアクションを付加することで、RESTful APIを使うことができます。

クライアントを認証するためのURL は以下のような形になります。

https://192.168.150.21:215/api/access/v1

サンプルのプログラム list1.py では、requests パッケージを使ってアクセスをしています。このあとの呼び出しでも同じですが、以下の3つのキーワードを指定しています。

(1) auth=(user_id, password)
(2) proxies = no_proxy
(3) verify=False

(1) の auth=にはユーザーとパスワードをそれぞれ入れます。
(2) の proxiesはプロキシーの設定です。no_proxyは以下の値からなる辞書で、HTTPとHTTPSのプロキシーを設定します。プロキシーサーバーを使う必要があるときには、この設定を変えてください。
(3) verify=False は証明書の警告を無視する設定です。この設定をしていても以下のメッセージは出ますが、こちらは、urllib3から警告を抑止する設定をしています。

InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)

②データセットの一覧を出力する。

まずはどんなデータセットがあるかを確認する必要があります。データセットの一覧を出力するには、以下の URLを使います。アクションの部分が /api/analytics/v1/datasets と言うことですね。

https://192.168.150.21:215/api/analytics/v1/datasets

このURLをつかって出力すると、以下のような返事が返ってきます。返事はPython の言葉で言うと、辞書の値として、リストが帰ってきていて、リストのそれぞれのの要素が辞書になっている形です。

{ "dataset": [ {dict1}, {dict2}, .... {dictn}] の様なイメージですね。

応答を見てもらうと、"href": という項目があります。これが、次の actionになります。今回は、NFS version 3のコマンド毎の統計情報を見てみましょう。(href": "/api/analytics/v1/datasets/nfs3.ops[op]"より、actionは/api/analytics/v1/datasets/nfs3.ops[op]になります。)

{
"datasets": [
{
"name": "arc.accesses[hit/miss]",
"grouping": "Cache",
"explanation": "ARC accesses per second broken down by hit/miss",
"incore": 649724,
"size": 20304264,
"suspended": false,
"activity": "none",
"overhead": "low",
"since": "Thu Apr 25 2019 03:09:03 GMT+0000 (UTC)",
"last_access": "Thu Apr 25 2019 03:09:02 GMT+0000 (UTC)",
"dataset": "dataset-000",
"href": "/api/analytics/v1/datasets/arc.accesses[hit/miss]"
},
(......)
{
"name": "nfs3.ops",
"grouping": "Protocol",
"explanation": "NFSv3 operations per second",
"incore": 205920,
"size": 4338584,
"suspended": false,
"activity": "none",
"overhead": "low",
"since": "Thu Apr 25 2019 03:09:17 GMT+0000 (UTC)",
"last_access": "Sun Jul 28 2019 04:20:14 GMT+0000 (UTC)",
"dataset": "dataset-026",
"href": "/api/analytics/v1/datasets/nfs3.ops"
},
{
"name": "nfs3.ops[op]",
"grouping": "Protocol",
"explanation": "NFSv3 operations per second broken down by type of operation",
"incore": 212627,
"size": 8420936,
"suspended": false,
"activity": "none",
"overhead": "low",
"since": "Thu Apr 25 2019 03:09:17 GMT+0000 (UTC)",
"last_access": "Wed Aug 21 2019 08:38:03 GMT+0000 (UTC)",
"dataset": "dataset-027",
"href": "/api/analytics/v1/datasets/nfs3.ops[op]"
},
(.....)

③データセットに含まれるデータを読み出す。

データセットに含まれるデータを読み出すには、データセットの URL のあとに、/data とつけます。つまり、私たちの例では、以下のようになります。

https://192.168.150.21:215/api/analytics/v1/datasets/nfs3.ops[op]/data

返答の例は以下の通りです。

{'data': {'data': {'value': 0},
'sample': 426380482,
'samples': 426380483,
'startTime': '20190821T09:05:37'}}

データの形式は、辞書のインデックス 'data' の値として辞書があります。
その値はさらに辞書で、インデックスが 'data' にたいして {'value':0} となっています。他の値の意味することは、以下の通りです。

・データを取り始めた最初の番号 (sample): 426380482
・データの最後の番号 (samples) : 426380483
・データを取り始めた日時 UTC (startTime): 20190821T09:05:37

作業の中で見つかった問題点

(a) 現在のデータをひろってきてしまう

作業の中で見つかったひとつ目の問題点は、何も考えないでアクセスすると、現在の時刻のデータを拾ってきてしまうと言うことです。これを回避するには、paramsという変数を作って例えば、以下のような値を入れます。

params = {
"startTime" : "20190808T00:00:00",
"span" : "day",
"granularity" : "hour"
}

これらの値は、Oracle ZFS Storage Appliance RESTful API Guide, Release OS 8.8.x に記載があります。(Get Dataset Dataの項目を参照)
それぞれ以下の意味です。

startTime:データを参照する最初の日付
span: データを収集する期間  minute, hour, day, week, month, year
granularity:統計情報の細かさ minute, hour, day, week, month, or year

一方で、ZFS Storage には自動的に古いデータを消す機能があります。ですから、消去されていないデータに対してアクセスをする必要があります。

(2) 出力結果に複数パターンがある

Analyticsのデータには複数の出力パターンがあります。端的に言えば、ドリルダウンをしているか以内かで情報が異なります。ここでお話ししている例は、毎秒毎のかつコマンドごとのNFSの統計になります。データがあった場合は、例えば、以下のような応答が帰ってきます。
先ほどの例では、data の値は空だったので、"value":0 でしたが、今回は、ここが辞書になっていて、それぞれの操作 read, getattrなどをインデックスとした辞書の形式で数字が入っています。

(.....)
{'data': {'data': [{'key': 'read', 'max': 578, 'min': 0, 'value': 0},
{'key': 'getattr',
'max': 72,
'min': 0,
'value': 0}],
'max': 699,
'min': 0,
'value': 0},
'sample': 426440359,
'samples': 426443959,
'startTime': '20190822T01:43:32'},
(.....)

複数のフォーマットがあるというのは意外と厄介で、例えば、Pandas の Dataframeに入れようと思ってもそのまま json_normalizeを使うと例えば、以下のような結果になってしまいます。

22 426438231 ... NaN
23 426441831 ... [{'max': 578, 'key': 'read', 'value': 0, 'min'...

このあたり、私の Pandasの理解が足りないのだと思います。

次回はこの最後の問題、複数フォーマットをどう処理するかという話題についてお話ししたいと思います。ここまで読んでくださりありがとうございました。

参考文献

Oracle® ZFS Storage Appliance Analytics ガイド
Oracle® ZFS Storage Appliance RESTful アプリケーションプログラミングインタフェース(日本語版は若干古いです)
Oracle® ZFS Storage Appliance RESTful API Guide, Release OS8.8.x


ご参考

今回の記事を書く際に使ったコードを少し整理して、GitLabに公開してあります。ご参考になれば幸いです。


この記事はここまでです。 最後まで読んでいただいてありがとうございます。 気に入っていただいたなら、スキを押していただいたり、 共有していただけるとうれしいです。 コメントや感想大歓迎です!