RubyKaigi 2017 レポート

04 October 2017 by Steven

こんにちは。エンジニアの Steven です。
広島で9月18日から20日まで行われた RubyKaigi 2017 に山本さんとエンジニア二人で行ってきましたので、どうだったのかについてレポートさせていただきます。

RubyKaigi は毎年 Ruby 言語を中心に行われる会議です。
最近は日本を巡って毎回違う都市で行われてて、今回は広島で行われました。
日本語のセッションもあれば、英語のセッションもあって、外国人の参加者が少なくはないイベントです。
Ruby のカンファレンスの中でレベルが一番高いと言われています( Ruby の作者曰く)。

会議は月曜日から水曜日まで行われてて、事前の週末に広島まで行けば、東京に住んでいる私達にとっては、広島で少し観光をする機会でもあって、そうできるように準備していましたが、残念なことにこの週末はちょうど台風がその近くまで通ってきて、観光するどころか、新幹線ではそもそも行けるのかと、逆に心配することになりました。
ですが、会議の3日間自体は天気は極めてよくて、日焼け止めが必要になるのではないかという逆転にもなりました。

1日目

朝起きて、元安川(今調べました)を渡って、会議が開催されてる広島国際会議場まで行ってから、入場券を受けて、会議スタート!


(目をつぶっていてすみません。後から気づきました。)

初日で見てきたトークは

■ 基調講演、Nobuyoshi Nakada
■ Fiber in the 10th year、Koichi Sasada
■ How Close is Ruby 3×3 For Production Web Apps?、Noah Gibbs
■ Gemification for Ruby 2.5/3.0、Shibata Hiroshi
■ How to optimize Ruby internal、Shizuo Fujita
■ I quit my job to write my own language: Goby、Stan Lo
■ Ruby Committers vs the World

今見返してみると、毎日の仕事ですぐに活かせそうなトークは初日はそんなになかったかと思いますが、Ruby のコミュニティーはどう構成されているのか、どんな課題を抱えているのか、何をやっているのかはより具体的に理解できて、他の Rubyist の毎日に触れて勉強になりました。

この日の最後のセッションとして、Ruby のコミッターが壇上に上がって、全員で議論をしながら、聴衆の質問に答えてたというイベントがありましたが、この日の中で一番記憶に残ってるところです。
質問に答えるためにコミッターの皆さんが議論にのめり込んで、質問一つだけで1時間が立ってしまいそうな状況に数回なってしまいましたが、その議論を聞くのは単に面白くて、話題はなんであろうと、専門的な技術力を持ってる人が周りにいれば、それだけで面白くなると感しました。

初日のセッションが終わってから、晩御飯が目的で街に出ててたのですが、なぜか赤色のシャツを着ている人が多くて、最初はよくわかりませんでしたが、なるほど、広島のカープが日本一になった直後でした。
広島市は全体的に盛り上がっていて、東京に戻ってきたのではないかと、ところどころ人混みができてました。

その夜は広島風お好み焼きを食べる機会になったのですが、やはり美味しくて、2日目も3日目ももう一度食べようという衝動に耐える必要が出ました。

2日目

翌日は朝にスターバックスによってから、会議場に戻って、2日目スタート!
2日目で見てきたトークは

■ 基調講演、Yukihiro Matsumoto
■ The Ruby Module Builder Pattern、Chris Salzberg
■ Improve extension API: C++ as better language for extension、Kouhei Sutou
■ Automated Type Contracts Generation for Ruby、Valentin Fondaratov
■ Type Checking Ruby Programs with Annotations、Soutaro Matsumoto
■ Ruby Language Server、Fumiaki Matsushima
■ Write once, run on every boards: portable mruby、Yurie Yamane
■ Lightning Talks

基調講演は今回は Ruby の作者によって行われてて、やはりまつもとさんは本当に実在する人で、自分が普通の人間でも実際に会える方だとわかりました。
基調講演でも少し紹介されましたが、この日の注目は Ruby での型の導入のトークだったかと思います。

最近新しくできた言語の中では静的型付けの言語が多くあって、どんどん人気になってますが、動的型付けである Ruby でも型のいいところを適切な形で活かせるのかという考えがあって、今回はそれについてのトークは2つもありました。
Ruby には型が実際に入ってしまうのかどうかはまだわからないのですが、型のチェックをしてくれるツールを Ruby に入れることでどうなれそうなのか、Ruby の未来を少し見れました。

個人的には Lightning Talks はその日の一番面白いセッションでした。
1時間で5分だけのトークが12あって、何かをゆっくり学ぶという目的より、いろんな情報を短時間で伝えて、面白話を交えながら、聴衆を楽しませるのがそのライトニングトークの一つの印象でした。
ビデオは公開されましたので、技術の話で少し笑いたければ、そのトークをおすすめします。

その日は昼休みに原爆ドームを見に行く時間は少しあって、日本の世界遺産の一つを写真にとどめることができました。
一言でまとめさせていただきますと、感動しました。

その夜の晩御飯は海鮮料理で、少し高めな食事でしたが、広島のもうひとつの名物を食べれてよかったです。

3日目

いよいよの最終日!
ホテルからチェックアウトして、会議場に戻って、最終日スタート!
この日見てきたトークは

■ Compacting GC in MRI、Aaron Patterson
■ Ruby for Distributed Storage System、Satoshi Tagomori
■ Pattern Matching in Ruby、Yuki Torii
■ Memory Fragmentation and Bloat in Ruby、Nate Berkopec
■ Busting Performance Bottlenecks: Improving Boot Time by 60%、Julian Nadeau
■ How to write synchronization mechanisms for Fiber、Masatoshi Seki
■ Towards Ruby 3×3 performance、Vladimir Makarov

この日は基調講演は特にありませんでしたが、注目はパフォーマンスに関するトークでした。

Ruby の GC をどう改善できるか、メモリー関連の問題をどう調査・解決できるか、Ruby をどう3倍早くに改善できるか、違う種類のパフォーマンスの問題についていろんなトークがあって、基礎知識としても実践力としても役に立ちました。

この前、Ruby の作者が設定した Ruby 3×3 という目的は、設定されただけで実際にそれを簡単に実現できるのかどうかは個人的には少し疑問に思ってたのですが、最後のトークでそれを実現できそうなプロジェクトを紹介してくださった方が現れて、そんなに遠い未来じゃないと思うようになりました。

面白い演説で聴衆の笑いを集めた閉会の辞の後、お土産を買って、無事に東京に帰りました。
今回会社で広島までこれたのは私達二人だけでしたが、得てきた知識を東京に残った他のエンジニアに共有する予定です。

終わりに

イベントが多い出張でしたが、RubyKaigi に参加できてよかったです。
新しい基礎知識と Ruby コミュニティーに関する知識を積めて、勉強になったカンファレンスでした。

Ruby 言語のカンファレンスに参加するのはこれで初めてでしたが、Ruby に限らずこれからも他に多くあるプログラミング言語を中心にしたカンファレンスに参加したいと思います。
今まで実際に参加してきたのは、大学で開催されたカンファレンスだけであって、それ以外のトークはすべてビデオで見てきましたが、前の私と同じく、まだカンファレンスに出席したことがない方に出席をおすすめします。一度やってみたら、中々やめられなくなってしまうかもしれません。

Pocket

Leave a comment | Categories: Events, Ruby

ヒカ☆ラボでReact導入の話と商品検索改善の話をしてきました

12 June 2017 by Yamamoto

こんにちは。エンジニアの山本です。
5/23に開催された、【 ヒカ☆ラボ 】大規模サービスがリスクをとってまでモダンな開発環境にリプレイスした理由~ここだけの苦労話や手法を交えお話します~ というイベントに参加 & 登壇してまいりましたのでレポートします。

今回のイベントのテーマは レガシー改善 という、長年継続しているサービスでは避けては通れないものでした。

弊社のサービスである BUYMA もローンチから10年以上経ち、溜まりに溜まった技術的負債を日々返済しています。

Reactを導入した話

弊社からは2人登壇させて頂きまして、私、山本は “React導入時の苦労話とこれからについて” と題しまして、ある機能のリプレイスプロジェクトでReactを導入した話をしました。

既にデファクト・スタンダードになったと言えるReactですが、導入当時の一年前は大規模なサービスに導入したという事例もまだ少なく、如何にして非SPAなWebサービスにReact/Reduxをマッチさせるかという点でとても苦労しました。

当時の苦労話を共有することで、少しでもこれから大規模サービスにReactや他のJavaScriptフレームワークを導入しようとしている方々のお役に立てればと思います。

こちらが発表資料です。

商品検索を改善した話

木村の方は、“BUYMAの商品検索システムの改善の取り組み”というテーマでした。バイマの商品検索システムをSolrCloudへリプレースし、耐障害性を向上させた取り組みについてや、レガシーな検索ロジックを、BigQueryなどを駆使しながら数値で検索精度を計測しつつ、新しいロジックへと改善していく取り組みについてお話しました。

発表資料はこちらです。

BUYMAの商品検索システムの改善の取り組み from 慎太郎 木村

当日の様子

木村
Image uploaded from iOS (1)
山本
Image uploaded from iOS
質疑応答時
Image uploaded from iOS (2)

まとめ

一緒に登壇させて頂いたJapanTaxiさん、一休さんのお話も非常に共感できるところが多く、また今回は最近開催されたヒカ☆ラボの中でも来場者数は多かったようで、”みんなレガシー改善に苦労しているんだなぁ”としみじみ感じました。
新しい技術がどんどん生まれる中、如何にして技術的負債を返済してくかはこれからますます重要になってくると思います。
みなさんもガンガン知見を共有して共にレガシーと戦っていきましょう。

Pocket

Leave a comment | Categories: Events, JavaScript

AMP対応のススメ

30 May 2017 by Omiya

エニグモでWEBエンジニアをやっております、大宮です。
今回は、先日英語版BUYMAで行った、AMP対応についてまとめた記事をお届けしたいと思います。

そもそもAMPとは?

Acceralated Mobile Pagesの略です。
その名称が示す通り、モバイル端末で高速なWebページを表示させるためのプロジェクト、またはそのためのフレームワーク(AMP HTML)の事です。
フレームワークはGoogleとTwitterにより共同開発されています。2016年の2月にローンチされて以降、AMP対応を行っている企業は増え続けています。

Googleからは今のところは明言されていませんが、メインの開発にGoogleが入っているということで、いずれSEOの上位表示に影響してくるのではないかという予測も立てられているようです。
現に、一部の記事ページではスマホで検索するとカルーセルで検索結果の上位に表示されます。

近年は新興国でもスマホ文化が普及する一方、回線速度の遅さが問題視されることもあり、AMPはこうした時代の流れにも対応したものと思われます。
国内を見ても格安SIMや通信容量制限による低速化などにより、WEBページの体感速度の向上はますます重要な要素になってきています。
ページが速く表示されるだけユーザーの満足度は向上するというのは、想像に難しくないでしょう。

実際に見てみましょう

実際に対応された英語版BUYMAのサイトを見てみましょう。

AMP未対応のページ(ベンチマーク計測:11.5秒)
AMP対応のページ(ベンチマーク計測:3.5秒)
AMP対応のページをキャッシュしたAMP Projectページ(ベンチマーク計測:0.76秒)

ベンチマークは低速な回線で撮ったものです。
体感でも表示速度が一番下のキャッシュ速度が速い事がわかるかと思います。

なお、上記AMPのページはPC版で見ると崩れているように見えますが、CSSをモバイルに最適化した(PC対応のCSSを排除した)結果です。後述する実装でAMPを別URLとした場合、AMPのページがPCからみられることはありませんのでOKとしています。

なぜ速いのか?

AMP対応のHTMLは読み込みが非常に速いです。その理由を見てみましょう。

■ AMPでは、非同期のAMP専用JSしか使用出来ない。
■ CSSのサイズ制限+外部ファイルに置く事を禁止している
■ 画像のLazy Load+幅高さ指定の強制でブラウザの負荷を軽減

特に一番大きいのは最後のLazy Loadでしょう。
通常Webブラウザはページの表示時でページ内のすべての画像を読み込もうとしますが、AMPでは表示領域のみ非同期で画像をロードしてきています。
それを可能にしているのが<amp-img />タグです。ampページでは通常の<img />タグは使用できず、すべてこちらに置き換える必要があります。

また、CSSのサイズ制限があるので、リッチなコンテンツの量は増やしづらく、AMPページとしては余分なモジュールを削りおとすことになり、全体として読み込むファイルサイズが軽減されやすいということです。

さらに、これらのHTMLは、AMP-ProjectのCDNサーバーにキャッシュされ、検索結果での表示時にはキャッシュされたページを表示するようになります。
このキャッシュ時に、画像もモバイル用に圧縮をし、ファイルサイズを軽減しています。

さらに検索結果の表示時には、ユーザーが見ている検索結果の部分で、裏側でPreconnect / Prerenderingが走っています。
ユーザーが検索結果からページにアクセスしようとしてタップした時には、すでに裏側でページが読み込まれているため、ユーザー体験としては爆速に感じるということです。

AMPの三大制約

AMPを実装するにあたって、設計の段階で留意すべき制約は3つあります。

■ JSが使えない*
■ CSSは50KBまで
■ Cookieが使えない

ということ。言い換えれば

■ リッチなページは作れません。
■ ログインユーザーに応じて出しわけ…などの機能は使えません。

ということです。

JSが使えないというのは、自前のJSは一切使用不可ということで、JSでよく使用される機能について、ある程度はAMP-Projectの方で用意されています。
例えば、サイドバー、カルーセル、フォームのバリデーション等。詳細は公式のこちらのページに記載されています。

また、JSに関しては、2017年6月現在、amp-bindという機能が開発中です。
リリースされればJSで自前のスクリプトを書いた時ある程度は同じような挙動を実現できるようになります。
具体的には、イベントトリガーでclassやInnerText, attributesの値を動的に変更するということが可能になります。

が、それでも既存のJSの流用はできないため、amp-bind用に書き直す必要があります。

URL方式の設計

まずは上述のように、できることとできないことをただしく把握する必要があります。
基本的に上の項目を把握されていれば問題はありません。

次に、AMP用に新規URLを作るのか、既存ページをAMP化させるのかを決めます。
モジュールを分けるかわけないかという選択ですね。
可能であれば、メンテナンス性を考えて同一モジュール…つまり今あるページをAMP化し、新規では作らないというアプローチが望ましいです。ただ前述の通り、AMPには制限がありますので、オリジナルページを残したい場合もあるかと思います。
その辺りはページのボリュームと、JS書き直しの工数(既存機能への影響)を加味して判断する必要があります。

ちなみに新規でページを作る場合には、最初からAMPに対応したものと作成してしまえば、既存ページへの差し替えで悩むことはなくなります。

画面の設計

基本的にはオリジナルページから何を残して何を削るのかを判断する必要があります。
オリジナルページをそのままAMP化しても、CSSの容量超え+JSのリッチコンテンツで実現可能なものと不可能なものが出ると思います。
なのでAMPページの要件として絶対に必須なものを厳選して残し、CSS容量や工数に余裕があれば別の機能の対応も行うというアプローチが良いでしょう。
実際に開発してみてできること、できないことが分かるという事もあります。

なお、前述の弊社サイト(商品詳細ページ)では、商品情報+カート購入機能だけを残して、グローバルナビや検索バーといった要素は排除しています。これらの要素はAMPでも代替は可能ではありましたが、CSSの容量制限の関係で断念した要素でした。

実際にAMPページにしてみる

AMP専用の雛形がありますので、ご自身のサイトにあててみましょう。
bodyタグやheadタグやCSSは適宜調整していただければ良いかと思います。

これで、サイトはAMPとして扱われます。

なおAMP用に新規でURLを作る場合には、オリジナルページのHTMLのheadタグ内に下記を記述しましょう。
<link href=”AMPページのURL(フルパス)” rel=”amphtml”>
これでGoogleにもAMPページが認識されます。

ただし、エラーが出る(多分)

Chromeの開発者モードを開きURLの末尾に#development=1とつけましょう。雛形をそのまま使っていない限り、このように大量のエラーとなるはずです。

スクリーンショット 2017-05-30 10.14.26
弊社サイトの対応途中で怒られていた内容としては、主に下記のような内容です。

■ img -> amp-imgに変換+幅・高さ指定してください
■ scriptタグの使用してる所を全部削除してください
■ a href=”javascript:void(0);”など
■ cssをインラインで読み込みしてください
■ cssのファイルサイズを削減してください

このエラーを解消しないと、GoogleからAMPページとして認識されませんので、すべて対応しなければいけません。
根気よく対応していけば、いずれは下記のように「AMP validation successful.」となりますので、頑張って対応しましょう。
スクリーンショット 2017-05-30 13.53.28
WEBアプリケーションの場合はVIEWにIF文があることも多々あるので、当然ながらその条件分岐は全パターンみておく必要があります。

晴れてエラーがでなくなれば、本番環境にデプロイして、完了となります。
この時本番環境でしか動いてない監視用のJSなどがあると、またエラーになってしまいますので、注意深く観察しましょう。

終わりに

AMPはそれなりに工数もかかる上に、完成する画面としては真新しいものではありません。
むしろ既存の画面より機能が削ぎ落とされたものなので、パッとみた完成品は物足りなさを感じるかもしれません。

なかなか成果のわかりにくい改修ではありますが、実際にAMP対応によって数字の伸びた事例も挙がってきています。
何より低速回線のユーザーにも、快適な挙動のページをお届けするという意味で重要な要因となりますので、ぜひとも導入を検討していただければと思います。

本記事がその際の一助となれば幸いです。

Pocket

Leave a comment | Categories: Uncategorized

ReproUserMeetup#1にて登壇してきました!

16 June 2016 by Enigmo Engineer

みなさんはじめまして!
BUYMAでiOSアプリのエンジニアを担当している、松本と申します!

先日6月2日に行われたRepro User Meetup #1に登壇してまいりましたので、その様子をお伝えします!!

Reproとは?

Reproとはアプリに特化した、アナリティクスツールです。従来のツールと大きく違う点は、ユーザーの行動を動画で確認をできる点とリテンション分析・ファネル分析といった機能によってユーザーの重要な行動を細かくトラッキングできる点です。詳しくは、ReproさんのHPをご覧ください

当日の様子

IMG_4506
当日はReproを活用されている10社様が登壇され、様々なReproの活用法や成功事例が発表されていました。各社様の発表内容はコチラから

BUYMAでのRepro活用

IMG_5837
新規ユーザーにまず継続的にアプリを使用していただくことは、どのアプリにおいても非常に重要な事と言えると思います。

Reproのリテンション分析では、特定のアクションを行ったユーザーのリテンションを測定するといったことも可能であり、今回のRepro User Meetupでは新規ユーザーに対して最も効果的なイベントをどう判断するかという事について発表を行わさせていただきました。

詳しい内容はこちらのスライドをご覧ください!

BUYMAにおけるRepro運用 from Takashi Matsumoto

IMG_5472
Repro株式会社取締役CMOの中濱 康広様(中央)と弊社松本(左)と松永(右)

Pocket

Leave a comment | Categories: Events

BUYMAの商品検索を支えるSolrCloud

02 September 2015 by Kimura

お久しぶりです。アプリケーションエンジニアの木村です。

BUYMAでは、この記事を書いている時点で世界中から出品された約155万件の商品が検索可能となっていて、商品検索機能は世界中から自分の欲しい物を探すことを実現する、まさに「世界を買える」を実現するための重要な機能の1つとなっています。今日はそんなBUYMAの検索機能の裏側を支える基盤部分についてご紹介いたします。

BUYMAでは検索機能実現のためにはSolrを導入していて、さらにSolrCloudを構成しています。

SolrCloudとは

SolrCloudは、高信頼性、耐障害性、拡張性を運用コストを抑えつつ実現するSolrのクラスタリングの仕組みです。紙面の都合上あまりSolrCloudについて詳しく説明できませんが、下記リンクが参考になるのではないでしょうか。

https://cwiki.apache.org/confluence/display/solr/SolrCloud
http://www.slideshare.net/kenhirose547/10solr-solr-cloud

あまりWeb上に詳説された記事がないので、下の書籍も参考にしつつ構築にとりかかりました。

・『Solr in Action』Trey Grainger・Timothy Potter (2014) Manning Publishing.
・『改訂新板 Apache Solr 入門』大谷純・他(2013) 技術評論社.
・『Scaling Apache Solr』Hrishikesh Vijay Karambelkar (2014) Packt Publishing.
・『ZooKeeperによる分散システム管理』Flavio Junqueira・Benjamin Reed [著]、中田 秀基 [訳] (2014) オライリー・ジャパン

さらに、上の2つ目の本も監修されているロンウィットさんのトレーニングも受講しました。最後の本はSolrCloudに組み込まれるZookeeperの本です。

BUYMAでのSolrCloudの構成

BUYMAのでのSolrCloudの構成を表したものが下の図になります。

SolrCloud

更新のしくみですが、Solrを更新するバッチが常に動いていて、DBから更新がかかった商品情報を取得し、leaderのSolrノードへ更新リクエストを送ります。するとSolrCloudの仕組みとして、leaderノードが他のreplicaノードへ更新を伝えて全ノードが更新されます。

検索はRailsのWebサーバーから直接SolrCloud内のSolrノードへリクエストします。特にロードバランサー用のサーバー等は挟まず、SolrノードのIPをランダムに選び、そのIPへリクエストを飛ばすように、Railsアプリ側でロードバランシングしています。

耐障害性への取り組み

RailsのWebサーバーから直接SolrノードのIPへ検索リクエストが飛びますが、各SolrノードのIPアドレスはそれらを監視しているZookeeperから取得しています。したがって、いずれかのSolrノードで障害が起こった場合でもそれをZookeeperが感知し、リクエスト可能なIPの一覧からダウンノードのIPを外してくれ、ダウン中やリカバリ中のノードへは常にリクエストが振られない仕組みになっています。

更新時も更新バッチがZookeeperからleaderであるSolrノードのIPを取得し、それに対して更新リクエストを飛ばしています。もしleaderノードで障害が発生し、フェールオーバーして別のノードがleaderとなった場合でも、Zookeeperがそれを感知して更新バッチ側へleaderの変更が伝わる仕組みです。

実は、Zookeeperと連携してそこらへんの面倒な処理をやってくれるSolrJというSolrCloudにも対応したJava用のSolrクライアントがあるので、JVMのWebアプリではそれを使ったり、そうでない場合はSolrJを使ったAPIサーバーを検索クライアントとSolrとの間に挟む構成が通常なんだそうです。ただ、そのためのサーバーの運用保守もコストなので、RubyからZookeeperと連携するSolrCloud用のRubyクライアントを自分たちで作りました。gemとして公開していますので、ご自由にお使いいただいてフィードバック等をお待ちしております。

https://github.com/enigmo/rsolr-cloud

BUYMAの検索基盤クロニクル

BUYMAがシステム面で今の形に近いものに生まれ変わったのは2008年ごろ(らしいの)ですが、その当時公開されていたSolr 1.3系の時代から検索機能にはSolrが導入されていました。その後2011年に3.x系へとバージョンアップがなされ、2015年6月まで稼働していましたが、商品数の増加とマスキャンペーンにより大量のアクセスが予想されたため、マシンリプレースと合わせて2015年リリースされた5.x系へとバージョンアップしました。さらに、運用し易さを求めて、構成をSolrCloudとしました。

SolrCloud導入以前は、マスタースレーブ構成でもなく、Solrノードを並列にならべてそれぞれのIPアドレスを更新・検索クライアントとなる全サーバーに固定値で持たせていました。更新バッチは全Solrノードへ同じ更新リクエストを何度も送る必要があり、1ノードでも更新に失敗すれば検索結果がノードによってズレてしまいました。Solrノードでの障害発生時やメンテナンス時にもそれぞれのサーバーのSolrノードのIPを書き換えてやる必要がありました。商品数やアクセス数の増大に伴って、この先ノード数を増やす場合にこの構成では限界を感じていました。また、仮にマスタースレーブ構成にしたとしても、マスターが単一故障点になってしまったり、障害対応の時の手間は変わらないというのが難点で、マスタースレーブ構成への変更にも二の足を踏んでいました。

SolrCloudはそういった煩雑さから開放してくれ、まさに自分たちにとっては渡りに船でした。結果、スキーマ変更や設定ファイルのチューニング、ノードの障害発生時の対応やメンテナンスが圧倒的にやりやすくなりました。マシンリプレースの効果もありますが、パフォーマンスも、導入前より向上しました。

今後

Solrのバージョンが3.xから5.xとなり、機能面でも新たに使えるものが増えたので、BUYMAの検索の機能面としても向上していければと思います。

Pocket

Leave a comment | Categories: Uncategorized

← Older posts