3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Firebase RealtimeDatabaseに大量データ投入 - その4 -

Last updated at Posted at 2018-07-12

GYAOのtsです。

#経緯
前回の投稿で一通り機能は揃ったので、テストや監視を設定してみる。

今回はかなり奮闘した。負荷テストの500万件登録は何度やったことやら。クラウドの使用料金がどこまで行くか心配。。。

#監視
functionsのログはすべてCloudLoggingに集約されるので、指標を作成し、それに引っかかったら通知を出す設定を行う。
通知先はSlack。

  • stackdriver Loggingで下記のフィルタを設定
フィルタ設定
resource.type="cloud_function" OR resource.type="gcs_bucket"
severity>=WARNING
  • 指標を作成する
スクリーンショット 2018-07-12 14.07.12.png
  • 指標から通知を作成する
スクリーンショット 2018-07-12 14.10.25.png スクリーンショット 2018-07-12 14.18.32.png
  • 通知先をSlackに
スクリーンショット 2018-07-12 14.19.55.png

完了。

#Unit test

  • ディレクトリ構成
スクリーンショット 2018-07-11 15.58.32.png
  • テストコードと起動
unit.box.aggregator.test.js
const test = require('ava');
const sinon = require('sinon');

const authenticate = require('../index').authenticate;
const StateContext = require('../state-context');
const userState = require('../user-state');
const messageState = require('../message-state');

test.cb('StateContext.getState: should get the correct state messages.', t => {
    t.plan(1);
    const stateContext = new StateContext('messages/test.json');
    t.is(typeof stateContext.getState(), typeof messageState);
    t.end();
});

test.cb('StateContext.getState: should get the correct state users.', t => {
    t.plan(1);
    const stateContext = new StateContext('users/test.json');
    t.is(typeof stateContext.getState(), typeof userState);
    t.end();
});

test.cb('StateContext.getState: should throw the exception because of invalid directory.', t => {
    t.plan(1);
    try {
        new StateContext('hoge/test.json');
    }
    catch (e) {
        t.pass();
        t.end();
        return;
    }
    t.fail();
    t.end();
});


and so on...
  • 結果
$ npm t

> functions@ test /Users/tstakano/IdeaProjects/BoxAggregatorFunctions/functions
> ava



  10 tests passed

sinonを使ってオブジェクトのモックを使用したテスト(オブジェクトの振る舞い偽装してのテスト)を行おうと思ったが、大したことはやっていないのと、それをやると偽装だらけになってあまり旨味がなさそうだったので(特にDB周り)、下記の方針で進めた。

  • ロジックを書く場合は極力関数として出せるものはexportsし、test対象。
  • ロジックのあまり入っていないevent triggerの部分やDBに近い部分は無理やりunitテストしない。

なので、cron起動の認証周りと上記のstateパターンもどきのオブジェクト切り替えロジックをテスト対象とした。

#Stress Test
高負荷時の挙動を見るためにストレステストを行う。
シナリオは10000行のjson linesが1ファイル記述されていて、それが連続で500ファイルcloud storageにアプロードされる。
結果500functions起動されて、firebaseに対してそれぞれのfunctionが10000件のupdateを試みることになる。

  • ファイル作成

dummy-jsonを使用して500万行のjson lines作成する。

$ npm install -g dummy-json
$ vim user.hbs
user.hbs
{{#repeat 5000000 comma=false}}
{"userId" : "user-{{@index}}", "messageId": "941"}
{{/repeat}}
$ dummyjson user.hbs > user.csv
  • ファイル分割
$ split -l 10000 user.csv test_
for f in test_??;do mv $f $f.csv;done
  • upload

まとめて一気にupload。
スクリーンショット 2018-07-12 12.52.09.png

  • 実行結果

各Functionが10000件ずつさばく。終わるまで20分位。
CloudLogging
スクリーンショット 2018-07-12 12.54.59.png

Firebaseからjsonをexportする。247MBある。。。
スクリーンショット 2018-07-12 12.57.53.png

$ grep -c 'user-' export.json 
5000000

500万件登録済みが確認できた。

#その他

Storageバケットライフサイクル

このままだとStorageにファイルが無限に溜まっていくので、ライフサイクルを設定する。

  • CloudStorageの対象バケットのライフサイクルをクリック
スクリーンショット 2018-07-12 14.23.37.png
  • ルールを追加して完了
スクリーンショット 2018-07-12 14.25.17.png
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?