2019年7月18日

旅行をもっと楽しくお得に!好きな宿と航空券の組み合わせた商品検索の仕組み

  • このエントリーをはてなブックマークに追加

こんにちは、ヤフートラベルのフナサカです。みなさんは夏休みの旅行の予定はもう決まっていますか?
ヤフートラベルでは昨年の12月4日に国内の宿泊と航空券をセットにした「ヤフーパック」という新サービスを始めました。
お得なサービスなので、ぜひ夏休みの旅行に利用してみてください。
今日はヤフーパックのリリース時にぶつかった課題の中で検索にスポットを当てたお話をします。

ヤフーパックとは?

ヤフーパックは宿と航空券をセットにしたいわゆる、ダイナミックパッケージ(以下、DP)と呼ばれるツアー商品です。
旅行代理店などのパンフレット販売でよくある「宿は〇〇ホテル、飛行機はX時出発」のような制約はなく、宿も航空券も候補の中から予約時に自由に組み合わせることができます。


料金は組み合わせや在庫状況によって変動しますが、基本的には早い時期に予約するほど安く、直前になると高くなります。
また、航空券はツアー用の割安なものを利用できるので、宿と航空券を別々に買う時よりもDPで買うほうが安いことが多いです。
航空券はJALとANAの2社を取り扱っており、それぞれヤフーパック専用のDP商品をジャルパック、ANAセールスで造成していただいています。

全体のシステム構成

ヤフーパックではユーザー向けの販売サイトだけではなく、商品造成用やカスタマーサポート用のツールなどの業務ツールも提供しています。
宿情報は一休と、航空券の情報はJAL、ANAと直接システムを接続して構築しています。
ユーザーの予約情報など絶対漏洩(ろうえい)してはいけない情報は特別なネットワークセグメントに保管しています。


検索速度の向上

複数のシステムで構成されているDPサービスですが、今回はユーザーがツアー商品を検索する部分についてピックアップしてお話します。

旅行代金の計算

DPは先程記載した通り、組み合わせや在庫状況によって料金が変動します。
検索結果画面を表示する際に一休から提供いただいている宿の空室状況や料金情報と各航空会社から提供いただいている航空券情報をもとに旅行代金をリアルタイムに計算しています。
料金計算は取得した宿、航空券の原価の足し算に加えて諸税の計算やヤフーパックとして還元するポイント数の計算なども行います。
ポイント計算はヤフープレミアム会員向けでは4%の上乗せ還元を定常的に行っており、ユーザー属性による料金出し分けも必要になっています。
これらの料金・在庫のデータ取得と料金計算は情報処理の量が多くとても時間がかかります。
また、組み合わせによって異なる価格調整値が存在し、旅行代金が変動します。
つまり安い順などの並べ替えはすべての組み合わせを計算してみないと正確な順番は分からないのです。
そのためDPを扱っている他社の検索画面も同様ですが、この検索結果を表示するまでの待ち時間を少しでも短く体感してもらうためにローディング画面を挟んでいます。


検索システム

検索というとApache Solrのような検索システムをイメージする方も多いと思いますが、DPではあえて利用していません。
料金計算の元となる各種データのうち、航空券については航空会社への直接オンラインで問い合わせて取得しています。一休からの宿情報については先行してサービス提供を行っていたヤフートラベルの国内宿泊サービス(宿だけの予約サービス)での知見を生かしてデータベース(DB)参照にて実現しています。

Apache Solrなどはキーワード検索のような全文検索で威力を発揮しますが、日ごとや人数ごとに料金や在庫などの情報が異なり更新頻度も激しい上に、主に宿泊日やエリア、禁煙ルームといった属性の絞り込みが多用される旅行商品の検索とはあまり相性が良くありません。DPではリレーショナルデータベース(RDB)に検索専用のテーブルを構築して実現しています。


キャッシュの追加

開発当初から旅行代金計算にかかる時間は懸念しており、ローディング画面を挟む対策を行っていました。
しかし、開発後半になりシステムが動くようになった段階でパフォーマンスを計測をした結果、とても利用に耐えられるものではないことが明確になりました。
料金を構成する項目数やその設定軸の細かさ、システム内でのレイテンシの予測ズレなど当初の想定と違い、複合的な原因でパフォーマンスが悪くなっていました。

開発期間中は各社の検証環境に接続していたのもあり、本番環境でも同様なパフォーマンスなのかヒアリングを実施した結果、やはりこのままではリリースが難しいと判断しました。
この課題はキャッシュシステムを追加することで速度向上を行い、解決しました。

キャッシュを追加する際に問題となったのは価格の正確性と表示速度のバランスです。
料金計算はリアルタイムに行えば正確ですが、毎回計算をしていては表示速度が遅くなってしまいます。
そこで各料金が変動しないであろう期間を予測し、計算した結果をキャッシュデータとして保存し、次回以降の表示速度向上に利用しています。
変動しないであろう期間を長く取れば、それだけキャッシュのヒット率は上がり、表示速度は向上します。
しかし、想定が外れて料金が変動してしまえば、正しい情報をユーザーに提供できないというリスクが発生します。


ヤフーパックでは予約する商品が絞られた段階で、最新の料金や在庫情報を必ず取得するようにしています。
取得するタイミングはJAL、ANAそれぞれ航空会社側システムの都合などにより異なるタイミングとなっています。
キャッシュデータの有効期間も各社の仕様に合わせた形で構築しており、2社似たような画面遷移をしていても裏側はそれぞれのシステムに合わせて最適化したまったく別の仕組みとなっています。
このような仕組みにすることで、ユーザーへの影響を最小限に抑えた上でパフォーマンスが大きく改善し、無事にリリースすることができました。


おわりに

JALとANAという国内2大キャリアとDPサービスを同時リリースするのは国内初ということでした。
2社同時に進めることで仕様決めなどスムーズに進められる部分もありましたが、各社の方針やシステム都合など異なる部分も多くキャッシュを利用している画面の様に見た目は似ていても裏側は全く異なっている部分も多々あります。

いろんな課題を乗り越えてリリースを迎えたヤフーパックはサービスとしてやっとスタートラインに立ったところです。
検索システムも現状はRDBで実現していますが、機能追加などに合わせてSolrの様なソリューションを取り入れていくことも十分考えられます。
まだまだ工夫できることや追加したい機能などが山盛りです。
ヤフーパックはこれからも進化し続けていきますのでご愛顧のほどよろしくお願いします。

Yahoo! JAPAN Advent Calender 2019(外部リンク)を開催します。12月1日から25日まで毎日ブログを公開予定です。詳しくはリンク先をご確認ください。
Qiitaアカウントがない方はこちらのRSSもありますのでぜひ購読ください。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加