社内で開発したAI技術を全社員に知ってもらうために

f:id:tstomoki:20190426105318p:plain

こんにちは。 株式会社バンクのデータ解析チームの齋藤 (id:tstomoki) です。

バンクにおけるデータ解析チームとは

まず、「データ解析チーム」って何をしているのかという話ですが、 基本的にバンクのプロダクト全てに関して下記を行っております。

  • 様々な判断や意思決定をデータや数値を使ってサポート
  • 課題に対してのデータ分析と問題解決のための予測モデルを構築, etc.

大企業におけるAIチームとBIチームとインフラチームなどで分担しているような業務を全てまとめて行っているのがこのデータ解析チームです。

※ Artificial Intelligence: 機械学習技術を用いたサービス改善
※ Business Intelligence: データ分析の結果を用いた意思決定のサポート

これまでどんなものを作ってきたのか

そんなデータ解析チームでは CASHTRAVEL Now で使用できるように、機械学習モデルを解析APIとして作成しています。

また、プレスリリースにもあるように、NVIDIA Inceptionプログラムの日本パートナーにも認定していただき、オンプレミスなGPU環境などを使用して、CASHの商品画像やサービスのユーザ情報を入力とした大規模なネットワークモデルなどの構築を行えるようになりました。

prtimes.jp

例えばその中の1つとして、「ブランドタグ分類API」というAPIがあります。

f:id:tstomoki:20190426105428p:plain

CASHでは、一部のブランドについてはアイテム全体の写真に加えてこちらのようなタグの写真も送ってもらえるような仕組みになっています。

※ 本ブログ内のアイテム画像は社内で撮影

f:id:tstomoki:20190425174240p:plain

このようなブランドタグの写真を入力に

画像のブランドタグが申請通りのブランドなのか

というような推定を行い、未然に虚偽申請を防ぐことでアイテムの査定などに活かしています。

社内でプロダクトを知ってもらうために

先日、弊社代表の光本がTwitterでもつぶやきましたが、これまでにデータ解析チームが作成し・サービス導入したAPIもかなり多くなってきております。

このようなAPIは、サービスでの問題ベースで開発が進められることが多いです。 ですが、学会等で発表された最新技術をベースに「なんとなく使えそうだな」というようにテクノロジードリブンでAPIの開発が行われる場合があります。

そのようなAPIは、我々からサービス側に働きかけないとAPIが存在することすら認知されないので、先述のツイートにもあったようにAPI一覧ページを全社に公開して呼びかけています。

f:id:tstomoki:20190426105733p:plain

また、一覧から対象のAPIを選択すると以下のように実際のレスポンスも確認することができるため、手軽にテストしてもらうことで、サービス導入のアイディアなどを膨らませてもらうこともできます。

f:id:tstomoki:20190425174355p:plain f:id:tstomoki:20190425174411p:plain

実際にアプリ側のエンジニアに導入を依頼する際にも、(もちろんAPI仕様書等は作成しますが)こちらのページを参照することで、説明もしやすくなるのでおすすめです。

まとめ

今回はデータ解析チームから初の投稿ということで、

  • データ解析チームがどのようなチームなのか
  • 社内でどのような工夫をしているのか

について記載させていただきました。

まだまだ少人数で未熟なチームではありますが、今後ともサービスをより便利に使いやすくするために取り組んでいきます。

bank.co.jp

次回はデータ解析チームのメンバーが2019年度 人工知能学会全国大会 (第33回)を聴講予定なのでそちらについての記事を書きたいと思っております。

www.ai-gakkai.or.jp

オフィスネットワークを刷新し、Cisco Merakiを導入しました。

オフィスの柱に設置されたMeraki AP

今回する話

みなさんこんにちは。株式会社バンクの うなすけ (id:yu_suke1994 )と id:HolyGrail です。 先日、オフィスのネットワークを刷新し、Cisco Merakiを導入しました。

今回は

  • オフィス人数と社内ネットワークの変遷
  • 機材とサービス選定の話
  • 自前でセットアップを行った話

について弊社における事例を紹介いたします。

オフィス人数と社内ネットワークの変遷

さて、我々のようなベンチャー企業だと、創業期は家庭用のWi-Fiルーターでも業務が滞りなく行えます。しかし、10人、20人と従業員が増えるにつれ、家庭用のWi-Fiルーターから、SOHOや業務用のルーターや無線アクセスポイント(以下、無線AP)を導入しないとインターネットが詰まったり、色々な問題が発生します。 そして、人員の増加に伴う移転のタイミングで専門の業者に社内ネットワーク環境の構築を依頼するというケースが多いかと思われます。

弊社の場合

弊社は、現住所に移転するタイミングで無線APを3つに増設しました。業者に構築もお願いし、従業員と来訪者とでSSIDの分割とVLANへの収容、VLAN間での通信の遮断などの基本的なネットワークの設定を行いました。

しかし、ワイヤレスLANコントローラの導入には至らず、各自が自席から一番近い無線APのSSIDを選択して接続するという、前時代的な運用を要求せざるを得ない状態が長く続いてしまいました。 また、無線APのスペックがよくないのか、20端末程度がぶらさがるだけで顕著な通信速度の低下や無線APからの切断が発生し、不満の声も多く挙がりました。

不満の声
不満の声

そこで、ある程度の規模の会社に所属している友人らに相談し、社内ネットワーク刷新に向けて業者や機器選定をすることになりました。

機材とサービス選定の話

さて、今回の刷新にあたり弊社では「Cisco Meraki」と「Mist」を比較検討する流れとなりました。

Cisco Meraki

meraki.cisco.com

Cisco Meraki(以降Meraki)は、前述のワイヤレスLANコントローラーなどの管理機器を全てクラウド上に置き、SSIDの設定、サイトフィルタリングから周波数設定までのあらゆる設定をWebブラウザ上で行うことのできる、クラウド管理型ネットワークシステムです。日本国内でも、検索するといくつもの導入事例が見つかります。

Mist

www.mist.com

Mistは上記Merakiの特徴に加えて仮想ビーコンによって得た位置情報などを元に、機械学習技術によって更なる運用の簡素化を目指すクラウド管理型ネットワークシステムです。

選ばれたのはMerakiでした

比較検証するにあたって、MerakiとMist、どちらも検証端末を借りて社内で試用してみました。

そして比較検討した結果

  • 社内でも環境設定等を行うにあたり日本語のUIが用意されている
  • 国内での採用実績がすでに多くあり、Cisco Merakiの担当者とも直接やりとりができる状態にある
  • スイッチ、ルータなどのレイヤーまで含めてMerakiクラウドシステム上で管理を行うことができる

といった点から今回はMerakiを採用するに至りました。

自前でセットアップを行った話

さて、機器とサービスの選定が完了し、いざベンダーに依頼をというところであるニュースが流れてきます。

thebridge.jp

そう、DMMからのMBOです。なので、今後は自己資本で会社を運営していかなければなりません。となると、無駄なコストはできるだけ削減する必要があります。 そこで、ベンダーからはネットワーク機器の購入のみ行い、施工と設定については自分達で行うことになりました。

設置の様子

というわけで、MerakiのSwitchとAPがオフィスに届いたので、設置、そして設定を行いました。

オフィスに届いたCisco MerakiのスイッチとAP
オフィスに届いたCisco MerakiのスイッチとAP

オフィスの柱に設置されたMeraki AP
オフィスの柱に設置されたMeraki AP

結果

Merakiの導入によって、社内のSSIDが統一され、社員に快適なインターネット環境を提供することができるようになりました。

また、Wi-Fiが使えるというだけではなく、実はMerakiAPIを公開しているので、これで色々と遊ぶこともできそうです。

documentation.meraki.com

Merakiのネットワークに接続してみたい方(?)、是非オフィスに遊びに来てください。

bank.co.jp

追記

4/24 19時

脚立について、推奨されていない使用方法をしている画像を削除しました。脚立の安全な使い方については、以下をご覧ください。ご指摘いただきありがとうございます。

脚立の安全な使い方 | 製品の安全な使い方 | サポート | 梯子、脚立のパイオニア 長谷川工業株式会社

4/25 14時

一部、本文を修正しました。

RubyKaigi 2019に弊社から2人が業務扱いで参加してきました

f:id:yu_suke1994:20190423153512j:plain

4/18から4/20にかけて福岡国際会議場で開催されたRubyKaigi 2019に、弊社からは私 id:yu_suke1994id:HolyGrail の2名が業務扱いとして参加してきました。

rubykaigi.org

興味深いトーク

今回のRubyKaigiでは、Ruby 3に向けての進捗報告があったり、Kaigi終了後ではありますがSVNからgitへの移行が完了したりと、色々と今後のRubyが楽しくなりそうなトピックがcore teamから共有されました。

また毎度おなじみ "Ruby Committers vs the World" では、スクリーンに写されたhackmdの画面に皆さんが思い思いのアイデアを書いていく様が見ていてとても面白かったです。

他にも聞きたい発表ばかりでしたが、肉体は一つしかないのでした。動画の公開を首を長くして待つことにします。

福岡はいいところ

今回のRubyKaigiは福岡で行われましたが、福岡は美味しいグルメがたくさんあることで有名です。開催までに、様々なブログで「ここは行っておけ」スポットの紹介がされていたのは記憶に新しいかと思います。

magazine.rubyist.net

弊社でも、福岡出身の社員からオススメのご飯情報を事前に共有してもらい、滞在中は毎晩舌鼓を打って過ごすことができました。

f:id:yu_suke1994:20190423153622p:plain

Conference week in Fukuoka

ところで、実はRubyKaigi 2019の前にはCloudNative Days Fukuoka 2019も開催されていました。 id:yu_suke1994 はこのイベントにも業務扱いとして、弊社からの支援を受け参加してきました。

cloudnativedays.jp

弊社では、マネージドKubernetes基盤の上でRailsアプリケーションを開発・運用しています。なので、Cloud Native界隈にも積極的に参加していきたいという想いがあります。

来年は松本開催

そしてRubyKaigi最終日には、次回は長野県松本市で開催されることが発表されました。もちろん私達はもう参加する意気込み十分な状態です。

f:id:yu_suke1994:20190423153702p:plain

来年の松本でまたお会いしましょう!

WE ARE HIRING!

私達は一緒にRubyKaigiに参加したい、というメンバーを募集しています!!

bank.co.jp

Japan Container Days v18.12 参加レポート

f:id:yu_suke1994:20181205140614j:plain

12月3日から5日にかけて、Japan Container Days v18.12が開催されました。弊社からは、業務扱いで id:yu_suke1994id:fujikawa-y の2名が参加しました。今回はその参加レポートになります。

多くのセッションに参加しましたが、その全てに言及するととんでもなく長い記事になってしまいそうなので、印象深かったセッションに絞って感想を書いていこうと思います。

keynote

keynoteでは、複数の企業におけるKubernetesの役割などについて話されました。

CNCFのChris Aniszczyk氏からは、CNCFの目指す地点、今後のロードマップなどについての話がありました。Serverlessだけではなく、Nodelessへの流れ、KubernetesをIoTやedge computingの世界まで広げたいという野望、kubeletそのものを仮想化するvirtual-kubeletの紹介などがありました。

github.com

またCNCFで定義している各プロジェクトの成熟度合いも確認することができるようです。

Projects - Cloud Native Computing Foundation

1年間の本番運用でわかったコンテナがチーム開発にもたらしてくれたもの


本番環境でコンテナを使うという事例を話されていました。

そもそもなぜコンテナ化をするのか?というところから言及されており

  • 開発環境を快適にしたい
  • 開発環境と本番の乖離をなくしてサイクルを早くしたい

これに尽きるのは納得の行く話でした。

そして、途中で口頭であった 心理的安全性を保つためにコンテナ化 というのが印象深かったです。

40 topic of Kubernetes in 40 minutes


マイクロソフトの寺田さんによる、40分でKubernetesにおけるトピックを40紹介する、という駆け足の発表では、 $ kubectl explain というコマンドの存在に衝撃を受けました。今までは https://kubernetes.io/docs/reference/#api-reference を見ながらYAMLを書いていたのですが、このコマンドがあればわざわざブラウザを使わずともYAMLにどのようなリソースの定義を記述できるのかがわかるので便利だと思いました。

1人でできるDocker/Kubernetes(GKE)を使った新規サービス立ち上げ


DeNAの新規サービス立ち上げにDocker/Kubernetesを使われた話が聞けるということで聞きに行きました。

最初からRailsで行くことのとチャレンジングなところでコンテナを使うという話があり 少人数でサービスを作るノウハウと過去の開発で課題だったことが印象深かったです。

また、サーバー側とインフラ側で担うところも明示的に示しておりとても参考となりました。

2020年のコンテナはどうなる!? コンテナプラットフォームのこれまでとこれから

コンテナ界隈の人たちを呼びこれからどうなっていくかを話されていまいした。 いくつかの議題があり、それに対するコメントのうち印象に残ったものを抜粋して記載します。

  • コンテナ技術浸透した?
    • 浸透したと思う理由
      • 来場者のアンケート回答結果の9割が使っているというのがあり、自分で調べられる状況にある
      • 普及はしているが、本番はこれからという印象
    • コンシューマ向けサービスの開発はβ版でも使っている
      • 開発、CICDもやっているが本番はやはりまだ少ない
    • 浸透したと思えない理由
      • 詳しい人とまったく詳しくない人の二極化が目立っている
      • 使えるけど、メリットに繋げられない人も多く感じている
      • エンタープライズには話が通じないのが現状
      • さらに概念を理解せずに使っている印象がある
    • どこがネック?
      • コンテナをコンテナらしく使うことが今後の課題
      • コンテナを使うからこその付加価値が必要
    • コンテナは何が動くのか?ということもありまた、マイクロサービスの定義にも繋がってくる
      • マイクロサービスは組織の問題も関わってくる
      • アプリケーションレイヤーのI/Fだけ連携する
        • その中の話はチームに権限委譲して自律的にやってもらうのが良い
    • システムを組織に合わせるのが今の日本の組織。
    • Webサービスなら導入できるが、エンタープライズはハードルが高く慎重である
    • 本番導入済のところはマネージドサービス使われているのが前提であって、自前で動かしている人は考えることが多すぎて本番に導入できないのではないか?というところがある
  • k8sデファクトスタンダードになっているが差別化は?
    • k8sの導入、運用、カスタムができるという差別化となる
    • k8sの全部の機能いります?という疑問に行き着くところもあり、他のやつを使った方が良い場合もある
    • 更に言うとコンテナ使えるだけいいのでは?ということも言える
    • Runcherもk8sとの差別化を意識しつつ使う人が幸せになるようにしたい
    • k8sの良さは拡張性があること
    • k8sのデプロイとバージョンアップが大変
      • また初期の学習コストが高くアプリデベロッパーへどう浸透させていくのか?が課題。
  • 今後追うべき技術は?
    • Knative
    • サービスメッシュが来る。Istioがきて成熟期になる
    • イベント情報をキャッチアップすることが大事
    • CoreOSも追うべきもので、それも含めて運用を楽にするためのもの
    • AIのKubeflowでデータパイプラインが必須な部分なのでこれも追う

Cloud Nativeプロダクト1000本ノック

CNCF Landscapeには、CNCFでないプロダクトも含め、600を超えるプロダクトが掲載されています。

landscape.cncf.io

このセッションでは、データストア、CI/CDなどのトピックに分けて主要なCNCFプロダクトの紹介が行なわれました。辛うじて名前だけ聞いたことがあったりするものや、初耳なプロダクトも結構あって、こんなの追い切れないだろう……と思いました。だからこそ、コミュニティとして活動し、様々な検証を持ちよって情報を共有し合うことが重要になるのですね。

また、Cloud Native Trail Mapを見るとわかるのですが、コンテナ化、Kubernetesによるオーケストレーションは "Cloud Native" という観点ではまだ入口に過ぎず、そこで満足していてはいけないのだなということも感じされられます。(プロダクトの規模にもよるとは思いますが……)

また、このセッションで知ったのですが、Spinnakerがpipelineをコードで管理できるようになっていたのには驚きました。それまではGUIによるpipeline定義しかできず、.circleci/config.yml のようにコード化できないのはちょっと、なーと思っていたところなので、導入に向けて前向きになれますね。

blog.spinnaker.io

pipelineの定義については、イベントでデモとして提供されていたshowKs( https://showks.containerdays.jp/ )で実際に使用されているものがGitHubで公開されています。

github.com

runcだけじゃない コンテナlow level runtime徹底比較


皆さんはコンテナのruntimeを意識してDockerを使っていますか?僕は全く意識していません。

Dockerは、コンテナのruntimeとして、デフォルトでruncというものを使用します。このruntimeは実は様々な特性のあるものが公開されているのですが、よっぽどのことがない限りはruncから変更することはないでしょう。

このセッションでは、そんな様々なruntimeの紹介と、それに対してのベンチマークを行い、その結果や選択の指針についての発表が行われました。 紹介されるruntimeはどれも特色にあふれ、技術的好奇心を刺激されはするのですが、じゃあproduction環境で使いますか、となるとそこまでのメリットは感じられない、と言うか一般的なユースケースにおいてrunc以外をあえて使うことって無いよな……と感じました。Nabla containersとか、うおお何じゃそれ! とはなるんですけどね……

とある30秒でできるKubernetes + GPU 開発環境


Canonicalの方による、 https://microk8s.io/ の紹介LTがありました。microk8sは初耳でしたがsnap packageになっており、Ubuntuユーザーの僕としては何ならMinikubeより導入が楽なのでは?という気さえしました。会場にいた方のなかには、「Minikubeはなにやってるかわからなくて若干ブラックボックス感があるのでmicrok8sのほうが好きだ」と言う意見もあり、ローカルでもKubernetesで開発する際にはぜひ使ってみたいと思いました。

CRIUの概要とその活用 - 未来のコンテナ技術について


GMOペパボにて、mrubyによるコンテナランタイムhaconiwaを開発していらしゃるうづらさんの発表でした。今回はhaconiwaの話ではなく、CRIUの話でした。

皆さん、 $ docker checkpoint というコマンドをご存知でしたか?僕はこの発表で初めて知りました。CRIUは、checkpoint/restore という機能を実現するためのツールです。利用することで、あるプロセスのその時点でのsnapshotを取得でき、その情報からプロセスの状態を復元することができる、ということが可能になります。

デモでは、whileループでカウントアップしていく変数の状態が、$ docker checkpoin crerate$ docker start --checkpoint の前後で保持されていることが確認できました。

docker v18以降では、checkpointはうまく動かないようですが、これが安定して動作するのであれば夢が広がりますね。例えば規模の大きなRailsアプリケーションは、起動に若干の時間がかかり、突発的なスケールには対応できません。これが、起動後の状態のcheckpointを作成しておき、それを展開することによって素早いスケールアウトができるようになったりするでしょう。

Runtime BoF

docs.google.com

ディスカッション形式でruntimeについて話すTechMeetingでは、第一線で活躍しているエンジニアの方々による、runtimeに限らない様々な議論について聞くことができました。 先程も書きましたが、結局runtimeをruncでないものにするメリットってあるんだっけ、という話から、コンテナイメージのセキュリティの担保、はたまた海外でのカンファレンスやOSS開発における英語問題など、本当に議題は様々でした。

コンテナイメージのセキュリティに関しては、とても考えさせられました。Docker Hubで個人が公開しているimageは使用しないというのは前提として、企業が公開しているimageであっても、それに悪意のあるコードが混入していないという保証はありません。imageに署名をするよりは、継続的なimageのスキャンのほうが重要である、という意見がありました。CNCFにも、そのようなことを行なってくれるClairというものがあります。またGCPにも、Container Analysisという機能があります。積極的に使っていきたいですね。

感想

非常に濃いイベントでした。便利そうなCloudNative productの情報であったり、Kubernetes運用の知見であったり、他の企業がどうしているのか、今後のCloudNativeの方向性、などなど……情報量で圧倒されました。今年は、聞くことのできなかったセッションのスライドを読んだりして、内容を噛みしめたり、書籍を読んだりして、今後のサービス開発に役立てられることがないか考えることにしようかと思います。

また、今年2回目となるJapan Container Daysですが、今回で最後となることが発表されています。ですが、CloudNative Daysと名前を変え、来年には東京だけでなく福岡や大阪でも開催されることが同時に発表されました。しかも福岡開催はRubyKaigi2019の直前ということで、僕は個人的にめちゃくちゃ盛り上がっています。

https://cloudnativedays.jp/

CloudNative、やっていきましょう。

sidekiq-cronアップデートへの道のり

f:id:yu_suke1994:20181121141855p:plain

こんにちは。ジョブスケジューラーとしてはSidekiqしか触れてこなかった うなすけ (id:yu_suke1994) です。

さて、Railsアプリ開発者の皆さんは定期的な bundle update を何らかの方法で実行していることでしょう。弊社でも最近になって Dependabot を導入することになりました。

今回は、Dependabot を導入する前に、一気に bundle update したときに起こった Sidekiq まわりの問題、それも sidekiq-cron で起こった問題について書いていこうと思います。

「一気に bundle update」 とは何か

弊社サービス、特に今回はCASHのAPI サーバーのRailsについての話になりますが、これまでは気付きベースで bundle update を行なってきました。

さすがに自動でやっていく仕組みを入れたいので、ツール導入のためにもう一度 bundle update を実行し、今後はツールによる差分のみを注意して見ればいいという状況に持っていくことにしました。1

問題なく bundle update できた……と思っていた

f:id:yu_suke1994:20181120171335p:plain

updateされるgemのコードを確認し、staging環境での動作確認も行ない、特にエラーもなかったのでmergeしてdeployしたのですが、本番ではJobの実行時に例外が発生するようになってしまいました。

なぜCronJobは実行されなかったのか

sidekiq-cron は、CronJob が最後にenqueueされた時刻をRedisに保存します。 v0.6.4 でのコードは以下のようになっています。

#enque cron job to queue
def enque! time = Time.now.utc
  @last_enqueue_time = time

https://github.com/ondrejbartas/sidekiq-cron/blob/v0.6.3/lib/sidekiq/cron/job.rb#L47-L74

ここで、 Time.now.utc の結果は、このまま to_s されてRedisに保存されます。

さて、 Redisから最後に queue に入った時刻を取り出す部分の v1.0.4 でのコードが以下のようになっています。

def parse_enqueue_time(timestamp)
  DateTime.strptime(timestamp, LAST_ENQUEUE_TIME_FORMAT).to_time.utc
rescue ArgumentError
  DateTime.strptime(timestamp, LAST_ENQUEUE_TIME_FORMAT_OLD).to_time.utc
end

https://github.com/ondrejbartas/sidekiq-cron/blob/v1.0.4/lib/sidekiq/cron/job.rb#L554-L558

そして、 LAST_ENQUEUE_TIME_FORMAT_OLDLAST_ENQUEUE_TIME_FORMAT は次のようになっています。

LAST_ENQUEUE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %z'
LAST_ENQUEUE_TIME_FORMAT_OLD = '%Y-%m-%d %H:%M:%S'

https://github.com/ondrejbartas/sidekiq-cron/blob/v1.0.4/lib/sidekiq/cron/job.rb#L15-L16

この辺で勘のいい方は気づかれるかと思いますが、Redisからの last_enqueue_time をparseする際、書式が想定外だと例外が上がります。

つまり、 Time::DATE_FORMATS[:default] を独自定義していた場合、 sidekiq-cron v0.6.4 時代に実行されたCronJobは v1.0.4 にアップデートすると実行できずに例外が上がってきます。

そして案の定、CASHのAPIサーバーでは Time::DATE_FORMATS[:default] が再定義されており、前述の挙動によって sidekiq-cron v1.0.4 が動作しませんでした。

アップデートするためにやること

このとき、無事に v1.0.4 にアップデートするために取り得る手段として、次の3つが候補としてありました。

  1. 正しい書式の時刻をRedisに格納し直す
    • 独自定義した書式からは時刻単位の情報が欠落しているので復元が不可能
    • Redisの値を手で操作したことがなく、不安
  2. sidekiq-cronで使用している key-value の組を全部削除する
    • これまでの実行情報が全て消えてしまう(が、そもそも正確ではないし……)
  3. 独自定義を削除し、正しい書式でRedisに格納されるまで待つ
    • 時間はかかるが安全

ということで、「独自定義を削除し、正しい書式でRedisに格納されるまで待つ」ことにしました。CronJobのなかには、毎月1回実行されるというものがあります。なので、 Time::DATE_FORMATS[:default] の設定を削除してから1ヶ月待ち、Redisに格納されている last_enqueued_at の書式が全て正しいものになっているかどうかを確認したうえで、sidekiq-cronのアップデートを行いました。

まとめ

という訳で、継続的bundle updateの体制が整いました!流れでRailsのバージョンも5.2.1になりました。

引き続き、やっていきましょう。


  1. 今考えると、そのようなことをする必要はなかったんじゃないかと思いますが……