読者です 読者をやめる 読者になる 読者になる

Alpaca技術ブログ

AIと超高速データストレージを駆使して新しいトレーディングを創る

MarketStore、或いはアルパカの時系列データストレージと配信

f:id:alpacablog:20160519184216j:plain (Photo by Greg Palmer)

こんにちは。アルパカCTOの原田(@umitanuki, github)です

アルパカのプロダクトはマーケットデータ、それも主に時系列データを扱っています。フィンテック領域でビジネスを拡大する中で、この時系列のマーケットデータに関する諸々の問題が明確になってきました。一般に共通するものもあれば、弊社のアプリケーションにユニークなものもありますが、おおまかに下記のようなデータに関する需要が金融市場におけるアプリケーションにあると思います。

  • 最小のリソース、最小のレイテンシで最大のスループット
  • 増加するユーザとアルゴリズムの数、そして拡大する資産クラスに対するスケール
  • 信頼性の高いマーケットデータの配信

最小のリソース、最小のレイテンシで最大のスループット

スピードは大事です。もしチャートの読み込みが遅ければ、アプリケーションは使われなくなってしまうでしょう。弊社では、数千人の人が同時に、異なる分足チャートで10年以上過去に遡りながら、どのような値動きがあったか、アルゴリズムはどう動いたのかグリグリスクロールしてを検証していくUIを作ったりしています。つまりスピードはユーザ体験に大きな影響を与えます。さらにライブテストの運用にも大きく影響します。時系列データは、ソートや時間集計などの特殊な操作が必要となり、汎用向きのデータベースでは高いパフォーマンスを達成するのが難しいことが知られています。多額の金額を投入して高いハードウェアでパフォーマンスを達成していくことも可能ではありますが、ウチのようなスタートアップのやることではないと思います。むしろ技術の会社として、最小のリソースを最大限に活かせる工夫を凝らしています。リソースは計算リソースだけではありません。人的リソースも重要なリソースです。ソフトウェアの運用メンテコストは言うまでもなく、周辺のアプリケーションを素早く開発していくためにデータの出し入れが最大のパフォーマンスで行えるかどうかは開発リソースを最大限に活かせるかに関わってきます。

増加するユーザとアルゴリズムの数、そして拡大する資産クラスに対するスケール

我々はニッチな問題からスタートはしましたが、お陰さまで日に日に大きなユースケースや問題に直面するようになっています。ユーザーベースは増加する一方、いずれは100万単位にサービスを提供したいと思っています。たった数万人のユーザーベースですら、たいてい一人が10ぐらいのアルゴリズムを作るとして数十万の投資アルゴリズムが我々のシステムで絶えず走り続けることになります。今までどのようなヘッジファンドや投資銀行がこのようなスケールで投資アルゴリズムを走らせたでしょうか?一つ一つの投資アルゴは一人の人間が常にチャートをウォッチしているようなものですので、各アルゴリズムにも適切に最新のデータが行き渡らないといけません。そして我々が走らせるアルゴリズムの数が増加する一方で、サポートする資産クラスについても当初のFXにおけるメジャー通貨ペアから、100近い広範囲の通貨ペア、そして現在日米の株式対応を進めており、果てはETFオプション先物やビットコインまでを視野に入れています。データのスケーラビリティのためにビジネスの拡大が止まることだけは避けなければなりません。

信頼性の高いマーケットデータの配信

データは刺し身のようなものです。できるだけ鮮度が高いうちに提供するのが一番。上記の通り、弊社では大量の投資アルゴリズムという生き物が大きな口を開けてマーケットから出てくる最新のデータを待っています。適切なデータを正しい宛先に最も早く届けることができなければ、アルゴリズムが生成できるデータの価値もどんどん低下してしまいます。特に我々のディープラーニングベースのアルゴリズムは一つ一つが非常に計算ヘビーな処理になっており、一箇所で全てを処理することは不可能のため、処理を複数のサーバに分散していますが、そのような状況下においてデータと処理を最も近づけておくことの重要性は強調してもしきれません。他方において、そのマーケットデータを外から取り込み続けるわけですが、こちらも増加し続ける資産クラスに対して最短で取得・配信を行わなければなりません。最後に、これが金融市場のアプリケーションである限り、お金が絡むシステムです。正確なデータを正確な計算に配信できなければ、弊社のビジネスが信頼を失うことは明確です。

どうやって解決するのか?

今日現在のアルパカのシステムは、昨年クローズドベータを始めた時から、数百行のPythonスクリプトで取り急ぎデータの管理と配信を行ってきました。それはそれで、スタートアップの戦い方として小さく始めて問題の大きさを測るという意味で悪くはないものでした。しかし、すぐにこの巨大な問題に改めて取り組まなければならないということが明確になってきていました。

というわけで、数ヶ月前にチームで集まって長い議論をしました。最近USチームにジョインしたChrisは、ミッションクリティカルな防衛システムとIBM/DB2の開発経験を持っていました。Lukeは90年台に流体シミュレーション用の数千台の計算クラスタを組んだこともあり、その後Greenplumというビッグデータ用のデータベース製品を作り上げ、成功に導いています。私自身はビッグデータとかデータサイエンスと呼ばれる前からデータ主導のアプリケーションを多数開発しましたし、Greenplumに入ってからはデータベースのコアエンジンのアーキテクチャの面倒を見ていました。特にその頃、金融関係の顧客も多く、この領域のアプリケーションがどのようなデータの問題に晒されているか、たくさんの知見を得ました。こういうメンツの知恵を振り絞って、MarketStoreという我々のデータベースを作るというアイデアに至りました。これは上記のような特有の問題を解決するために、最新の技術を多数取り入れて設計されています。

要件と設計

まだまだ荒削りな状態で設計を完了したとは言いがたい状態で、使いながらさらにこの領域のデータの問題を理解しながら改善していくことになりますが、下記に幾つかの設計ゴールを挙げておきます。

  • 数十万の時系列を配信、リアルタイムでのアップデート(1万以上のシンボル×数種類の時間軸)
  • 10年以上にわたる、秒レベルでのデータ
  • 数十万のクライアント(アルゴリズムやチャート)からの過去データクエリ及びリアルタイム配信
  • 各時系列における最速で秒頻度での更新
  • ミリ秒以下のクエリレイテンシ
  • 最小のハードウェアリソース使用
  • 最小のマニュアル運用コストでの高可用性

基本的にこの要求はいわゆる「ファストデータ」と「ビッグデータ」という、通常別々の製品で扱うべきものを一つの仕組みで扱うということを意味しています。一般的には、一方にフォーカスすることで他方を捨てなければデータベースとしては生き残れません。それを実現しようというのは私のデーターベース開発経験から言っても非常に難易度が高いことだと思います。MarketStoreがそういう要求の中で上記を満たせて中途半端にならずに済むのは、これが金融マーケットデータを扱うことに特化しているからです。汎用目的のデータ製品ならまずプロダクトマネージャに却下されてしまうような内容だと思います笑。

現行のスクリプトにはPythonインタプリタに由来する同時実行性やメモリの問題が多々あり、MarketStoreはGoで記述されています。設計的にはSSDやスパースファイル等の最近の下層技術、あるいはグローバルのオブジェクトストレージ等を前提としてフル活用するようにしています。クライアントからのクエリはよくあるデータベースのパーサ/プランナ/エグゼキュータというパイプラインを通って処理されます。クライアントのインターフェイスにはWebSocketを含むHTTP(現在は1.1ですが2.0への対応も予定)を採用しています。

MarketStoreのMVPも先日完了し、US株を始めとしてより広いデータに対応できるようになりました。アルパカのサービスを提供しながら、常にユーザの方々の意見を取り入れてリアルな問題解決を開発していますが、このデータ・ストレージのおかげでアプリケーション開発コストは劇的に改善し、次々に新しい試行錯誤を行っていける環境が整いつつあります。マーケットデータを使ったアプリケーションを開発するのは簡単に聞こえるかもしれませんが、MarketStoreのようなものを使わずに、頻繁に更新される数万の銘柄/時間軸データの時系列の中の一つを取り出して何かをするというようなことは実はそれほど気軽なことではないのです。

代替策

世の中にこんなにいろいろなデータ製品があるにもかかららず何故独自の開発をしているのか、と疑問に思う方もいるかもしれません。一つずつ見てみましょう。

リレーショナル・データベース

PostgreSQLやMySQLのようなRDBはアリな選択肢だとは思いますし、私は好きです。とはいえ、順序を前提としない関係代数の仕組みの中で順序を全体とする時系列データを最適化していくのはかなり難易度が高くなっています。あと、SQLはこの場合全く必要ないです。

Hadoop

Hadoop、特にHDFSはあらゆるタイプの最近のデータプラットフォームとしては良いチョイスです。特に巨大なデータを放り込んで放置しておくという運用にはうってつけだと思いますが、ウチの場合は頻繁にクエリするようなワークロードであるのと、置いておくだけならS3があるので特に困っていません。MapReduceやHiveのレイテンシでは我々の要求には全く追いつけませんし、Sparkはk-meansのような複雑な計算を大規模データに対して走らせるのであれば良いのかもしれませんが、ウチではとりあえずそのようなニーズがありまあせん。HBaseは書き込みには非常に向いていますがウチは読み込みがほとんどです。いずれについてもリアルタイム配信はできません。他にいくらでもHadoopソリューションを挙げていくこともできますが、残念なことにプロダクトが多すぎてよくわからなくなっているのと、単純にウチのようなチームサイズでHadoopクラスタを運用するのは面倒だ(面倒そうだ)ということに尽きます。

メッセージバス

もちろんメッセージ配信にはKafkaやRabbitMQという素晴らしい製品があります。まさに配信のためにあるわけです。可用性も高いし管理も容易です。これらを利用することも可能ですが作るのもまた簡単です。特にウチのケースでは、一度配信したものを間違いなく永続化してその後のヒストリカルクエリで一貫性のあるレスポンスを返すという意味においては、メッセージバスはそのようには作られていないです。まあストレージ部分から自前で実装して一通り作っていく中で、Goの同時実行プログラムの容易性を考えると、わざわざ外部のものを取り込んで複雑性を上げる必要はないだろうという結論に落ち着くわけです。

Pandas/DataFrame

DataFrameは偉大ですし、実際ウチでもこれで開発を始めました。元々クオンツの人が作っているだけあって、金融アプリに必要な時系列データ機能は一通り揃っている感じがあります。ただ単純にPandasはバックエンドシステムの一部として利用されるようにはできていない、というだけのことです。実際、MarketStoreのクライアントプログラムはDataFrameとしてデータを再構築できるようになっています。そして、今システムの色々なところで使われている(永続化としての)DataFrameをこれからMarketStoreで置き換えていくことになります。

InfluxDB

比較的新しいこのGoで書かれたオープンソースのデータベースを聞いたことがあるかもしれません。皆が抱えている時系列データベースの問題をオープンなアプローチで解決しようという試みは素晴らしいと思います。ただ、私が以前触った感触では時系列の中でもシステムメトリックスや或いはIoTのようなアプリケーションに向けて作られているなあという印象はあり、金融アプリとしては物足りないところがいくつもありました。テクニカル分析ともなると、移動平均を始めとするウィンドウ処理というのは当然入ってきますが、クエリにそのような拡張を行うところは当時ありませんでした(最近は少し移動平均もできるみたいですが)。あとはやはりメッセージ配信には使えないというはあります。

KDB+

もし金融業界のDBAをやったことがあってこのデータベースの名前を聞いたことがなければモグリと疑って下さい笑。カラム指向、インメモリなデータベースでクオンツのために作られています。ただ、商用製品であるのと、単一ノードで走るスケールしないタイプのデータベースであるため、メモリをたくさん買うという、「札束で問題を解決する」方向性が求められます。

というわけで、世の中には大変多種多様なデータ製品があるわけですが、我々が抱える金融マーケットデータの問題を解決してくれそうなものはなかなか見つかりそうにありませんでしたし、みんなどうしてるんだろうと思ったりしています。そんなわけで少し遠回りしてでもこの分野に労力を割いています。

まとめ

MarketStoreと呼ばれる、弊社独自の金融データストレージの現状をまとめました。この辺の内容はエンジニアの方々にはなかなか興味深いのではと思った次第ですし、皆さんからフィードバックや質問等もお待ちしております。必要があるので作ってはいますが、これが我々のメインビジネスというわけではありませんので、時期が来たらオープンソースするということも考えたりします。しばらくは弊社内でじっくり育てていくことにはなりますが。。。