ITANDI TECH BLOG

イタンジのスタッフブログです。イベントや技術情報などを発信しています。

AWS Data PipelineとAthenaを使ってお手軽DWHを3分クッキング

横澤です、いつもお世話になっております。

本当は5月に書こうと思っていたネタなのですが、最近は時空の歪みの影響を強く受ける事があり気づいたら6月になってしまいました。

本題です、本エントリではData Pipelineを使ってRDSデータをS3にエクスポートし、去年のre:inventで発表のあったAthenaを使ってDWHっぽいものを作ってみるエントリです。Athenaについては説明記事やチュートリアル記事が沢山あるので気になったらググって見て下さい。Data Pipelineはデータ処理に特化したワークフローエンジンの様なサービスです。名前の通りデータの抽出や加工、集約等についてAWS内部の様々なリソースを活用してワークフローを組み立てる事が出来ます。今回はRDS(MySQL)に入ってるデータをCSVファイルとしてS3に吐き出す部分をData Pipelineで実行し、Athenaで読み込めるようにしてみました。

【最初の1分:ジョブの登録】

RDSからS3にCSVを出力する処理はテンプレートが用意されているので簡単に作成できます。 テンプレートを選択したらDBへの接続情報、バッチスケジュール、S3のバケットを指定すれば初期設定は完了です。

このタイミングで幾つか注意点があります。

  • Athenaは現時点(2017-06-08)ではUSリージョンのみサービス提供となっているので、読み込み先となるS3バケットもUSリージョンに作成する必要があります。

  • Data Pipelineは「DataPipelineDefaultRole」と「DataPipelineDefaultResourceRole」というロールを使うのでこれらにS3やRDSへのアクセス権を付与する必要があります

  • データエクスポートを実行するEC2インスタンスについて、デフォルトだとt1.microが選ばれていますがt系インスタンスVPC上への作成がデフォなので接続先がVPCに置かれていない場合はm系のインスタンスを使うなどの工夫が必要です

【間の1分:ジョブの編集】

登録されたジョブはこのような感じでワークツリーで可視化されます、それぞれのタスクを選択すると右側でconfigを修正する事が出来ます。 RDSでsubnetを設定している場合はEc2Resourceタスクを開いてオプションでsubnet-idを設定しないとconnectionエラーになってしまいます。またEC2からRDSへ上手く接続出来ない時にはデバッグ目的でEC2にsshで入りたくなる事もあるのでキーペアも登録しておくと後々幸せになれるかもです。

【最後の1分:Athenaでクエリ発行】

これでジョブは登録されたのでスケジュールをon-demandに設定してactivateするとワークフローが実行され、成功するとS3にCSVが吐き出されます。ワークフローエンジンらしく各ジョブはこんな感じで結果成否やログが見れるのでハマった時も修正がかけやすいです。 最後にAthenaのQueryEditorを使ってHiveQL形式のCREATE TABLE文を発行すればDWHっぽいテーブルの完成です!一点ハマったポイントとしてLOCATIONは「s3://[バケット名]/[パス名]」と指定しなければならず、当初はリージョンURLを含めて指定していたせいでエラーが起きてました・・・

以上で3分クッキングは完了です、実際にはもっと時間かかりましたが本記事を読んで頂く事で3分くらいで作れるようになると嬉しい限りです。そしてここまで書いておいてなんですが、イタンジではDWHっぽい事を実現するツールとしてはGoogle Big Queryを使っており、最近はDigdagというワークフローエンジン経由でembulkを動作させてData Pipelineと似たような事をやっています。なので今回はあくまでもData PipelineとAthenaを実験する目的でやってみた的なネタなので実運用するとどうなるかは未知数だったりします。

イタンジ株式会社ではこのようなデータエンジニアリングにテンションが上がるエンジニアや、集約管理されたデータを使って探索的にデータ解析したいエンジニアを募集しております。

railsのactive jobでGoole Cloudのpub/subを使う

こんばんは、エンジニアの福崎です。 最近仕事でGCPを使ってます、AWSに比べて情報は少ないけど意外にドキュメント揃っているので ドキュメント読めば簡単なチュートリアルは動かせちゃいます。 まだネットに情報少ないので個人的には公式ドキュメントを読み漁るのが一番早かったです。 今日はrailsのactive jobでGAEのpub/subを使ってみたのでメモがてらブログに残します。

Pub/Subを使った背景

active job最初はいつもどおりsidekiqでやろうとしたんですがGCPにはフルマネージドなredisが無いみたいなので 自分でサーバー立てて管理するのはちょっと。。と思っていたらPub/Subに行き着きました。

Pub/Subとは

Cloud Pub/Sub はフルマネージドのリアルタイム メッセージング サービスで、個別のアプリケーション間でメッセージを送受信できます。

今回はこちらのメッセージングサービスにjobをキューイングしていきworkerでpullして処理します。

日本語チュートリアルもあるので読んでおくと良いと思います。

たこの内容はこちらの公式ドキュメントをベースにした内容になってます。

完成物

ここに置いてます。

前準備

pub/subを有効にする

GCPで新しいプロジェクトを作ってpub/subをapi managerから有効にしておいてください。(デフォが無効になってます)

rails環境の準備

今回はrails 5.1でやってます

認証ファイルの取得

GCPにログインして「API Manager」→「認証情報」→「認証情報を作成」→「サービスアカウントキー」→「GAEと選択」→「jsonを選択」→「作成」保存したjsonファイルを /config/pub-sub-sample-auth.jsonに設置してください。

project idの記述

/config/settings.ymlを作りproject_idにGCPのproject idを入れてください。

development:
  project_id: <your project_id>
  auth_file: pub-sub-sample-auth.json

実装

gemを入れる

Gem Fileにpub/sub用のgemを定義してbundleで入れておきます。

gem 'google-cloud-pubsub'

APIドキュメントがあるので目を通しておくと良いです。

application.rbの設定

/config/application.rbに以下の定義を追記します

# 今回作るadapterを使うよう定義します
config.active_job.queue_adapter = :pub_sub_queue
# libの下にadapterとか置くのでautoloadの対象にしておきます
config.autoload_paths << Rails.root.join('lib')
# GCP周りの設定をsettingファイルに定義するので
config.x.settings = Rails.application.config_for(:settings)
# GCPにログ吐くようにします
if Dir.exist?('/var/log/app_engine/custom_logs')
  config.logger = ActiveSupport::TaggedLogging.new Logger.new('/var/log/app_engine/custom_logs/application.log')
end

adapterの定義

今回の本丸です。 /lib/active_job/queue_adapters/pub_sub_queue_adapter.rbを以下の内容で作成します。

require 'json'
require 'google/cloud/pubsub'

module ActiveJob
  module QueueAdapters
    class PubSubQueueAdapter

      def enqueue(job)
        Rails.logger.info "[PubSubQueueAdapter] enqueue job #{job.inspect}"

        topic = PubSubQueueAdapter.pubsub.topic(job.queue_name, autocreate: true)

        topic.publish(job.class.name, arg: job.arguments)
      end

      class << self
        def pubsub
          @pubsub ||= begin
            project_id = Rails.application.config.x.settings['project_id']
            Google::Cloud::Pubsub.new(
              project: project_id,
              keyfile: "#{Rails.root.join('config')}/#{Rails.application.config.x.settings['auth_file']}"
            )
          end
        end

        def run_worker!(queue_name = 'default')
          p 'Running worker'

          topic        = pubsub.topic(queue_name, autocreate: true)
          subscription = topic.subscription("#{queue_name}_task")

          topic.subscribe("#{queue_name}_task") if subscription.blank?

          subscription.listen(autoack: true) do |message|
            message.data.constantize.send(:perform_now, *JSON.parse(message.attributes['arg']))
          end
        end
      end
    end
  end
end

workerタスクの作成

後はいつもどおりjobを定義します。 app/jobs/sample_job.rb

class SampleJob < ApplicationJob
  queue_as :default
  def perform(num)
    p '==================='
    p "#{num} sample job executed!"
    p '==================='
  end
end

そしてjobを発行するrakeタスクを用意 lib/tasks/sample_job.rake

desc 'issue job'
task issue_job: :environment do
  (1..5).each do |num|
    SampleJob.perform_later(num)
  end
end

早速キューイングしてみましょう

bundle exec rake issue_job

最後にworkerを起動するとキューイングしたjobが処理されていくのを見ることが出来ます

bundle exec rake run_worker

まとめ

いかがでしたか? sidekiq程高機能ではないので時間を指定しての実行などは出来ませんが 単純にworkerの機能がほしいのであればこれでも十分です。 GCPを使う際はpub/subを是非使ってみて下さい!

今回はlocalで動かしたので次回はこれをGAEにdeployする方法を書きたいと思います

WebpackをRailsに導入する方法を比較する: 後編

9a5b0608-318e-5e20-110c-d98fa941d784

こんにちは、エンジニアのケントです。

前編の解説により、webpackerが提供する方法論は

  • js環境構築がとても楽である
  • webpackerが提供する環境に開発がロックインされる

ということがわかりました。

後半ではWebpackとRailsを独立して使う方法を解説し、rubygemのWebpackerを使う方法との比較をしようかと思います。

WebpackとRailsを独立して使う

この方法を実装するにあたってはCookpadさんのブログを参考にさせていただきました。

まず、ルートディレクトリに frontend というディレクトリを作ります。

├── app
│   └── assets
│
├── lib
│   └── tasks
│
└── frontend

そして

├── app
│   └── assets
│
├── lib
│   └── tasks
│
├── frontend
│   ├── src
│   ├── .babelrc
│   ├── .eslintrc
│   ├── package.json
│   ├── webpack.config.js
│   ├── webpack.config.prod.js
│   └── yarn.lock

このように frontend ディレクトリにwebpackの開発に必要なコードを全て詰め込み、frontend/src ディレクトリに主なソースコードを書くスタイルです。

webpackerでは開発環境を定義するファイルが自動生成されましたが、今回の場合は開発環境を定義するファイルを .babelrc .eslintrc webpack.config.js webpack.config.prod.js などといったファイル群によしなに自作していく必要があります。

また、frontend ディレクトリにwebpackによるjsの環境を詰め込んだので、Railsのルートディレクトリからwebpackを起動するコマンドを用意したくなります。なので

├── app
│   └── assets
│
├── lib
│   └── tasks
│       └── webpack.rake
│
├── frontend

といったrakeコマンドを lib/tasks ディレクトリに追加してあげましょう コマンドの中身は

namespace :webpack do
  task build: :environment do
    begin
      result = exec('cd frontend && yarn run build')
    rescue
      print result
    end
  end
end

といった感じです。必要に応じてコマンドはよしなに生やしてください。

そして、最後にwebpackによる成果物の配信先を作る必要があります。

├── app
│   └── assets
│       └── javascripts
│           └── frontends
│
├── lib
│   └── tasks
│       └── webpack.rake
│
├── frontend

配信後は javascript_include_tag で任意のファイルを読み込んでください。

webpackでファイル圧縮をするのでアセットパイプラインは必要ないかもしれませんが、必要が生じた場合はマニフェストファイルも app/assets/javascripts の下に置きましょう。

あとは rails srake webpack:build コマンドをそれぞれ別コンソールから打てば開発をスタートすることができます。

必要に応じて webpack-dev-server をrakeコマンドから叩いてもいいですし、別々のコンソールを開くのが面倒な場合は foreman の導入も検討してください。

デプロイする場合は、capistrano

task :build do
  yarnでnode_modulesを作るコマンド
  webpackのコマンド
end

Rake::Task["assets:precompile"].enhance(%i(build))

と追記しておけば、precompile時にwebpackのコマンドをhookできます。 (この部分はこの方の記事を参考にしました)

環境によってはyarnが環境変数をうまく読んでくれないことがあるので、その場合は上記のコマンドに

'export NODENV_ROOT="nodenvの位置"',
'export NODENV_VERSION="nodeのバージョン"',
'export PATH="$NODENV_ROOT/bin:$PATH"',
'eval "$(nodenv init -)"',
'export PATH="$PATH:$(yarn global bin)"',

と行った環境変数を読むコマンドを泥臭く追記してください。

まとめ

Webpackerを使う方法とWebpackとRails別にする方法の pros & cons をまとめると

  • Webpacker
    • pros
      • 全自動でWebpack環境が作られる。今現在Webpackの知識が少なくても始められる
    • cons
      • Webpackerのレールから外れたくなると相当のWebpackの専門知識と覚悟が必要とされる
  • WebpackとRailsを独立して使う
    • pros
      • 自分のWebpackの知識の範囲内で環境を作れるので、後々のメンテナンスが楽になる
    • cons
      • 最初の段階でWebpackの知識がそれなりに要求される

といった印象でした。

WebpackをRailsのプロダクトに組み込みたい人の判断の助けになれば幸いです。

WebpackをRailsに導入する方法を比較する: 前編

Unknown

こんにちは、エンジニアのケントです。

2017年のフロントエンドの開発において、Webpackが大人気です。

イタンジのプロダクトはRailsで開発することが多いのですが、WebpackをRailsに導入することを考える場合、大きく分けて二つの選択肢が考えられます。

  • rubygemのWebpackerを使う
  • WebpackとRailsを独立して使う

直近で二つのイタンジのRailsプロダクトにWebpackを組み込むお仕事をし、上記の両方を試してみたので、それぞれの導入方法と雑感、pros and consをまとめてみようと思います。

rubygem webpackerを使う

導入方法

webpackerは、Rails5.1から標準で導入されるwebpackのラッパーです。 導入方法はwebpackerのreadmeにだいたい載ってるので、詳細はそちらにお任せしますが、結論だけ説明すると

  1. gem 'webpacker', github: 'rails/webpacker' をgemfileに追記する
  2. bundle install する
  3. bin/rails webpacker:install コマンドを打つ

たったこれだけでwebpackによる開発をスタートすることができます。

webpacker導入後、Railsディレクトリ構成が変わりますが、ざっくりいうと以下のような構成が追加されます。

├── app
│      └── javascript --①
├── config
│      └── webpack   --②
├── public
│      └── packs        --③

webpackerでは、①で主なソースコードを書き、②で開発環境を定義し、③に開発の成果物を配信する形になります。

雑感

しかし、この②の部分がなかなかの曲者でして、なかなか複雑なディレクトリ構成となっています。

├── config
│      └── webpack --②
│               ├── configuration.js
│               ├── development.js
│               ├── development.server.js
│               ├── development.server.yml
│               ├── loaders
│               │         ├── assets.js
│               │         ├── babel.js
│               │       ├── coffee.js
│               │        ├── erb.js
│               │         ├── react.js
│               │         └── sass.js
│               ├── paths.yml
│               ├── production.js
│               ├── shared.js
│               └── test.js

このように開発環境を定義するファイルが乱立しているため、より込み入ったフロントエンドの開発をしたくなったタイミング等で開発環境を変更しようとした際に苦労する印象です。

(後編で解説しますが、単純にWebpackによるjs開発環境を用意するだけならこのような複雑な構成にはなりません。) とはいえモダンなjs開発環境をgemを入れてコマンドを打つだけで用意できるのは大変素晴らしいと思いました。

後編はWebpackとRailsを独立して使う方法を解説し、rubygemのWebpackerを使う方法との比較をしようかと思います。

「AIは不動産業界の敵か味方か?」不動産テック最新事例セミナーVol.1を開催しました!

現在、「フィンテック」(金融×IT)の次は「不動産テック」と言われるなど、ビッグデータ解析、AI(人工知能)などを活用し不動産業界にイノベーションを起こそうとする「不動産テック」に対して、注目が集まっています。当社は、今後ますます不動産業界のIT活用が進み、業界全体が発展することを目的として、不動産仲介会社、不動産管理会社を対象とした「不動産テック」に関するセミナーを開催することとなりました。参加者の皆さまに、身近でリアルな事例を知ってもらいたいという思いのもと、記念すべき第1回には、株式会社S-FIT代表取締役社長、紫原 友規様にお越しいただきました。

その一部をご紹介します。

はじめてAIと出会ったのは10年ぐらい前、23歳の時だった?

 まずはじめに、代表の伊藤が登壇し、自身がAI(人工知能)に関心を抱いたきっかけについて語りました。 「10年ぐらい前、当時23歳だった私は、三井不動産レジデンシャルリースに勤めていました。当時は社内でもエクセルが得意な方だったということもあり、自分でマクロを組んで賃料査定をしていました。現在のテクノロジーとは全然レベルが違いますが、その頃から『こういった作業を人ではなく機械が出来るようになれば、効率化出来ることがたくさんあるのでは?』と感じていました。今では実際にAI技術が具体的に活用され効率化が進んでおりますが、当時から必ずしも人が作業をする必要なく、機械で効率化出来ることを考えていましたね。その後、仲介会社を立ち上げる中で再度、『物件の入力などがもし機械によって自動的になったら、不動産取引がもっと円滑になるのではないか』と思いました。これらの経験が、イタンジを立ち上げるきっかけにもなりました。」

 その後は国内外の不動産テックの事例について、自社サービスのデモも含めて紹介をしました。  「今は不動産取引のデータをクラウド上に蓄積する時代。そのデータを活用することでさまざまなことが自動化される、つまりAIが本当に活躍する時代が来る」という話で締めくくりました。

不動産テック勉強会伊藤

集客専門チームを作ることで1人あたり月間300反響の対応が可能に!

続いて、S-FIT代表の紫原様から「IT戦略や働き方改革」についてお話いただきました。「お陰さまでS-FITの業績は好調です。売上は14年連続で増収しております。このような状況でも課題なのは、優秀な人材を確保すること。どうずれば人を増やさずに業績を伸ばせるのか?悩んだ末の答えが仲介で一番大変な集客を営業から切り離す分業化スタイルでした。この時期にイタンジと出会い、そこにAIを導入することで、多い時では一人で月間300反響の対応が可能になりました。」 「現状はまだ、どこをAIでやるのかはっきりしていない。でも、本当に正社員がやるべきなのか?、パートに任せるのか?、それともAIなのかを考えるようにしている」等、興味深いお話をしていただきました。

不動産テック勉強会紫原様

AIにさせたい業務とは?将来どのような業務がAIに置き換わるのか?

 パネルディスカッションでは、「AIにさせたい業務とは?将来どのような業務がAIに置き換わるのか?」等の質問がなされました。伊藤は「身体を使うこと、課題発見以外はAIにやらせたい。特に管理の領域はデータが豊富なので、家賃査定、入居者の審査、入居者とのコミュニケーション等、可能性が非常にある。」等と答えました。  対して紫原様からは、「今でも、クロージングに遠いものはAIでもできる。繁忙期の業務量、残業減らすのに役立っている。でも最終意思決定に関わるものはやっぱり人。」等のお話をしていただきました。  その他、「今後、業界で活躍するのはどのような人材か?」、「システムを自社で持つべきか」等の質問に対して、非常に活発な議論が交わされました。

不動産テック勉強会

最後は、参加企業者の方々と懇親会を開催しました。ビールを飲みながら、今後の不動産業界の未来について、熱く語り合いました。

これからも「不動産テック最新事例セミナー」を定期的に開催していきます!

次回は4月25日(火)です!不動産会社の皆さまのご参加を心からお待ちしています!申込は、下記のページからお願いいたします。

http://www.itandi.co.jp/seminers

機械学習エンジニア育成プログラムを外部にも公開しました

こんにちは、エンジニアの建三です。

前回のブログ機械学習エンジニア社内育成プログラム(MLTP)のお話をしました。開始から一ヶ月程経ち、大分コンテンツが溜まってきました。社内のエンジニアからも分かり易いと好評です。

そこで今回MLTPを外部にも公開することにしました

僕が機械学習を勉強していた時はとても苦労しました。何故苦労したかというと、世に出てる機械学習のコースや本は大抵理論的過ぎるか理論を飛ばしています。

大学で使うような教科書は大まかなコンセプトを理解するには良いんですが、大抵数式で説明されているので、僕のように数式だけでなくコードを読んでアルゴリズムを理解するような人には中々辛いです。

逆に実践書だと理論をすっ飛ばしてコードを書くので、理解出来ないまま終わることが多いです。

MLTPは理論を数式で説明するだけでなく、コードを書きます。しかもただコードをコピペするのではなく問題形式になっているので理解が深まります。答えがちゃんと載っているので、もしつまづいても問題ありません。

研究者を目指すほどではないがある程度の理論は知っておきたいという方にオススメです。

もしやってみて質問やフィードバック等ありましたらgitterまでお願いします。

全エンジニアに機械学習のスキルを

IMG_9481

こんにちは、エンジニアの建三です。

イタンジでは先週MLTP(Machine Learning engineer Training Program)なるものを始めました。これは何かというと、イタンジの全エンジニアに機械学習のスキルを身に付けてもらおうという試みです。

これには主に3つの理由ががあります。

1 - イタンジのエンジニアリング力の強化

Googleは全エンジニアが機械学習をある程度知ってる状態にしたいと宣言しています。どんなエンジニアでもRailsなどでWeb開発がある程度出来るのが必須なのと同じで、どんなエンジニアでも機械学習をそれなりに知っているのが普通という時代があと数年で来ると思います。

2 - 機械学習研究者/エンジニアは中々見つからない

最近こそエンジニアのための機械学習入門的なブログ/オンラインコース/本が出てき始めましたが、まだまだWeb Developerに比べて機械学習エンジニアは圧倒的に少なく採用が大変です。

更に、機械学習を効果的に使うにはその会社のビジネスと既存のシステムを理解している必要があり、機械学習エンジニアを雇ってから会社に貢献出来るようになるまである程度時間がかかります。

既存のエンジニアは既にそれらを理解しているため、後は機械学習を学べばすぐ会社に貢献出来ると考えています。

3 - 自分を置き換えられる存在にする

強い組織というのは誰が突然抜けても問題なくやっていける組織だと思います。その為には自分にしか知らないこと・出来ないことを徹底的になくす必要があります。

自分にしか出来ないことはある意味会社での自分の存在価値のようなものなので、それを守ろうとする人がいるかもしれません。しかし知識や情報は与えて減るものではないので、必死にそれを守るメリットはありません。

プログラムの内容

僕はnumpyで機械学習アルゴリズムを一から書くことのが一番機械学習の勉強になりました。なのでこのプログラムでも実際にアルゴリズムを書くことによって学ぶことを重点に置いています。 更に、イタンジで実際に使われてる機械学習のモデルを使い、実践で機械学習を使うためのスキルやノウハウを勉強します。

まだ始まったばかりなので今後変わるとは思いますが、以下の内容を網羅する予定です。

1 Traditional Machine Learning

numpyを使ってmini scikit-learn libraryを作ります。 色んなアルゴリズムを勉強してく中で同時に機械学習の基本的なコンセプトを身に付けます。

  1. Supervised Learning
  • K nearest Neighbors
  • Naive Bayes
  1. Unsupervised Learning
  • K means clustering

2 Deep Learningを学ぶ為の基礎

numpyを使ってmini kears libraryを作ります。

  1. Linear Regression
  2. Logistic Regression
  3. Feed Forward Neural Network(Back Propagation)

3 Deep Learning

PyTorchを使います。

  1. Recurrent Neural Network
  2. Convolutional Neural Network

第一回目の様子

先週に第一回が行われ、3種類の機械学習の説明(教師あり学習、教師なし学習、強化学習)とK-Nearest Neighbors(k-NN)の説明をしました。

レクチャーではk-NNのアルゴリズムを手で計算しました。

IMG_9490

IMG_9491

宿題では実際にk-NNをnumpyで書きます。Python機械学習の知識は人により差はありますが、全員コンプリートしたようです。

今後の展望

第一回目のレクチャーはライブで行いましたが、2回目以降はスクリーンキャストを作って各自のペースで進めてもらう予定です。エンジニアの中でも営業を兼任してる者が何人かいるので、勤務時間内と言えども全員揃うのは難しいです。更に今後入社するエンジニアにも使ってほしいので、使い回しが出来るものの方が良いと思っています。

上記のプログラムをこなすのに大体3ヶ月くらいかかりそうですが、もしこの取り組みが上手くいったら外部にも公開する予定です。