Open3

金融時系列データの保存方法について、コストと使い勝手の観点から選定

うお~うお~

要件

例として、bitFlyer の約定履歴データは過去30日分しか提供されないため、一定以上過去のデータを分析するためには自前でデータを保存しておく必要がある。

  • 時系列データのため、データは挿入操作ができれば良い(編集や削除はしない)
  • データ分析に利用したいため、指定した2点の時刻の範囲のデータを取得できると好ましい
うお~うお~

フルマネージド RDBMS に保存

当初 IaaS のフルマネージドな RDBMS に保存していた。これは完全に失敗で、まず単純に高い。要求に対しての提供機能が過大すぎるので当然想定コストとのミスマッチが発生する。

データ保管コストだけでなく、データ分析時にかかる通信コストも痛い。

結局のところ時系列データ分析は pandas に頼らざるをえない現実があり、RDBMS を採用しても SQL が使えることに対してメリットがない

うお~うお~

タイムフレームで分割した CSV ファイル形式で S3 に保存

日次なのか月次なのかもっと小さいタイムフレームなのかは要件次第だが、とにかく一定のタイムフレームでデータをファイルに区切り、S3 ないしは S3 互換ストレージに保存する。

とにかくコストが安く、CSV ファイルをやり取りするだけなのでデータの取り回しも平易である。
一定のタイムフレームでファイルを保存する、すなわちファイルの命名規則に時刻情報を含めるようにしておけば、ある程度絞り込んだ範囲のデータのみダウンロードしてくることもできる。細かい絞り込みは pandas でデータを読み込んだ後に行えば良いだろう。

S3 互換ストレージサービスを使えば AWS S3 よりも更に安くなる。Backblaze B2 Cloud StorageWasabi あたりが安い。

データ分析においては CSV ファイルをダウンロードしてきて pandas に読み込ませることになる。データの集計や変形などは pandas で行う。

RDBMS と違って主キーを使った INSERT IF NOT EXISTS ~ 的な操作はできないので、ヒストリカルデータが提供されておらずリアルタイムフィードデータを保存するしかない様なケースでは、どの様に冗長化してデータを保存するかが問題となる。

例えば WebSocket 通信で提供されるリアルタイムフィードデータを受信して一旦ローカルファイルシステムに CSV 形式でデータを保存しておき、日を跨いだ際に前日分の日次データを S3 にアップロードしローカルファイルシステム上から削除するといったタスクをこなす VPS インスタンスを走らせるケースを想定する。

この場合の冗長化としては、複数台の VPS インスタンスを同時稼働させ、S3 上に保存するファイルに VPS インスタンスごとのサフィックスを追加しておく、といった方法が最も単純で効果的である様に思う。

VPS インスタンスの数に比例して保存データ量が増えるため、それらのファイルを統合するバッチ処理を走らせる様にしておけば更に良い。

例えば Backblaze B2 の場合は Vultr など一部提携サービスとの通信料が無料になる ため、そういったバッチ処理は Vultr VPS インスタンスで行う様にしておけばコストも抑えられる。