モノタロウがGCPで挑戦するデータドリブン ECプラットフォーム

モノタロウがGCPで挑戦するデータドリブン ECプラットフォーム

  • devsumiの記録です

紹介

モノタロウ

  • CM紹介
  • BtoBで関節資材の販売会社
  • モノタロウが入る前は時間と人的コストがかかるものだった
  • 見積もりー>価格交渉と納期確定ー>配送
  • 価格交渉なしで翌日届く ​

    モノタロウの価値

  • 関節資材の調達プロセスをテクノロジーとデータで圧倒的に簡単にする
  • 価格透明性、必要なものを全て、すぐ見つかる買えるを提供する
  • 1800万SKU(ストック・キーピング・ユニット)ー>(単品管理) ​

    データマーケティング

  • 顧客接点でデータを活用
  • 業種別最適化、SEO /SEM、プッシュ型マーケテイィング、特価クーポン ​

    検索最適化一例

  • ユーザの業種で、手袋にしても、医療系か、製造業を絞る
  • 「涙目」ー>業界用語 等の検索結果で商品マスタのない専門ワード業界用語も検索可能にする ​

    エンジニアリングドリブンなカルチャー

  • AI無人店舗を佐賀県でやっている ​

    モノタロウのデータマーケティングの基盤説明

    古いデータ基盤

  • データ基盤の分散
  • オンプレデータ基盤
  • 分析にひつようなデータがそろっていない
  • データが集約されスケールできる基盤がほしかった
  • そこであたらしい基盤 ​

    あたらしい基盤の成果

  • 全てが10倍に。1000テーブル、Biが300レポート、SQL業務利用者人数が50人 ​

    新しい基盤紹介

  • BigQuery RqwData、DWHを活用
  • Oracleから移行-> Digdog,embulk->DWHへ
  • Mysql から移行-> BinlogConnectorでDWHへ
  • BiqQueryにしたのは、圧倒的スケーラビリティ ​

    CDCによるデータ連携

  • 変更情報を取得して、擬似的にSlaveDB作成
  • BinlogConnectorで実現 ​

    BinlogConnector

  • 変更情報ををSchemalizerでDDL作成
  • 変更情報をPubSubni経由でProcesseorにわたしRowDataへ渡した(DML作成) ​

    BinlogConnector

  • データ基盤にできるだけリアルタイムに近いデータ利用のニーズ
  • マスタDBに負荷をかけない ​

    非エンジニアにDB基盤を提供

  • BiqQueryだと業務担当が直接SQLかける
  • 同時にクエリ流してもBiqQueryなら問題ない ​

    どうやってSQL学んだか

  • 定期的に研修
  • もともとクエリを使う非エンジニアがいた
  • Slackのチャンネルで質問答えた
  • アドホックにクエリをなげて活用して慣れた ​

    管理ポイント

  • AuthorizedViewでみせない
  • 秘密情報はマスキング
  • あらゆる人にアドホッックにクリ強化 ​

    ECアプリケーションの活用

  • パーソナライズ化したデータをAPI化して、ECアプリに活用
  • ECアプリのデータ基盤を今後刷新したい ​

    ECアプリの刷新のアーキテグクト

    モノタロウ

  • セッション数千万/月
  • 数十万/月 ​

    ECサイトの構成要素説明

  • 検索が専門用語対応している
  • ただ機能は他のECサイトとほぼ同じ
  • ただ資材の専門知識がいる ​

    今まで

  • 倉庫や部門によって商品在庫の管理がバラバラだった ​

    セキュティ問題

  • Chrome Samesite
  • AppleITp2.1 ​

    コード管理の問題

  • API のエンドポイント増加
  • リクエスト増加
  • APIのコール元の管理が大変
  • そのためスケーラビリティトアジリティーが必要 ​

    モノタロウの

  • SEMとリスティング
  • 業種別リコメンド
  • システム全体像説明 ​

    課題

  • データ活用がしにくい
  • 非対称なアーキテクト
  • データがAwSGCPとオンプレに別れた ​

    READMODELのばらつき

  • DBスキーマ(店舗で在庫データがばらばらとか避けるニーズ)
  • フロントエンド
  • マーケターダッシュボード
  • RESTAPIによる改善をしてきた ​

    REST API化で改善したが

  • 100近いエンドポイントで依存関係がつよくなってきた
  • APIの属人化 ​

    DBスケーラビリティ

  • 商品、価格、納期をJOINしているとDBに負荷かかる
  • そこでインデックス使うと、検索インデックス増加で負荷集中した
  • そこで改善したい ​

    スター型からスパイラル型へ

  • MYSQLに集中した形がスター型でから、GCPを用いたAPIのスパイラル型へ ​

    データ活用をしたリコメンドのために

  • リリスースが用意でスケーラブルなAPI
  • 常に最新データが反映されたストレージ
  • 持続的な成長を支えるインフラ ​

    そのための改善点

  • 既存APIのマイクロサービス化
  • 巨大バッチのイベントドリブン化
  • UXに関わるイベントでビューを逐次更新したい
  • マーケティングもリアルタイム化したい ​

    どうやって実現->CahgeDataCapturerする

  • BinLogとPUBSUBで、MYSQLテーブルデータを、そのままBigTable(KVS)へレプリケート ​

    CDCによるデータパイプライン

  • CloudDataFlowを使ってBigTableへいれる ​

    運用のデータドリブン化

    変化への柔軟な対応のための以下への指標と予測

  • ユーザ数売り上げの伸び
  • 新たな施策やトラフィックの変動 ​

    対策

  • A/Bテスト・カナリアリリースー>SLO/SLIによるデータ・ドリブン運用
  • BigQuery,GKE,Spinnaker,DataDoG,StackDriverを活用

Pyenv Install 2.7でエラー

pyenv install 2.7.Xでエラー

対応

エラーメッセージ

  • pyenv install 2.7.11
BUILD FAILED (OS X 10.14.6 using python-build 20180424)

ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

参考にしたサイト

  • 以下を見たが答えがでずググった
  • コンソールに出たサイトgithub.com

  • 以下をやってもエラーが出てインスールできず

CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib"  pyenv install 2.7.11
  • 以下メッセージ見て、そもそもXcodeないからな気がしたので、Xcodeを入れることにした
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

Xcodeインストール

  • AppleStoreにてXcodeインストール

Pyenvしたら以下を求められ実行

Xcodebuildライセンス受諾 - 以下コマンド実行

sudo xcodebuild -license accept
  • 結果:また同じエラー

環境変数設定

  • ググると以下を実行とのことだが、おそらくXcodeいれているから不要。案の定Alreadyっていわれた
xcode-select --install
  • pyenvする前に以下環境変数設定がいるらしいので実行
CFLAGS="-I$(brew --prefix readline)/include -I$(brew --prefix openssl)/include -I$(xcrun --show-sdk-path)/usr/include" \
LDFLAGS="-L$(brew --prefix readline)/lib -L$(brew --prefix openssl)/lib" \
PYTHON_CONFIGURE_OPTS=--enable-unicode=ucs2
  • また同じエラー

必要なものをインストール

  • ほかにもいりそうなものがありインストール
brew install zlib
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
  • 上記失敗する時/Library/Developer/CommandLineTools/Packages が丸ごと消える事があるそう
  • その場合は Developer サイトから Command Line Tools を D/L してきて、インストール
  • ここからhttps://developer.apple.com/download/more/

  • pip 7.1.2 requires SSL/TLSってでたら以下実行。ただし2行目はすでにやっているな

export CPPFLAGS=-I$(brew --prefix openssl)/include
export LDFLAGS=-L$(brew --prefix openssl)/lib
  • ここまでやったがエラーが取れん
brew install readline

pythonで前月やら今月の末尾初日返す

前月1日を出す

def getLastMonthStartDay():
    # 今日を取得
    today = datetime.datetime.today()
    # 当月1日を出す
    thismonth = datetime.datetime(today.year, today.month, 1)
    # 前月末日を出す
    lastmonth = thismonth + datetime.timedelta(days=-1)
    # 前月1日を出す
    lastmonthFirstday =  datetime.datetime(lastmonth.year, lastmonth.month, 1)
    print(lastmonthFirstday.strftime('%Y-%m-%d'))
    return lastmonthFirstday.strftime('%Y-%m-%d')

来月末日の値を出す

def getNextMonthLastDay():
    # 今日を取得
    today = datetime.datetime.today()
    # 翌々月を出す
    nextmoth = today + relativedelta(months=2)
    # 翌々月1日を出す
    thismonth = datetime.datetime(nextmoth.year, nextmoth.month, 1)
    # 前月末日の値を出す
    lastmonth = thismonth + datetime.timedelta(days=-1)

python3.6インストール

pyenvのインストール

$ brew install pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

pythonインストール

$ pip install locustio
$ pyenv install 3.6.0
$ pyenv global 3.6.0
$ pyenv rehash
$ python --version

Pythonでランダムな日付返す

ランダムな日付年月日をかえす

  • 応用可能
import datetime
import random
from dateutil.relativedelta import relativedelta

def getRandamYmdFrom2019ToNowYear():
    min_year=2019
    dtMax = datetime.datetime.now()
    max_year=int(dtMax.strftime('%Y'))

    start = datetime.datetime(min_year, 1, 1, 00, 00, 00)
    years = max_year - min_year + 1
    end = start + datetime.timedelta(days=365 * years)
    dt = start + (end - start) * random.random()
    print(dt.strftime('%Y-%m-%d'))
    return dt.strftime('%Y-%m-%d')

ランダムな時間を返す

# ランダムな時間を出す
def getRandamTime():
    # 今日を取得
    today = datetime.datetime.today()
    # 0以上24未満のランダムな整数を取得する
    hour = random.randrange(0, 24)
    # 1以上4未満のランダムな整数を取得する
    minutes = random.randrange(1, 4)
    start = datetime.datetime(today.year, today.month, today.day, hour, minutes*15, 00)
    return start.strftime('%H:%M:%S')