IPAのデータサイエンティスト スキルチェックリストを読んでみたらとても良かった

はじめに

Twitterにも呟きましたが、IPAITSS+にあるデータサイエンティスト スキルチェックリストを読んでみたら思いの外よかったので紹介記事を書いてみます。

なお、私自身はデータサイエンティストでもデータエンジニアでも特に無いので中の人から見たら現実と相違してるとかはあるかも。

何が良いの?

そもそもこのチェックリストの何を私がそんなに称賛してるかなのですが、みなさん「データサイエンティスト」ってどんな職種だと思いますか?

AIを使いこなして会社の課題を解決する人ですか? データを分析してダッシュボードにする人ですか? データを集計したりビックデータ処理基盤を作る人ですか? あるいはアルゴリズムの研究者ですか?

たぶん、どれも正解です。今の所データサイエンティストはAI/ML/BIに関わる全てを含んで使われることが多いと感じるので、実際の定義はお「そう思うならそうだろ、おまんなかではな」状態です。

そこが曖昧なせいで、周りにもデータサイエンティストになりたいとか雇いたいと言う話もあり、それが叶ったのも見たことがあるのですが求める実際のスキルや働き方が違い不幸になった結果も知っています。

なので、自分が話すときにはせめてアナリスト(ビジネス分析)なのかサイエンティスト(アルゴリズム系)なのかエンジニア(基盤系)なのかは分けて話してましたがオレオレ定義なので定義から説明が必要なことも当然しばしば。

で、たまたまこう言うのあるよと言われて見つけたのがITSS+データサイエンティスト スキルチェックリストです。

このチェックシートの良いところは図のようにデータサイエンティストの領域をフェーズ分けして可視化した上で、チェックシートではデータサイエンス力、データエンジニアリング力、ビジネス力 を大項目としてカテゴライズしていることです。

f:id:pascal256:20200524163645p:plain ref: ITSS+/「データサイエンス領域」 タスク構造図(中分類)

これによってフワッとしてた「データサイエンティスト」の人物像を明確にし、どのフェーズを動かす人間が必要でそれにはどのスキルセットが必要かがクリアになります。

スキルレベル判定基準

スキルセットは以下のような方法で評価していくようです。判定方法は各項目を何%満たしてるかでチェックするようなので機械的で良いですね。各領域に求められる詳細な説明もPDFにはきちんと載ってますので要参照。

  1. Senior Data Scientist(業界を代表するレベル)
  2. Full Data Scientist  (棟梁レベル) 
  3. Associate Data Scientist(独り立ちレベル)
  4. Assistant Data Scientist (見習いレベル)

スキルカテゴリ一覧

データスキルチェックリスト自体はこちらにありますが、PDFにあるカテゴリの一覧だけ参考に転載しておきます。 チェックリストは膨大なので読むの大変ですが、そもそもどんなこと書いてあるかはこちらのカテゴリ一覧で雰囲気掴めるかと。

カテゴリ ID サプカテゴリ 項目数
データサイエンンス力 1 基礎数学 24
2 予測 23
3 検定/判断 7
4 グルービング 12
5 性質・関係性の把握 15
6 サンプリング 5
7 データ加工 15
8 データ可視化 38
9 分析プロセス 4
10 データの理解・検証 23
11 意咲合いの抽出、洞察 4
12 機械学習技法ー 39
13 時系列分析 9
14 言語処理 16
15 画像・動画処理 10
16 音声/音楽処理 6
17 パターン発見 3
18 グラフィカルモデル 4
19 シミュレーション/データ同化 5
20 最適化 9
デークサイエンスカ項目数 271
データエンジニア力 1 環境構 28
2 デーク収集 18
3 データ構造 11
4 データ蓄積 18
5 データ加工 14
6 データ共有 15
7 プログラミング 24
8 ITセキュリティ 16
データエンジニア力項目数 144
ビジネスカ 1 行動規範 15
2 契約・権利保護 9
3 論理的思考
4 着想・デザイン 7
5 課題の定義 17
3 データ入手 3
7 ビジネス観点のデータ理解 6
8 分析評価 3
9 事業への実装 7
10 活動マネジメント 30
ビジネスカ項目数 113
スキル項目数合計 52S

使い方

個人的にはまず自社が必要としているデータサイエンティストのスキルを自分たち自身が理解するために利用することが第一でしょう。時間と予算が無限にあるならば全てを100%満たせる超人を揃えることも夢では無いかもしれませんが、時間と予算には限りがあるので大抵は夢です。

なので、そもそもどう言うスキルセットの人間が必要なのか? どのタイプのスキルは社内人材で転用できそうなのか? どのスキルは外部から新規雇用をするのか? どのスキルは外注するのか? など人事/採用的には考える必要がありますよね。

特に「最初の一人目」は薄くても良いので全領域、特にビジネス力が必要です。プラットフォームが「あれば」データが分析できる人間も、エンジニアリングだけができる人間も最初の一人目としては厳しくて、それらが見よう見まねで良いからできてビジネス側と会話してソリューションに落とし込める人間が必要です。もちろん、最初からチームを組んで分担できればなお良いですね。

だいたい不幸になるケースは最初の一人目にそもそも自社にデータ分析基盤が無いのにサイエンティストを雇うとか、データエンジニアだけ雇って基盤は作ったけどこのあとどうしよう? となるパターンです。こういったフレームワークを活用すればそのような不幸なミスマッチを避けやすくなります。

こうして採用戦略/育成戦略を立てやすくなるのが企業側のメリットですね。

もちろん、被雇用者側にもメリットはあって自分のスキルを可視化する事でどこを伸ばしていくのか、どこを強みとして押していくのかを整理してキャリアパスを作りやすくなります。

こう言ったみんなで共通の認識を作るという点に関してはIPAのような公の機関が出してる「標準」あるいは業界団体やベンダー/コンサルが作ったフレームワークが役立ちます。

まとめ

「標準」と聞くとやっぱりプロセスが重いとか古臭いとかで軽視しがちな所もありますが、IPAITSSにしろ共通フレームワークにしろカスタマイズするにしても軸として採用しとくと色々便利だったりはします。

特に、スキル分類とかは自社や自分自身で組み上げたオレオレ定義を使うよりは、ある程度大きな団体が作り普及した標準ないしはデファクトスタンダートを採用する事でスキルの可視化やコンバートがしやすくなり評価や採用/転職に活用しやすくなるので積極的に使いたいですよね。

とはいえ、ITSSv3 個人的にはちょっとだけ古いとやはり思うのでITSS+に書かかれてる内容やDEVOPS, クラウドインフラ, スマホアプリ開発などある程度トレンドを反映したv4をそろそろ作ってくれないかなと期待する今日この頃です。

それではHappy Hacking!

参考

Microsoft Build 2020に参加してきた

実は去年に引き続き、なのですがMicrosoft Build 2020に参加してきました。 と言っても今年はコロナの影響でオンライン開催。

f:id:pascal256:20200521153350p:plain f:id:pascal256:20200521153313p:plain f:id:pascal256:20200521153210p:plain

初の大きなオンラインイベントということもあり、48時間耐久レースということもあり、なかなか楽しめました。とりあえず自分のツイート+αをまとめてみました。 togetter.com

今回は大手のオンライカンファレンスという事でTeamsやSkypeを駆使ししたセッションになってるのが印象的でした。MSだからZoomではないのですw

Hanselmanとゆかいな仲間たちのデベロッパーキーノートは内容ももちろんですがWFHのネタがいっぱい散りばめられてて面白かったですね。キーノートの最中に子供が映り込んだり、自分をバーチャル背景に写してこっそり休憩したりw

キーノートに関しては下記のブログが爆速でまとめられています。

blog.azure.moe

個人的にはWSL2が思った以上にマイクロソフトの中で基本的な開発ツールチェインとして組み込まれたことですね。Visual Studioとかともきっちり統合されています。

あと、Windows Terminalの正式リリースやパッケージマネージャであるwingetも大きいですよね。最近気になってるPowerAppの話も聞けてよかったです。

Daprを今までIstio的なものと思ってたのですが、それとも少し違いそうなので少し触ってみたいとも思いました。

JavaGCPがメインなのであまりMicrosoft製品をガッツリ使うことは少ないのですが、やはりこういうセッションを聞くと楽しくなりますねー。情報盛り沢山でBuildは良い。。。

コロナの影響下でみんな大変ですが、こうしてカンファレンスにオンラインでも参加しやすくなったのはメリットですね。次はGCPNext OnAir2020かな。

それではHappy Hacking!

参考:

DockerでCucumberのQuickstart環境を作ってみた

はじめに

BDDなe2eテストと言えばやはりCucumberですよね。

Gherkinを使って自然言語のようにテストケースが書け、具体的なステップをRubyJavaで書けるので非常に便利です。

今回、久方ぶりにCucumberを使う必要がありそうなので便利そうな設定をいくつか入れてDocker化しておきました。これでRubyとかが入ってない環境でも問題なく利用できます。

今回実施してる設定は以下の通り

  • ChromeのHeadlessモードを使ったテスト
  • デバッグ用にオプションで指定したらChromeGUIモードで起動するように設定
  • テストに失敗したら自動的にスクリーンショットをとってテストレポートに含めるように設定
  • Dockerコマンドのラッパースクリプトとしてqcmbコマンドの作成

以下のGitHubリポジトリに置いてあるのでCloneすれば使えます。Chromeを使ってるのでJSやCSSを実際と違う形で解釈したりレンダリングしないので安心感がありますよね。

github.com

使い方

テストの実行

とりあえずcucumberを実行するなら以下のコマンド。featuresディレクトリ配下のテストを実行.

qcmdは単にDockerのラッパーコマンドで実際はdocker run -it --rm -vpwd:/usr/src/app koduki/cucumber cucumberを実行しています。

$ ./qcmb

標準出力ではなくHTMLでレポートが欲しい時は下記のようにCucumberのコマンドを実行。出力先はreportを前提にいくつかの設定がされているので注意。

$ ./qcmb --format html --out report/index.html 

テストが失敗した時のスクリーンショットも上記のreportディレクトリに出力されます。

ディレクトリを削除したい時はcleanを実行

$ ./qcmb clean

GUI mode で起動

CI/CDで利用することを考えるとヘッドレスモードがベストなのですが、たまにデバッグGUIモードでChromeを立ち上げたい事もあります。

DockerはCLIベースの環境ではありますが、LinuxなのでX11をホスト側に飛ばすのは簡単にできます。

Macでの準備

MacX11とProxyをインストールします。

$ brew install socat
$ brew cask install xquartz

Xquartzを起動してXteam を xquartz上で開きます。

open -a XQuartz 

パーミッションを許可してProxyをXteam上で起動します。

$ xhost + 
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:/tmp/.X11-unix/X0

qcmbコマンドの--Xheadless=falseオプションを指定して起動します。スクリプトの中で環境変数DISPLAYにホストマシンのIPアドレスなどを連携しています。

$ qcmb --Xheadless=false

設定の解説

support/env.rb

Docker内だとChromeを実行しようとするとDevToolsActivePort file doesn't existが出ます。そのため--no-sandbox を有効にする必要があります。 また、環境変数に応じてHEADLESSモードとGUIモードのそれぞれが選べるようにしています。

require 'capybara/cucumber'
require 'webdrivers'

Capybara.register_driver :docker_chrome_headless do |app|
  browser_options = ::Selenium::WebDriver::Chrome::Options.new
  browser_options.args << '--headless'
  browser_options.args << '--no-sandbox'
  browser_options.args << '--disable-gpu'
  browser_options.args << '--window-size=1920,1080'
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: browser_options
  )
end

Capybara.register_driver :docker_chrome do |app|
  browser_options = ::Selenium::WebDriver::Chrome::Options.new
  browser_options.args << '--no-sandbox'
  browser_options.args << '--disable-gpu'
  browser_options.args << '--window-size=1920,1080'
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: browser_options
  )
end

def driver
  is_no_headless = ENV["CHROME_NO_HEADLESS"]
  if is_no_headless then :docker_chrome else :docker_chrome_headless end 
end

Capybara.configure do |config|
  config.default_driver    = driver()
  config.javascript_driver = driver()

  config.app               = nil   
  config.run_server        = false
end

support/screenshot.rb

Cucumberのテストが失敗したときに自動でスクリーンショットをとってテストレポートに埋め込むようにしています。

そもそもsupport配下にあるRubyスクリプトは名前に関係なく読み込まれます。これを利用してこの中にフックポイントであるAfterを追加してシナリオ終了後の動作を記述します。 あとは見た通りですがシナリオが失敗したときに、スクリーンショットをとってレポートに埋め込んでいます。

After do |scenario| 
    if scenario.failed? 
        path = "report/#{scenario.__id__}.html"
        page.driver.browser.save_screenshot(path)
        embed(path, "image/png")
    end 
end%

例: テストレポートとスクリーンショット

f:id:pascal256:20200507092702p:plain

まとめ

かなり久しぶりのCucumberだったので結構調べながら作りました。

Cucumberは10年経ってもやはり現役で多少は競合はあるものの圧倒的なシェアは流石ですね。Gherkinは仕様記述言語とまでは言えないもののログインとかの動作の意味が厳密に定義されるので自動テストをしなくてすら有用な文法だと思います。この手のツールを使ってテストケースと実際の自動テストの実行の解離が小さくなることがやはり良いですよね。

それではHappy Hacking!

参考リンク

メインフレーム、無停止サーバ、クラウドにおける信頼性

メインフレームの異常処理」という記事が話題になってましたがとても面白かったです。 qiita.com

せっかくなので自分が知ってる範囲で各システムの信頼性における考え方を書いてみました。特にシステムが死んでも仕掛かり中のプロセスが正常完了する事を「無停止システム」としてフォーカスしています。 詳しいわけじゃないからあまり詳しくは話せないので、指摘とか頂けると嬉しいです

メインフレーム

  • ホスト機/汎用機とも。国内の富士通とか日立はIBMアーキテクチャをベースにしている。独自進化部分もあるけど。NECとかユニシスはまた別アーキテクチャ
  • 金融や行政系を中心に現在もたくさん利用されている
  • Fail Softに基づいたハードレベルの冗長化や障害時の切り離し
  • 単独マシンで信頼性を実現。ハードウェアレベルのクラスタ機能もあるのでさらに複数マシンを使ってさらに信頼性を上げることも可能
  • ハードウェアのエラー時の処理をハンドリングする仕組みを用意している
  • 逆に言えばアプリケーションエンジニアがハードウェア障害を意識する必要がある
  • z Systemなんかは現代でも最高スペックのマシン。DockerとかLinuxを動かすことも実はできる
  • 単独メーカで全てを製造しているのでシステム全体で一貫したセキュリティモデル/信頼性モデルが構築できるのは魅力

HPE NonStopサーバ

  • Tandem)とも。銀行のATM、証券売買、クレジットカード処理と言ったメインフレーム以上の無停止性が要求される金融トランザクションを中心に利用
  • Fault Tolerantに基づいたハードレベルの冗長化や障害時の自動切り替え
  • 複数マシンを束ねてシステムの信頼性を実現。(少なくとも現代では)ソフトウェアが中心の信頼性
  • プロセスペアという仕組みを使いメインのプロセスをサブプロセスで監視し問題があれば別サーバで動かす
  • CPUは非同期なので性能は出しやすい
  • OSは独自。旧来からのGuardian環境だけではなく、POSIX風のOSS(Open System Services)も使えてJavaとかKVSも動く
  • Java言語ライブラリやJavaEEなどの内部実装をプロセスペアを発展させたTMF やTS/MPで書き換えてより高速/高信頼な実装を実現している
  • 文化的にはOSからパッケージ、アプリケーションまでプロセスペアやTS/MPを活用して無停止性をキープする事を強く意識している
  • 専用ハードウェアを必要としていたが、現在はソフトウェアベースになっておりx86はもちろんVMware上でも同等の信頼性で動作する

Stratus FT Server

  • Strutsじゃないよ。ストラタス。銀行のATM、証券売買、クレジットカード処理と言ったメインフレーム以上の無停止性が要求される金融トランザクションを中心に利用
  • NEC ftServerもあるけど違いは良く知らない
  • Fault Tolerantに基づいたハードレベルの冗長化や障害時の自動切り替え。
  • 複数マシンを束ねてシステムの信頼性を実現。ハードウェアが中心の信頼性
  • ロックステップ処理と呼ばれるCPUレベルで同期しながら処理を実行するので片方が死んでも処理を継続できる
  • もちろんHWの交換はシステムを止めずに実施が可能。
  • OSはVOS(Virtual Operation System)。WindowsRed Hat Enterprise Linuxなどをサポートしている。VOSとかだとPL/1とかCOBOLで開発
  • 専用ハードウェアだが、汎用OSも動くのは魅力的なポイント

オープン系: クラスタ

  • ここではOSレベルのクラスタシステム. 今でもx86系で冗長構成を組む一般的な方法の一つ
  • Fail Overを基本としたマシンレベルの冗長化や障害時の切り替え
  • 複数マシンを束ねてシステムの信頼性を実現
  • アクティブ/スタンバイを基本として障害時にシステムを待機系に切り替える。ただしFTサーバとは違い分オーダーの時間がかかり実行中の処理もエラーになる
  • OSはUnix/Linux/Windowsなどなど。
  • システム構成もシンプルで費用も安いが原理的に無停止稼働ができない

オープン系: 負荷分散(シェアードナッシング)

  • ここではロードバランサに繋がった負荷分散のシステム。Webサーバを中心に一般的
  • システム全体でFault Tolerant/Fail Softを目指すマシン単位の冗長化
  • 複数マシンを束ねてシステムの信頼性を実現
  • アクティブ/アクティブ構成なのでサーバ障害時には対象システムを切り離すだけで良いので運用が非常に楽
  • WebやAPサーバなどステートレスなサーバでは無停止が実現できるが、DBなどステートフルなシステムには冗長性の観点では単純適用できない

クラウド/仮想環境: Live Migration

  • クラウドインフラやVMwareで実施されるHypberviosrレベルの信頼性確保技術。クラウドを支える技術として裏で使われてる
  • Hypberviosrを抽象化しているのでハードウェアレベルの個々の故障を見えなくするマシンレベルの冗長化
  • 複数マシンを束ねてシステムの信頼性を実現
  • 例えばGCPの場合は稼働中にゲストOSのメモリコピーを行いVMの停止を極小にすることでアプリレイヤーからは遅延に見える程度の無停止性を実現している
  • 信頼性の責務をOSより下のHWとOSより上のアプリケーションで明確に分離できるのが特徴

ソフトウェア: Jakarata EE/EJB

  • OSではなくミドルウェアレベルの信頼性。
  • 分散アプリケーションを実装しシステムとしてのFault Tolerantを目指すマシンレベルの冗長化
  • 複数マシンを束ねてシステムの信頼性を実現
  • 基本的にはEJBでの信頼性確保技術としてはフェイルオーバーとリトライがある
  • フェイルオーバーはエラー時に透過的に別のサーバで実行される。ただしDBなどトランザクションは対応していない
  • トランザクション処理はロールバックされるのでリトライを実行することでシステム全体としての無停止性を確保できる
  • ただし、実際のアプリ実装ではシステム側でのリトライは運用課題も多いので素直にユーザにエラーを返すケースも多い。システム間接続だと場合による。
  • EJBに代わり現在主流のCDIには同等機能はないがMicroProfileのFault Toleranceでエラー時の処理を記述するフレームワークが追加される
  • Weblogicなどはデプロイや障害時のフェイルオーバを含めてミドルウェアレベルの無停止を標榜しているが、最近はJavaEEで頑張らずシステム全体の無停止の枠組みにパーツとして組み込むことが主流

ソフトウェア: Oracle RAC

  • OSではなくミドルウェアレベルの信頼性。OracleRAC(Real Application Cluster)を使った信頼性機能。
  • DBシステムとしてのFault Tolerantを目指すマシンレベルの冗長化
  • 複数マシンを束ねてシステムの信頼性を実現
  • RACはシェアードエヴリシングなので障害時にマシンを切り離しても透過的に利用できる
  • 特にTransparent Application FailoverはSQL実行中のサーバにて障害が発生した場合、SQL文を他のサーバへフェイルオーバー(リカバリ)を実施
  • Oracle DBの専用機能なので適用範囲が限定されるがDBとしての無停止を実現している

ソフトウェア: Erlang/OTP

  • OSではなく言語レベルの信頼性。類似の仕組みをAkkaなどはミドルウェア/ライブラリレベルで実現している
  • 分散アプリケーションを実装しシステムとしてのFault Tolerantを目指すマシンレベルの冗長化
  • 複数マシンを束ねてシステムの信頼性を実現
  • let it crashと呼ばれる思想に代表される適切に落として素早く復旧させる信頼性確保の方法
  • Supervisorがプロセスを監視し、問題があったら自動でフェイイルオーバーやリカバリを行う
  • 個人的にはNonStopのプロセスペアと少し思想が近い気がする
  • 分散システム全体として無停止を担保するが利用できる言語には少し制約がある

ソフトウェア: Cloudで良くありそうなMSAや非同期キューをベースとした無停止デザイン

  • アーキテクチャーなんだけど具体的な名前を思いつかないのでフワッとした表題に。名前はまだない?
  • クラウドでは無停止システムってどう考えて作るっけ? と思って良く使われそうな考え方を書いておく
  • OSや各アプリケーションではなく分散システム上のサービス単位でFail Soft/Fault Tolerantを実現
  • 複数マシンを束ねてシステムの信頼性を実現だが、マシン単位はもはやあまり気にしてない
  • 基本的には止まることを前提に回復性に極振りしたデザイン
  • MSAにより各サービスの障害時の影響範囲の局所化とリカバリ速度の向上と、可能な限りシェアードナッシングによるアクティブ・アクティブの冗長構成が基本
  • 可能な限り非同期/結果生合成を受け入れて、とりあえず信頼性の高いキューに一時保存。失敗したらロールバックとリトライをすることで無停止性を担保
  • データはインフラとしては事実上無限のリソースがある事を前提に複数のストレージに同時に書き込むと言うのが基本
  • OSとかのレベルの無停止性を実質期待してないのが最大の特徴。体系化/フレームワーク化はもう少し蓄積が必要な印象
  • Kafkaだったりk8sだったりIstioだったりなんとかDBだったり実装は決定版がある分けでもまだない
  • まだ過渡期だけど思想的にはサービスメッシュなどを活用してアプリケーションからはいくつかの制約を満たせば透過的に無停止性が担保されるはず

まとめ

他にもたくさんある気はするのですが、メインフレーム/無停止サーバ/オープン系/クラウドにおける信頼性確保の基本的な戦略を書いてみました。

意図的にハードウェアレベル、OSレベル、システムレベル、ソフトウェアレベルをまとめて書きましたが実際はこれを混在させてシステム全体の信頼性を組み上げます。銀の弾丸はないと思うのでそれぞれを把握して適切なものを選ぶのが大事ですね。

特にNonStopやftServerといった高可用性サーバは存在自体がマイナーですが、アーキテクチャ的には結構面白いので誰かの詳細な解説があると教えて欲しいです。

クラウドでももちろん無停止サービスは実現できますが、高可用性サーバを使うと商用パッケージからOSライブラリに至るまで全て無停止を意識しているので無停止サービスの実現が容易というのも魅力ではありますね。 これはNode.jsは実行基盤だけではなくライブラリなども非同期を強く意識しているので非同期プログラミングがしやすい、という話に似ています。

この辺はクラウドでのノウハウやパッケージが揃ってくれば変わってくると思いますが、現状はクラウドでは「アーキテクトが自分たちのシステムに最適な仕組みを個別に考えて実装」というラインです。もちろんk8sをはじめ良いミドルウェアやCloud環境自体の機能も強化されてきてますけど「レールに乗って作れば無停止になる」というところにはまだ至れてません。今後のノウハウ蓄積が大事ですね。

あと、最後に書いてる「Cloudの無停止でありそうなデザイン」は具体的な名前があれば誰か教えてください。MSAは大部分はカバーするにしても無停止システムデザインという意味では要素にすぎない気がするし。

それではHappy Hacking!

参考リンク

テックポエム:010 - 祝! JDK14 リリース

www.youtube.com

スライドはこちら: テックポエム 祝! JDK14 リリース - Speaker Deck

今回はRecord型やパターンマッチングなど目玉機能といえるものが多く入ったリリースでした。

一方で、それらはまだpreview版で通常は利用できないので、今後に向けての中間リリースとしての側面も強いです。

これは、JavaChromeなどと同じく機能の有無ではなく定期的にリリースをするRapid Releasesのモデルを採用したことによる効果だと思います。

preview版がproductionになったりpreviewで新機能を早くから試せたり、特に今回リリースではないShenandoah GC向けの改修が地味に入ってたりするのは象徴的だなー、と個人的には思います。

TLDR;

  • JDK14が無事にリリース。LTSの17に向けての下準備多数
  • RecordやPattern Matching、Text Blocks がプレビューながら追加
  • JFR Stream API, Switch式など新APIや構文も追加
  • ZGCのWin/Macサポート、CMSの廃止などGC周りの改修もあり
  • 詳しくはきしださんのJava 14新機能まとめ参照 https://qiita.com/nowokay/items/ec85d97a7cecaaac8123
  • 一応言っておくけど、今もJavaは無料で使えます

テックポエマーの10min IT News! - 2020/03/15 - 「ARMメニーコア時代/技術系ポエムにLGTMしないで」 を公開しました

www.youtube.com

動画で使ったスライドはこちら: Speaker Deck

BGMを付けたり開始までの待受け画面を作ったりとか少し工夫をしてみました。

なのですが、ついでにボイスチェンジャー回りの設定を弄ったせいか音声周りが声が小さくて音質悪い感じに。。。 とりあえずアーカイブ版を作るにあたっては多少音量調整をしてみたのでマシになったはず。この辺の加工が私の技術の限界です. orz

今回はQiitaのLGTMへの変更が個人的には印象的でした。と言うのも、この動画のタイトルの元ネタの「技術系ポエムはQiitaに書かないで!」というテーマが改めてフォーカスされました。これからQiitaがどこに向かうのかはとても興味深いです。

今週のサマリ

  • ARMが超メニーコアに突入
  • 英銀行のMonzoのマイクロサービス
  • Qiitaの「いいね」が「LGTM」に変更。でも意図に対してUIが疑問

動画中の引用記事

Product Update

AR新興企業のMagic Leap、身売りを検討か

Amazonがレジなし決済技術「Just Walk Out」を小売店に提供開始

64 Core? 80 Core? 超メニーコアARMの登場

発電所が余剰電力でビットコイン採掘事業

How does Monzo keep 1,600 microservices spinning?

Qiitaの「いいね」が「LGTM」に変わります

Cloud NativeなServerless DBを開発した - 超α版

はじめに

GCPのCloudRunやAWSのLambdaのようなFaaSはアプリケーションのデプロイ先にとても便利です。

一方で、サーバレスなのでストレージを何とかしないといけないのですが、やはりRDBは使いたい。本気の業務システムならここでCloudSQLだとかAWS Auroraが出てきてこいつらは問題無くこれらのサーバレスなアプリから接続できます。

ただし、高い。大事なことなのでもう一度言います。高い。

KVS系は無料枠があるのでそっちを使えば良いですが、やはりRDBが。。。となるととたんに選択肢が無くなります。たんに実行したいのが手元の管理アプリとかだとちょっともったいないですよね?

アプリ側がIaaSやステートフルなコンテナならsqliteを動かすのがこういう用途では多かったと思います。そう、私はサーバレスでもsqlite的なことがしたいのです!

という分けでまずはプロトタイプを作ってみました。

今回はこのプロトタイプをベースに何を作りたいのかを話していきたいと思います。

コンセプト & アーキテクチャ

主なコンセプトは以下の3つです。

  • 利用している時以外は稼働しないサーバレスDB
  • RDBでありSQLをサポート。でもACIDには目をつむる
  • JDBCで接続できJPAなどから活用できる

まずサーバレスDBという事が必須の要件です。これによってsqliteをローカルに置いていた時のような手軽な運用を取り戻せます。

つづいて、DataStoreやDynamoのようなKVSも良いのですが、やはりRDBは欲しいです。特に既存のOSSを移植したいと思ったときにSQLが使えることは重要でしょう。ただし、用途が実験用または個人向けという事を加味してACIDの完全性は目を瞑ります。

最後にJDBCで接続できること。これは上記とほぼ同じですがRDBなのだからアプリから見たI/FはJDBCであるべきです。RESTやgRPCをアプリから使ってというのは実装が容易そうなのですが既存のライブラリと整合性が無くなるので、完全では無くてもJDBCのサポートは重要と考えます。

上記の3つをコンセプトにして以下のようなアーキテクチャーにしました。

  • DBエンジンはCloud Runで動作
  • ストレージはGCSで動作
  • DBエンジンのI/FはWeb API
  • JDBC側でDBのAPIサーバと会話してアプリからはJDBCに見せる

図にすると以下のような感じです。

f:id:pascal256:20200316125559p:plain

ストレージの実体は可用性とコストを考えてオブジェクトストレージにしています。これをDBエンジンが都度読み書きする事で永続化しています。

とりあえず超ナイーブに実装したのでSQLのリクエストがある度にDBのフルロードとフルストアが発生しますが、ここは何かしらの工夫が可能が気がします。

現在はDBエンジンはh2dbのラッパーです。Javaだから取り扱い安いというのもありますがh2dbは多くのDBの互換モードも備えてるのでそれも活用できるかもです。

JDBCドライバとサーバはHTTPSの通信なので完全にトランザクションが切れています。なので、必然auto-commitのみの運用になります。WebSocketとか使えば何とかなるかもですが現状は未検討。むしろ性能観点ではgRPCに対応したいですね。

一応、JDBCドライバとして実装してるので以下のようなコードがそのまま動きます。逆に言えば今はこのコードを動かすための実装しかまだしてないですが。。。

var url = "jdbc:serverlessdb://http://localhost:8080/mydb";

Class.forName("cn.orz.pascal.serverlessdb.jdbc.ServerlessDriver");
try (var con = DriverManager.getConnection(url); var st = con.createStatement()) {
    st.executeUpdate("CREATE TABLE IF NOT EXISTS sample_tbl (name varchar(255))");
    st.executeUpdate("INSERT INTO sample_tbl(name) values('Nanoha')");

    try (var rs = st.executeQuery("SELECT name FROM sample_tbl")) {
        while (rs.next()) {
            System.out.println("rs[1]=" + rs.getString(1));
        }
    }

    try (var rs = st.executeQuery("SELECT count(1) FROM sample_tbl")) {
        while (rs.next()) {
            System.out.println("count=" + rs.getInt(1));
        }
    }
}

URLで設定したDBを無ければ新規で作ったりもするので、テストの場合にはかなり便利かと思います。

パフォーマンス

さて、パフォーマンスはどんなものでしょうか? またベンチマークテストをするレベルではないので単体リクエストを投げたときのログを出します。

2020-03-16 13:05:08.444 JST2020-03-16 04:05:08,443 INFO [ser.profile] (executor-thread-1) tracelog: getBucket(ms): 39.420
2020-03-16 13:05:08.572 JST2020-03-16 04:05:08,571 INFO [ser.profile] (executor-thread-1) tracelog: readDbFiles(ms): 127.543
2020-03-16 13:05:08.579 JST2020-03-16 04:05:08,578 INFO [ser.profile] (executor-thread-1) tracelog: execute(ms): 0.658
2020-03-16 13:05:08.697 JST2020-03-16 04:05:08,697 INFO [ser.profile] (executor-thread-1) tracelog: storeDbFiles(ms): 117.519
2020-03-16 13:05:08.697 JST2020-03-16 04:05:08,697 INFO [ser.profile] (executor-thread-1) tracelog: executeQuery(ms): 293.730

これはデータ件数が数件しかない非常に小さなデータだという事に注意してください。それでもデータのREAD/WRITEに240msくらいかかっており処理速度の大半を占めています。 データが大きくなったときにどういう傾向になるのかとか、実感速度としてどの程度遅いかは今後の計測ですね。まあ、原理的にはあまり期待できない気がします。

リードレプリカを作るのは容易なので、リードヘビーなアプリなら読み込みをスケールさせることも理屈上は可能な気がしますが、それもデータサイズが影響してくるので真面目に作るとシャーディングが必要になりそうです。

きっと真面目に作るとSpannerクローンみたいになってくるのでそこを真面目に作ってはダメでしょう。

今後の展望

まずはちょうど欲しかったREDMINE的なチケットシステムを実装しながら機能を拡充して、標準的なAPIは実装させておきたいです。

その上で、既存のMetabaseみたいなOSSツールをサーバレスに改造してみたいとは思ってたので、そういった場合のコンフィグ格納先として使えると良いなぁ、と思ったり。上手くいくかは分かりませんが。

あと、管理APIは実装しないとですね。DBを消したりとか。

sqlite3的な気軽なDB運用はやはりサーバレスになってもしたいので、しばらく開発は続けてみたいと思います。

それでは、Happy Hacking!

参考