mongoDB でのデータの持ち方(構造化、非構造化)について

639 views
Skip to first unread message

Nishimura Ryuichiro

unread,
Jan 5, 2016, 7:13:36 PM1/5/16
to MongoDB JP
いつもお世話になっております。西村です。

今更ながらの基本的な質問ですが、今、以下のような感じのデータを mongoDB に
どんどん蓄積しようとしています。

例)
//Cpu情報
{
"header" : {
    "time" : 1451228400,
    "host" : "tokyo01",
    "core" : 1
},
"data" : [
    {
        "parameter" : "Total%",
        "value" : 10.6
    },
    {
        "parameter" : "User%",
        "value" : 10.4
    },
    {
        "parameter" : "Sys%",
        "value" : 0.2
    },
    ...
]
}


データ量の目安としては、1host について、1日1,500件程度、host数は数千件
を考えています。

data部分について配列としたのは、header部分を共通化することで、蓄積時
のデータ容量を抑えようとしたためです。(特にmongoV2のころ)

実際の処理では、このデータを $unwind して、個別にデータをとったりしている
ので、ばらばらの方がありがたいこともあります。

ここで初歩的な質問になるのですが、皆さんがmongoDBを使ってデータを蓄積
されるとき、どのような観点からデータの形(スキーマレスなのに変な言い方で
すが)を決められているでしょうか。

参考として教えていただきたく。

よろしくお願いします。


Fukuzaki Akinobu

unread,
Jan 5, 2016, 7:20:42 PM1/5/16
to mongo...@googlegroups.com
西村さん、こんにちは。
福崎です。

あくまで私見ですが、私は集計・分析したいデータの形優先でやる派です。

いただいたケースで、もしシステムの長期的な拡張計画のための指標とするならば
Total%の推移がホストごと、全体で欲しいところですので、header、dataと分けずに
{
“time” : 1451228400,
“host” : "tokyo01”,
“core” : 1,
“Total%” : 10.6
}
といったエントリーにしたいところです。
インデクスはhostかなぁ。
Timeは長期にやるならシャーディングで分けますかねぇ。うーーん、悩む。

以上、ご参考までに。

> 2016/01/06 9:13、Nishimura Ryuichiro <nish...@gmail.com> のメール:
> --
> このメールは Google グループのグループ「MongoDB JP」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには mongodb-jp+...@googlegroups.com にメールを送信してください。
> このグループに投稿するには mongo...@googlegroups.com にメールを送信してください。
> https://groups.google.com/group/mongodb-jp からこのグループにアクセスしてください。
> その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

------------------------------------------------------------------
Akki
Akinobu Fukuzaki

Tetsutaro Watanabe

unread,
Jan 5, 2016, 7:25:05 PM1/5/16
to mongo...@googlegroups.com

渡部です。

データの持ち方は、クエリのかけ方から考えるのが良いと思います。

西村さんのデータ構造だと、時間とホストを指定したクエリであれば、一つのjsonを取れば良いため、高速ですし、メモリの使い方も効率的です。
しかし、ある時間の全ホストのuserのCPU使用率を求めようとすると、複数のjsonをとる必要があり低速ですし、メモリにも無駄なデータ(user以外のcpu使用率)がたくさん乗ります。

また、MongoDBはアトミックに更新できる単位はjsonなので、アトミックに更新したい単位でjsonにする必要があると思います。

2016/01/06 9:13 "Nishimura Ryuichiro" <nish...@gmail.com>:

Nishimura Ryuichiro

unread,
Jan 12, 2016, 12:08:18 AM1/12/16
to MongoDB JP
福崎さん

ありがとうございます。

データの目的としては、ホスト毎の時系列データを串刺しにして複数のホストで
比較するためのもの、となります。

時系列+インデックスを張りすぎるとそこがネックになるかも、ということで、今は
タイムにのみインデックスを張っています。

ですが、見たい感じは、指摘してもらっている通りです。

header, data 部に分けていたのは、単にそうすることでデータ部へのアクセスが
早くなる(たしか mongo の本に載ってたような)ということが頭にあったからです。

Total%:10.6 的な持ち方は当初考えていたのですが、何かの条件でこれをやめ
てしまってました。(それが何だったかが今思い出せないのですが。)

意外とこの持ち方に変えても問題なくなったかもしれないので、もう一度検討して
みます。


西村

2016年1月6日水曜日 9時20分42秒 UTC+9 Akki:

Nishimura Ryuichiro

unread,
Jan 12, 2016, 12:12:55 AM1/12/16
to MongoDB JP
渡部さん

ありがとうございます。

クエリ条件としては、時間+ホストが must で、データ毎(Total, User, ...) の方向で考えています。
データは aggregate で持ってきているのですが、確かに、User しか欲しくない時も、全部持ってき
て $unwind なので、余計なデータを引っ張ってきていることにはなってます。
そういう意味で、配列構造にしているところがネックになったかな、という気がしています。


西村

2016年1月6日水曜日 9時25分05秒 UTC+9 Tetsutaro Watanabe:

Hiroaki Kubota

unread,
Jan 12, 2016, 10:04:56 AM1/12/16
to mongo...@googlegroups.com
窪田です。

少しこのデータ構造は疑問です。
例えば、TotalのCPU 90% 超えの時間を抽出したい場合、この構造では、クエリーがかけられないからです。
当然Indexも使えません。

確かに今はある時間範囲だけの話なのかもしれませんが、
私の場合は、データ構造を決定する際に、データを将来的にどう使えるか?の部分も考慮に入れます。

2016年1月12日 14:12 Nishimura Ryuichiro <nish...@gmail.com>:

Nishimura Ryuichiro

unread,
Jan 13, 2016, 8:24:50 PM1/13/16
to MongoDB JP
窪田さん

ありがとうございます。

基本的に、今のシステムでは、時間範囲指定で、そのデータをすべて抽出する
(=>visulal化)という流れのみなのでこのようにしています。
溜まったデータを言われるようなやり方でデータとりたい、という要望が出る
ことも考えると、一考ありです。

ちなみに、福崎さんからのご指摘とも絡んでくるところなのですが、

Total% : 10.6

のような形にしなかった理由として、データによっては、このパラメータ名部分
が固定ではなく未知のケースがあって、たとえばそれを全抽出で aggregate とか
をしようとしたときに、キー名を取得する処理とかが必要になって負荷となるこ
とを避けようと考え、名前部分を一つの括りとした経緯があります。

今回提示した CPU 情報とかについてはパラメータ名は固定なのでそこだけでも
替えてみるのはありかと思ってます。


2016年1月13日水曜日 0時04分56秒 UTC+9 crumbjp:

Hiroaki Kubota

unread,
Jan 14, 2016, 8:07:43 AM1/14/16
to mongo...@googlegroups.com
実は、複数metricを一つのドキュメントに纏めるかどうか?に関しても
僕ならドキュメントを分けます。

が、まあ纏めてもアリはアリだと思うので、もし纏めた場合、僕ならこういうデータ構造にします。


{
"header" : {
    "time" : 1451228400,
    "host" : "tokyo01",
    "core" : 1
},
"data" : {
   "cpu_total": {
        "parameter" : "Total%",
        "value" : 10.6
    },
    "cpu_user": {
        "parameter" : "User%",
        "value" : 10.4
    },
    "cpu_sys": {
        "parameter" : "Sys%",
        "value" : 0.2
    },
  }
}


2016年1月14日 10:24 Nishimura Ryuichiro <nish...@gmail.com>:

Tetsutaro Watanabe

unread,
Jan 14, 2016, 12:58:49 PM1/14/16
to mongo...@googlegroups.com
渡部です。

えっと、これから空気を読めないことを言いますが、念のため言わせてください。

> データの目的としては、ホスト毎の時系列データを串刺しにして複数のホストで
> 比較するためのもの、となります。
>
> 基本的に、今のシステムでは、時間範囲指定で、そのデータをすべて抽出する
> (=>visulal化)という流れのみなのでこのようにしています。
>
> このパラメータ名部分が固定ではなく未知のケースがあって

元も子もないこといいますけど、Elasticsearch+Kibanaじゃだめなんですかね?
JSONいれて、どんなキーが来るかわからないけど時系列でメトリックをvisual化したいって、
それまさにElasticsearch+Kibanaですよね。。。

2016年1月14日 22:07 Hiroaki Kubota <cat.s...@gmail.com>:

Hiroaki Kubota

unread,
Jan 15, 2016, 12:23:04 AM1/15/16
to mongo...@googlegroups.com
用途的にはまさに!だろうね。
ただElasticsearch ってデータ大きくなった時に急激に性能劣化してツラい。
日々の監視や数日分の遡りまでが限界だろう。

あと永続化には向かない。

2016年1月15日 2:58 Tetsutaro Watanabe <fet...@gmail.com>:
このメールは Google グループのグループ「MongoDB JP」の登録者に送られています。

Nishimura Ryuichiro

unread,
Jan 16, 2016, 9:26:41 PM1/16/16
to MongoDB JP
渡部さん、窪田さん

ありがとうございます。

"KY"じゃなく、とても貴重なご意見もらえました。

ちなみに、今私の方で考えているシステムの構成ですが、データソースから
あくまで一時受けの意味で mongo にデータを格納して、それをカラムDBに
整形等しながら入れ込んで、大量データを保存・可視化できるように、とい
う流れをとっています。

全文検索関連については一時期考えていたのですが、棚上げしてました。
どちらかというと、今は、MySQL 5.7 の全文検索で何かできないか、みたい
なことを考え出しています。



2016年1月15日金曜日 14時23分04秒 UTC+9 crumbjp:
Reply all
Reply to author
Forward
0 new messages