Hadoopを使ってEveOnlineのマーケットデータを解析してみた

Hadoop-Job1
Hadoop

最初からこれがやりたかったのだがなんだかんだでHadoopのインストールに手間取ってしまった。

EveOnlineというオンラインゲームではEve-Centralで日々のマーケットデータを出力している。これをなんとかして解析してどこで何が売れるのかが分かれば儲かるんじゃないか?という思いからHadoopをはじめてみました。

以前MongoDBを使ってやってみたときプログラムの作り方が悪いのか1日分解析するにはかなり時間がかかった(1時間くらいして終わらなそうだったんで止めたのでどのくらいかかるかわからなかったが)

1日あたり2Gのファイルなのでそれなりに時間がかかるだろうし、Hadoopだったら処理する台数増やせば早くなるのでかなり早く解析できるんじゃないだろうか。

 

今回はようやくそれをやってみようと思う。

 

マーケットデータについて

まずはEve-Centralが出力するCsv Daily Market Dumpsの中身についてみてみる。

orderidregionidsystemidstationidtypeidbidpriceminvolumevolremainvolenterissueddurationrangereportedbyreportedtime
3370586756100000433001348960015021447099997.77137472014-01-16 12:27:1690 days, 0:00:003276702014-02-03 02:09:47.146754
3370586756100000433001348960015021447099997.77137472014-01-16 12:27:1690 days, 0:00:003276702014-02-03 01:13:32.762434
3367478423100000433001348960015021370194.991111933212656782014-01-14 05:49:4090 days, 0:00:003276702014-02-03 23:58:17.077872
3367478423100000433001348960015021370194.991112082712656782014-01-14 05:49:4090 days, 0:00:003276702014-02-03 23:37:40.658216
3367478423100000433001348960015021370194.991112082712656782014-01-14 05:49:4090 days, 0:00:003276702014-02-03 23:36:40.249476
3367478423100000433001348960015021370194.991112082812656782014-01-14 05:49:4090 days, 0:00:003276702014-02-03 23:28:34.270795
3367478423100000433001348960015021370194.991112082812656782014-01-14 05:49:4090 days, 0:00:003276702014-02-03 23:27:50.757008

一部抜粋してみた。

これをみていると次の事が分かる。

orderid : 3367478423 をみてみるとreportedtime 2014-02-03 23:27:50.757008 と2014-02-03 23:58:17.077872でvolremain(在庫数)が異なる

この差をみるとこの間に1496個差がある。

つまりは、30分あまりでtypeid:37(typeidはアイテム番号)がstationid:60015021(これどこのステーションだろ)で1496個売れた事がみえてくる。

こんな感じで解析していけばどこで何がうれたのかわかります。(実際のEveonline上のデータではないので正確なのはわからないが、なんとなくはつかめるはず)

 

また、ordered:3370586756は報告日時が2014-02-03 02:09:47.146754で終わっているが、上記のデータから23時58分に同じステーションで報告があるのに、このオーダはないことから次のどちらかに当てはまる。

  1. 完売した
  2. 有効期限切れ
  3. オーダを取り消した

有効期限切れについてはissuedとdurationから判断できるが完売とオーダを取り消したはどっちかわからない。今回解析するときは完売と楽観的に判断して作る事にする。なお、楽観的すぎるので絶対に売れた一覧と売れたんじゃないか?一覧の2種類を出力しておくことにする。後者は正確性に欠けるが完売するものって結構あると思うので出さないのはもったいないので一応出力する。

ちなみに売った瞬間に売れたものについてはレポートにもあがってこないので解析できない。まあすぐ売れるってことは値段が安いってことだからあんまり儲からないだろうし気にしない事にする。

 

作成ジョブ

1.マーケットデータを複数行から1行にまとめる。(この後解析するための前準備)

Hadoop-Job1

2.各ステーションの最終報告時刻を求める。
Hadoop-Job2

3. 整形済みマーケットデータ(1)と最終報告時刻(2)のデータをもとに各solarsystem毎でアイテム別の売れた数、売れた数の合計金額を求める。
Hadoop-Job3

3-補足.
mapの部分がほかのジョブより処理をやってるのでここについて、詳細イメージを載せておく。
Hadoop-Job3_Detail

完売、有効期限切れ、売れなかった それぞれについてマップタスク中で次のログを吐くようにしてみました。
(性能的にはよくないが、まあデバッグ用に)
order_not_sold_out : 3399075345
order_not_sold_out : 3399075744
order_sold_out : 3399075827
order_not_sold_out : 3399075833
order_sold_out : 3399075858
order_sold_out : 3399076213
order_expired : 3399076217 expire: 1391386080000 reporttime: 1391386209000 issued: 1391299680000 duration: 1 tmp86400000
order_not_sold_out : 3399076746
order_not_sold_out : 3399076981
order_not_sold_out : 3399076988
order_sold_out : 3399077248
order_not_sold_out : 3399077301
order_sold_out : 3399077469
order_sold_out : 3399077472
order_not_sold_out : 3399077916
order_expired : 3399077929 expire: 1391386156000 reporttime: 1391385404000 issued: 1391299756000 duration: 1 tmp86400000
order_sold_out : 3399078019
order_not_sold_out : 3399078039
order_not_sold_out : 3399078413
order_not_sold_out : 3399078457
吐いたログから売れなかった数、完売数、有効期限切れの個数を数えてみたのが下記。
root@hadoop-dev:/data/1/mapred/local/userlogs/job_201405112246_0014/attempt_201405112246_0014_m_000004_0# cat stdout | grep -c order_not_sold_out
18833
root@hadoop-dev:/data/1/mapred/local/userlogs/job_201405112246_0014/attempt_201405112246_0014_m_000004_0# cat stdout | grep -c order_sold_out
36836
root@hadoop-dev:/data/1/mapred/local/userlogs/job_201405112246_0014/attempt_201405112246_0014_m_000004_0# cat stdout | grep -c expire
1184
root@hadoop-dev:/data/1/mapred/local/userlogs/job_201405112246_0014/attempt_201405112246_0014_m_000004_0#

これを見てみると、

  • 売れなかった数:18833
  • 完売数:36836
  • 有効期限切れ:1184

ってことで完売した数が売れなかった数の2倍くらい。有効期限切れもまあまあある感じですね。なお、マップタスクは何個か動いていて、これはそのうちの一つであることに注意。これでもなんとなく割合を感じることができると思います。また、完売数の中には取り消しも含まれちゃってるので正確な数ではない。(実は取り消しが半分以上占めてたら。。。。なんか完売数多すぎる気がするしね)

 

結果

量があるのでダウンロードしてみてください。解析データは2014-02-03となります。

解析してみた結果

完売を楽観的に判断した結果: 完売あり シート

絶対売れたと思われるものだけを集計した結果:完売なし シート

 

結果は各typeidとかを名前でみられるように加工してます。ここらへんは、そのうちcsvファイルを読み込んでweb画面からみられるようにしようかな。

 

まとめ

今回は各ソーラシステムごとの品目別売り上げ数、売上合計金額を出力してみました。大体私のPC(VM上で実行(メモリ:10240MB,プロセッサー:4) )では15分程度で一通りのジョブ実行ができました。MongoDb使った時より圧倒的にはやい!!

もっと早くしたければ処理PC台数増やせばいいので、過去1年分とかの解析も夢じゃないですね。

今回の方法以外にもたとえばsellorder じゃなくてbuyorderを解析してみて、どこで何が需要あるかとかもわかりそうですね。あとは複数日解析してみることで、たまたま1日だけ需要あったのか、継続的に需要があるところなのかといったこともわかってくるのではないかと思います。

Hadoopはインストールはちょっと手間取りましたが、プログラム作成はそんな時間かからなかったです。Hadoop初心者でもここまでできたのはやはり時代ですかね。いや~夢が広がります。

 

最後に今回作ったプログラムをGitHubにあげましたのでそのURLを

EveMarketJob

 

コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

AWS
Docker
ECS+ALBの動的ポートマッピングでダウンタイムのないデプロイを試してみた

はじめに 少し前に個人で作成しているWebサービスのインフラにDockerを使い始めました。 複数台 …

スクリーンショット 2016-01-09 20.02.08
Ruby on Rails
Capistrano3を利用してBitbucketプライベートリポジトリにあるRailsアプリをデプロイしてみた

Railsアプリを配置する際、毎回手作業で頑張って配置してきたが、そろそろ自動デプロイを・・・ とい …

MarketTreeViewのイメージ
Ruby on Rails
[Eve Online 3rd party app] Market Tree Viewの実装 [EOPES制作記]

Eve Online 3rd party app のEOPES を作り始めてから約3ヶ月が経ちました …