TKC Works

ギジュツ的なメモ、読書感想文など

Azure CosmosDBとFunctionsのbind & multi insert

速度もデータ量も要求されている時にはAzure Cosmos DBを使いたい。

FunctionsとCosmosDBの統合は公式にサポートされているのでいい感じにサーバーレスな仕組みが作れるかと思った。 が、ドキュメントを見ると1件ずつしかinsertできない。

https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-cosmosdb

やりたいのは↑のサンプルみたいにHTTPトリガーで1件ずつのinsertじゃなくてIoTHubとかEventHubとかと統合して大量データを一気に保存すること。

SDK見てみると、どうやらmulti insertは無いらしい..

Stream Analyticsを使うとできそうだけど、今回はCosmosDBのストアドプロシージャも試してみた。

ストアドプロシージャのコードはほぼ以下の通り、

https://stackoverflow.com/questions/28769507/azure-documentdb-bulk-insert-using-stored-procedure

getContext() からCollection, Request, Responseのオブジェクトを取得して処理を行う。

http://azure.github.io/azure-documentdb-js-server/index.html

クライアント側はこんな感じのコードをFunctionsに書いてやればよい。

const DocumentClient = require('documentdb').DocumentClient

// このリンクのルールを理解するまではこのSDKで何も出来ない…
const sprocLink = `dbs/${dbId}/colls/${collectionId}/sprocs/${spId}`

const client = new DocumentClient(host, {masterKey: masterKey})

// Arrayをいれるとエラーになったので対策
const sendData = {
  docs: []
}

client.executeStoredProcedure(sprocLink, sendData, (err, res) => {
  context.log(err, res)
  context.done()
})

脱webpackerしてみた

今風のフロントエンド開発環境をサクッと構築してくれたwebpackerだけど、(3系からかな?)webpackに関する各種設定が@rails/webpackerパッケージに内包されてしまってカスタマイズがし辛くなっていた。

実際ぶち当たった問題としては、fontファイルが読み込めなかったからresolve-url-loaderを使いたかったんだけど、webpack.config.jsは存在しないので以下のようにゴニョゴニョするという…。 https://github.com/rails/webpacker/blob/master/docs/css.md#resolve-url-loader

今後カスタマイズしたいことが増えてくると面倒くさくなりそうなのでいっそフロントエンドはRailsから剥がして素のwebpackをつかったほうがいいんじゃないかと思ってやってみました。(前からJSのライブラリ使いたい時にそれをwrapしたgemを入れるのも違和感があった)

この辺りを参考にさせていただきました。

ポイントは参考記事にもあるようにjavascript_pack_tagとか無くなるんでwebpackでbuildしたアセットを読み込むためのヘルパーを作成すること。

あとdockerを使っているのでRailsのコンテナとwebpack-dev-serverのコンテナを分離できて、rubyのイメージにnodeをいれたりゴニョゴニョやってたDockerfileがすっきりした。 docker-compose.ymlは以下のような感じになった。

  webpack-dev-server:
    build:
      context: .
      dockerfile: Dockerfile.webpack
    command: yarn run dev
    volumes:
      - .:/work
      - /work/node_modules
    environment:
      NODE_ENV: development
    ports:
      - "8080:8080"

  rails:
    build:
      context: .
      dockerfile: Dockerfile.rails
    command: |
      ash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/work
      - /work/node_modules
    environment:
      WEBPACK_DEV_SERVER_HOST: localhost
      WEBPACK_DEV_SERVER_PORT: 8080
    ports:
      - "3000:3000"

production環境の場合はどうせCDNとかに置いちゃうと思うのでwebpack buildしてコピーしてやればいいと思います。

しばらくはこんな構成でやってみたいと思います。

RedashのAzure Table StorageのQuery Runnerを作った

Redash Advent Calendar 2017 の9日目の記事になります。 作ったのがちょうど12月でまだ空きがあったのでついでに登録してみました。

使えるデータソースが多いことを理由にRedashを導入しようと動いているところですが、Azure Table Storageには対応してなかったので作りました。

作ったのは以下です。しばらくRubyとJSの仕事が続いていて、Pythonは素人レベルですがなんとかなりました。

github.com

Table Storageについて

  • 安く大量にデータが格納できるらしいNoSQL
  • ただのKVSってわけではなく検索クエリも使える
  • 以前はストレージアカウント配下のサービスだったと思いますが、いつの間にかCosmosDB配下になっていました。
  • 廉価版CosmosDBってことでいいのかな?
  • 詳しくはドキュメント見てください

Query Runnerの作り方

アドベントカレンダーの前日の方がQuery Runnerの作り方を書いてくださるようなので簡単に。 それみて後で修正点いろいろ見つかりそう汗

このページと他のquery_runnerとかの実装みればなんとなくわかります。

redash/query_runner ディストリ以下にファイル作って、 BaseQueryRunner を継承して、対応したいサービスやミドルウェアのライブラリを使って必要なメソッドを書くだけです。

忘れがちなのは最後 register(TableStorage) のようにクラスを登録することと、 redash/settings.pydefault_query_runners に作ったQuery Runnerを追記することです。

あと、めんどいのは対応したいサービスやミドルウェアの型とRedashの型を合わせるところです。 TYPE_INTEGER みたいな感じで定義されているので対応付けします。Jsonエンコードもできる必要があります。

今回のTableStorageの場合は azure.cosmosdb.table.models.EntityProperty のオブジェクトで返ってくることがあったりそうじゃなかったり、 datetime.datetimeJson対応でハマりました。

まとめ

RedashはPython Sqriptがあるので何でもできるけど、Query Runner作成もなんとかなる。

GitlabのMySQLをPostgreSQLに移行した

Gitlabの8系までは大丈夫だったと思うけど、9系に上げると4バイト絵文字の読み書きでエラーになるようになってしまった。

文字コードをutf8mb4に変えてみたが、うまくマイグレーションできなかったのでいっそPostgreSQLに変えてみた。

gitlabのリポジトリに移行ツールがあったのでさくっと対応できた。

github.com

やってることは単純で、

  1. MySQLからデータをdump
  2. dumpしたファイルをPostgreSQL用に変換
  3. PostgreSQLにインポート

他のRailsアプリケーションでも使えそう。

Docker for Macのディスク問題への対処

問題

Docker for MacでコンテナをVolumeして使うと辛いですよね。遅いし…。

特に困ったのはイメージビルド時に母艦のディスクは余ってるのにディスクが足りないというエラーがでてDockerfile内のapt-get updateすらコケるようになったこと。

https://github.com/docker/for-mac/issues/371

このへん見てqcow2の圧縮やらイメージ、コンテナの削除やっても解決しませんでした…。

結論

開発環境をLinuxデスクトップに移した。

  • 仕事は主にWebアプリの開発、たまに機械学習の手伝いなので特に困らない。
  • iOSアプリの仕事が来たら困るけど、たぶんこない。

詳細

マシンについて

  • MBP2015を使っていたが会社に使ってないデスクトップ(Dell Vostro470)が眠ってたのでもらった。
  • Ubuntu Mate 16.10を入れて使っている。
  • メモリは8Gあったけどスロットが空いてたので買い足して24Gにした。
  • CPUはi7-3770(3.4GHz8コア)
    • 5年前くらいのマシンでもそれなりに快適。やっぱりデスクトップ用とラップトップ用のCPUは違うなあ。
  • SDDじゃなくHDDなのはちょっと残念。

代替アプリ

  • SlackとかDropboxとか割とLinux版もある。
  • VSCodeとかGitKrakenとかElectronのおかげでLinuxでも使えてありがたい。
  • PostmanとかChrome Appもそのままで助かる。
  • iTerm2→Guake Terminal+tmux
    • 元々iTermもそんなにカスタマイズしてなくてタブとペインの分割があればよかった
    • terminatorもよかったけどGuakeのほうがかっこよかったので。
    • Guakeはペインがないぽいのでtmuxで対応
  • Evernote→NixNote
  • Dash→Zeal
  • Alfred→Albert
  • Clipy→Diodon
  • MS Office→Libre Office or Office Online
  • アプリじゃないけどpbcopy→xsel

感想

  • Macじゃなくても割と大丈夫だった。
  • Dockerのおかげでどの環境でも同じように動かせるはずだったんだけど…。
  • Appleは頑張らないとエンジニアが離れていくかもなあ。