by shigemk2

当面は技術的なことしか書かない

メモ クラウドネイティブアプリケーションとSpring Framework #jjug_ccc

クラウドネイティブアプリケーションとは、プログラマブルにクラウド環境の制御を行いサービスを実現するアプリケーションである。

www.okinawaopenlabs.org

pivotal.io

  • 世の中にソフトウェアによるビジネス変革をもたらす会社
  • アジャイル開発してる
  • ソフトウェアを迅速にリリースする

  • 高価な環境からのクラウドへのワークロード移行

    • クラウドネイティブ クラウドに根ざしたアプリケーションのリリース
    • マイクロサービス
    • アプリケーションを細かく、スケールアウトしやすいようにする
    • 安く早く的確にスケールアウトしやすいものを作る
  • クラウド時代のアプリのあり方(12個)

    • Herokuとか
    • 新しいアーキテクチャが増えてきている
  • 新しいトレンドとしてのマイクロサービス

    • 疎結合 + 細かいリリース
    • いろいろな会社(IOTとか)

Seven micro-services architecture advantages | Art of Software Engineering

  • マイクロサービスを業務の要件として盛り込む企業が増えてきている

    • 内製化 + マイクロサービス
  • マイクロサービスを使うために必要な条件

    • 迅速なプロビジョニング
    • ベーシックな監視機能
    • 迅速なアプリケーションの展開
    • DevOpsの文化
  • こういったのを実践実装している企業 Google FB netflix amazon

    • こういった企業の技術を最大限活用する
    • 協業しているのがnetflix
  • リファレンスアーキテクチャ

    • 細かくサービスを組み合わせる
    • 全体の整合性をどうするのか
    • netflixは最大限技術を公開している(netflix ossとして還元)

enterprisezine.jp

  • netflix
    • スピードがマーケットを制する
    • マイクロサービスのパイオニア
    • netflix ossは部品を提供
    • クラウドプラットフォームの独自構築
    • spring

www.slideshare.net

  • クラウドネイティブという言葉ができたのは2013年。最近バズってきた
  • カオスモンキー
    • 特定のシステムを破壊するプログラムをわざと組み込む
    • データソースがいっぺんに集中しないように気をつける

www.publickey1.jp

  • CI CDといったものを適切に使う
  • マイクロサービスと言いながらも、それを支えるプラットフォームは必要
    • spring cloudとか。。。
  • クラウドネイティブなアプローチの推進
  • spring boot

Spring Boot

  • 導入数は増えていってるが、今後どうするか
    • spring cloud アプリケーションの連携パターンを定義
    • 実行環境とクライアントライブラリを提供
    • spring cloud service netflix ossとの等号を勧めたクラウドネイティブなコンポーネント

Spring Cloud Netflix

  • service discovery

Service discovery - Wikipedia, the free encyclopedia

サービスレジストレーションディスカバリー

github.com

e-words.jp

  • デモで立ち上げは大変
  • プラットフォームとしての機能を提供している
  • アプリケーションを登録するだけでいい
  • ほぼすべてのアプリケーションが実行可能なプラットフォームを提供する

  • 数多くのフレームワークと管理手法、自動化ツール

  • パイプライン管理 コードを書くだけではなく、コードを読んで、継続的デリバリーを実現する = cloud foundary
  • デプロイの自動化
  • コマンドひとつでデプロイできる(今まで手作業でやっていたことがプラットフォーム側で吸収できる)

pivotal.io

paasからcloud native application platformへ

メモ これからのコンピューティングの変化とJava #jjug_ccc

どんな話?

  • ハードウェアが変わっていく
  • Javaも変わらないとね

こんな経験ない?

  • サーバが遅いから速いCPUが載ったマシンに買い換えたい
  • サーバを増やしたい
  • サーバが遅いからデータベースにキャッシュ

処理を上げるためには

  • 並列度を上げる
  • より近いところにデータを置く

ムーアの法則

  • 18ヶ月くらいでトランジスタの数が倍
  • 寸法半減

ムーアの法則の終焉

" 物理的に配置できない(ナノミリレベル) * 電子が漏洩する(配線の間) * 歩留まりが上がらない 製造コストが増える

微細化が進んでも今までと違う

  • コストが下がらない
  • 消費電力と高速化は両立できない

データセントリックシステム

  • データの移動に電力 時間が食われている
    • ストレージ→メインメモリ→キャッシュメモリ
    • Hadoopなど
  • データの移動を減らす
  • データの近くでデータをうつす

コンピュータの種類

  • ノイマン型
  • 非ノイマン型

ノイマン型

  • メモリから命令を呼び出して命令にしたがった回路で処理
    • CPU
    • GPU
    • 所謂プロセッサ
    • メモリ→データ読み込み→回路
    • 回路の構成がシンプル

CPU

  • 高性能 高機能 高粒度
  • 割り込みとか権限制御とか
  • OSが実行できる
  • OSが実行できることがCPUの基準
  • 演算器自体が足し算と引き算
  • コアあたり10個程度の演算器
  • 明示的にメモリを制御出来ない
    • いかにキャッシュを載せるか
    • いかにメモリをまとめて扱うか
    • そのデータがどこに置かれるか意識しない

GPU

  • ちょうたくさんコアがある
    • 同じ処理 行列計算に向いてる
  • GTX 970
    • 1664コア(つよそう)

GPUの構成

  • コアごとにグループ
    • 同時に同じ命令を実行
    • グループだけからアクセスできるメモリをもつ
  • コアのグループが多数ある
    • コアあたり数個の演算器
    • プロセッサ全体としては演算器が数千数万ある

https://ja.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E8%A3%85%E7%BD%AE

非ノイマン型アーキテクチャ

" ノイマン型ではないコンピュータ全体(ノイマン型でなければなんでもいい) * FPGA * ニューラルネット型 * 量子コンピュータ * ニューラルや量子はプログラム可能ではないので、FPGAがメインになろう

FPGA

  • Field Programmable Gate Array

回路の入出力の組み合わせ

  • 論理素子(AND/OR)をいっぱいならべると難しい
  • 入力と出力が1対1で決まるので入力と出力のパターンを決めれば回路が決まるのでは?というコンセプトで、平たく言えばメモリ
  • LUT(LookUp Table)

論理ブロック

  • Logical Element
  • 論理ブロックが格子状に配置

乗算回路とメモリ

  • 蒸散やメモリを論理ブロックで実現すると効率悪いので専用の乗算回路やメモリ(SRAM)が乗ってる

その構成

  • メモリが帯状に並んでいる

FPGAなら

  • 命令を読み込む必要がなく、回路をやりたい処理の通り並べることができる
  • メモリを読み込んで解釈するというレイテンシが生まれない!
  • 処理の回路に直接データを流すことができる

利点

  • 命令を読む必要がない
  • 低レイテンシ
  • 細かな並列化

Javaでやってみる

  • CPU Streamでやると簡単
  • GPU Aparapi OpenCL(JOCL) Project Sumatraなどを使う

Aparapi

  • A PARarell API

JOCL

  • OpenCLを薄くラップしてるライブラリ(書くのはちょっと面倒)
    • Aparapiのコードをコピペしたりできる

比較

  • Aparapi
    • GPUの性能出しづらい
  • JOCL
    • ちょっと面倒
    • GPUの性能出しやすい

DeepLearningやってみたけど

  • 階層の深いニューラルネット
  • 最近人工知能と言われているのはほぼこれ

Aparapiを使うと

  • 15枚/分→90枚/分
  • 1400万枚の画像処理が600日→100日!(それでも長い)

JOCLを使う

  • 90 枚/分→298枚/分
  • 1400万枚の画像処理が100日→34日!
    • Aparapiのほうが、データと処理のやりとりの回数がJOCLより多いから

GPUローカルメモリ

  • 298 枚/分→300枚/分
  • 1400万枚の画像処理が34日→33日!
    • プロだと1週間で終わるらしい

GPUの結果

  • 90 枚/分→300枚/分
  • 1400万枚の画像処理が100日→33日!
    • 77日分の無駄が発生してる

FPGAでやったら?

  • GPUの半分のスループット
  • 1/10の消費電力
  • 電力あたりの性能は3倍

Sumatra

  • Java VMに組み込むことが目標だけど
    • 実装 コード 性能などに難がある
    • メリットが少なそう
    • と思ったら開発止まってた

JavaでFPGA

  • Synthesijer

http://www.sigemb.jp/ESS/2014/files/IPSJ-ESS2014003-1.pdf

http://synthesijer.github.io/web/

  • HDLを書かない方法になると思われる

Javaでもいろいろできる でも今のままで足りるの?→足りない

  • オブジェクトのメモリ効率が悪い
  • アーキテクチャに対応した値が使えない
    • いろいろな型をコンピュータ自体が持ってる
  • 高性能データ構造がメモリにやさしくない
    • List Mapに数字を入れようとするとラップオブジェクトに値を入れないといけない
  • 配列がハードウェアにやさしくない
    • 多次元配列(配列の配列ができてそれは配列なのか?)
    • 読み込み専用(メモリキャッシュをJavaで使おうとするとでかいデータが使えない)

Close To the Metal

https://en.wikipedia.org/wiki/Close_to_Metal

" ハードウェアに近づく

そこでUnsafe

  • 並列化プリミティブ(compareAndSwap*)
  • シリアライズ(メモリ上のオブジェクトをそのままStreamに流す)
  • メモリ管理(アロケート)
  • JVM外でのやりとり

Unsafeを利用している製品

  • Cassandra Ehcache HBase Scala Springなどなど
  • ミドルウェア 現行製品ではだいたい使っている

Unsafeの廃止

  • Java 9でメンテ停止
  • Java $N-1で完全置き換え Deprecate(非推奨)
  • Java $Nで廃止
  • Java 10 or 11で廃止 5年後くらいだろうか
  • で、どうするの?

Unsafeの代替

  • JEP 193 Variable Handles(Java 9)
  • JEP 187 Serialization
  • ProjectPanama ProjectValhalla Arrays2.0
  • ProjectPanama JEP191FFI

Valhallaへの道

  • Value Type
  • Specialization

Value Type

  • ユーザ定義基本型
  • Codes like a class
  • 配列 = ヘッダ + 参照

Pointクラスの配列の効率化

  • 自力解析など

ValueType版Point

  • value class Pointみたいな定義
  • Nullを持たないプリミティブ
  • 参照型ではなく値がそのまま格納されるので幸せになれるかも

Specialization

これを実現したい

ArrayList<int>

Java 8の美しくないクラス

  • StreamとIntStream 捨てたい
  • OptionalとOptionalInt 捨てたい

  • IntStream extends Stream OptionalInt extends Optionalみたいな書き方をしたい

ValutType対応

  • それぞれのValueTypeにあわせたコレクションを作るのは無理
  • 効率のいいものを自前で実装しようとするとValueTypeは難しい
    • Genericなクラスを作る
    • プリミティブが入れられない
    • Specialize可能なクラスを作れるようにする

Name Mangling

  • 名前就職
  • Javaの入れ子クラス Hoge$Foo
  • Specializedなクラス Box${T=I} JVM上でIntを扱う記号

条件付きメソッド

  • Intだけ扱うメソッドとか欲しい

https://docs.oracle.com/javase/specs/

Foo<?> ワイルドカードをどうするか

any ref

  • Foo intでもObjectでも
  • Foo<?>

可視性

  • FooからFooのprivateメンバを使いたい
  • ソース上は同じクラス
  • 実際はspecializeされた別クラス
  • privateメソッドが呼べない(VMが拒否ってしまう)
  • JavaVM助けてくれ
  • 配列

    • Objectとintは違う
    • Arrays2.0さん助けて!

    問題点

    • FooとFooは共通の基底クラスを持たない別のクラス
    • Specializedなクラスをいつ生成するか
      • classDynamicはVM実装が複雑
    • JavaVM助けて

    JavaVMをどうするか

    • aload/iload/lload
    • astore/istore/lstore
    • areturn/ireturn/lreturn

    int long double float全てに足してロード ストア 演算などの命令がある

    バイトコードの統一

    • 型を持ったまま汎用の公文
    • 新しい型が自然に拡張できる

    • vload vstore vaddなど

    • vload :I vaload :Dみたいな書き方

    Arrays2.0

    • 配列をインターフェイスに!
    • バイトコードレベルのSpecializationが不要になる…という夢を見た
    • そういう構想が2015夏に言われてた

    http://openjdk.java.net/projects/valhalla/

    • 構想が形になっていない?
    • valhallaやっても金にならない?
    • プログラミングがハードウェア寄りになっていくので

    • Unsafe

    • Valhalla
    • Panama

    まとめ

    • コンピュータが変わる
    • Javaも変わる
    • あんたはどうだい?

    http://openjdk.java.net/projects/mlvm/jvmlangsummit/

    メモ Java8 Stream APIとApache SparkとAsakusa Frameworkの類似点・相違点 #jjug_ccc

    前提

    • JJUGのみなさまならばJava8 Stream APIは知っているだろう
    • Java8 StreamAPIとApache SparkとAsakusa FrameworkのコーディングはDAGの点から似ている
    • Asakusa Frameworkの紹介

    自己紹介

    Scalaですっごいお世話になっています

    年表

    • 2006 Apache Hadoop
    • 2010 Hadoopを知る
    • 2010 Spark OSS化
    • 2011/3 Asakusa Framework公開
    • 2014/2 Apache Sparkトップレベル昇格
    • 2014/3 Java8リリース

    • バッチ処理を早くしたいという同期

    • 2,3倍の速度なんて無理だろうと思っていたらHadoopで簡単にできるよ!ってなったので勉強しはじめた
    • 勉強会も超人気
    • なるべく早くHadoopの情報を知りたいという理由からTwitterを始める
    • SparkをScalaをごにょごにょしている人がいたのでScalaも勉強しはじめる Hadoop(HBase)のサンプルをScalaで書いている人がいたのでScalaの勉強を始めました。そして、Scalaで出来た分散フレームワークということでSparkを知りました。
    • Hadoopを勉強しているうちにAsakusa Frameworkなどを知る
    • Asakusa Frameworkをやっていたら転職できる!

    StreamAPI Spark AsakusaFW

    • 省略!したいと思った
    • 内部イテレーターで処理を行うためのAPI

    Hadoopについて

    • 分散処理フレームワーク
    • HDFS(分散ファイルシステム)
    • MapReduce(処理方式 アルゴリズム)
    • YARN(リソース管理)

    • データを複数のマシンに分散配置

    • MapReduceアプリケーション(jarファイル)を各マシンに転送して分散処理

    従来だと

    • RDBにデータを置きバッチサーバを経由して転送する(分散の意味があまりない)
    • (補足) バッチサーバーを分散してもDBが分散しないとDBに負荷が集中して意味がないということ。(DBを分散させるということでNoSQLが流行りました)

    Hadoopバッチ

    • Hadoopクラスターがあって、データとアプリケーションが分散配置されている(アプリケーション 数百メガバイトのjarファイルもデータのあるサーバに転送する)
    • (補足)何GB・何TBのデータを転送するよりは、大きくても数百MBのjarファイルを転送する方が転送量が少ない、ということです。

    自分が思うHadoopの功績

    • ビッグデータはバズワード化したが、Hadoopは分散処理を身近にした
    • MapReduceはシンプルだがアセンブラでコーディングするというイメージなので、コーディングしづらい
    • 常にファイルを読み書きするシンプルな構成なのでメモリにデータをキャッシュして使い回すみたいなことはできない(機械学習はそういうことをしたいらしい)

    →という問題点があったので、Apache Sparkが出てきた

    Apache Spark

    • RDDを使ったコーディング(Scala)
    • インメモリでキャッシュして使いまわせる
    • 分散ファイル入出力にはHDFSを利用

    Asakusa FW

    • 分散処理するバッチアプリケーションを作成するためのフレームワーク
    • 実行基盤としてHadoopやSparkを使える
    • ノーチラステクノロジーズが開発

    類似点

    • Java8 Stream API
    • メソッド参照

    これをDAGで表現する

    グラフ理論

    https://ja.wikipedia.org/wiki/%E6%9C%89%E5%90%91%E9%9D%9E%E5%B7%A1%E5%9B%9E%E3%82%B0%E3%83%A9%E3%83%95

    • 向きがある
    • 閉路(循環)がない

    といったフローのことを指す

    Java8 Stream API

    • 向きがあって循環のない流れ
    • s0 filter map out1

    cf. Scala

    filterしてmapして…

    ScalaのStreamもJava8 Stream APIと変わらない

    Apache Spark

    • DAGなのは変わらない
    • RDDが使われている
    • s0 filter map out1

    Asakusa FW

    • フローというところでDAGなのは変わらない
    • 入出力はファイル
    • s0 Branch(f) Update(m) out1
    • inputがsourceで現れる
    • StreamAPIとかSparkなどと比較しても、DAGを使っているという点ではAsakusaFWと一緒

    • コンパイルするとMyOperatorFactoryが生成される アノテーションとしてBranchとかUpdateとかが生成される

      • (補足)BranchやUpdateのアノテーションをOperatorのメソッドに指定すると、それに応じたフロー用のメソッドを持つFactoryクラスが生成されます。

    類似点まとめ

    • 処理がDAG(有向非循環グラフ)で表せる!

    相違点

    複数入力

    • 合流(union)
    • 結合(join)
    • zip
      • unionやjoinはSQLとイメージはいっしょ

    合流 union

    • Stream API concat
    • Spark ++を使う(Scalaは記号をメソッドとして使える)
    • AsakusaFW confluent(可変長引数ではないがある程度の数の引数なら面倒見れる)

    結合 join 一対一

    • Stream API ない
    • Spark join
    • AsakusaFW masterJoin(join)

      • (補足)多対一です。(少なくともAsakusaFWは)
    • マッチしないものは結合しない

    結合 cogroup 多対多

    • Stream API ない
    • Spark cogroup
    • AsakusaFW CoGroup(group)

    複数入力 zip

    • 順番でレコードのKeyValueをくっつける

    • Stream API ない

    • Spark zip
    • AsakusaFW ない

    • 結構難しい実装なので、多用は禁物

    複製 duplicate

    • Stream API ない
    • Spark map
    • AsakusaFW m1 m2

    分岐 branch

    • 複数出力

    • Stream API ない

    • Spark ない
    • AsakusaFW branch

    根本的な相違点 使用目的

    • Stream API 内部イテレーターのため ワンライナーで書きやすい
    • Scalaのコレクション Scalaの書き方で、並列Streamでマルチスレッド処理が可能
    • Spark 複数マシンで分散する処理を書ける マルチプロセス
    • AsakusaFW バッチアプリケーションを書く。テスト機構あり

    • マルチスレッド 複数マシン分散 扱うデータ量の違い

    • マルチスレッド処理といっても、数十万件といったデータでないとメリットがない
    • 数千万 数億とかだと、データ自体を分散し、それぞれ処理するほうが効率が良い Hadoop Spark(自分で頑張るよりは…)
      • (補足)「自分で頑張るよりは」は、Stream APIでもファイル読み込み部分を自分で分散読み込みさせれば出来るけれども、そこを自分で頑張るよりは既にあるHadoopやSparkを使った方がいいんじゃないか、ということです。

    Asakusa Frameworkの目的

    • 分散処理するバッチアプリケーションを作成するためのフレームワーク

      • 当初はHadoopが実行基盤
      • 少量データの場合はオーバーヘッドが大きい
      • マシンVMを立ち上げるので、普通のバッチであれば数秒で終わるのが、逆に時間がかかる
      • 解決策としてのスモールジョブ実行エンジンを実装
        • 単体テストの実行環境としても使える
      • 最新版では実行基盤としてSparkを使用可能
    • Asakusa Frameworkで作ったアプリケーションはコンパイルしてjarファイルを生成

      • Spark版実行バイナリはアプリケーションをリコンパイルするだけ!
        • Javaなどもバージョンが変わってもコンパイルするだけでいいので、結構似ている
      • Hadoop Spark以外も採用される可能性がある?
    • バッチの実行時間

      • Hadoop(180個のジョブを45-50分)
      • Hadoop + スモールジョブ実行エンジン(180個のジョブを10-15分)
      • Spark(180個のジョブを3-4分)
        • 超速い Sparkは効率が良いらしい
        • Hadoopだと開いているタスクができるらしい
    • やっぱりDAGでフローを書ける

      • 関数合成で最適化
    • 分散処理するバッチアプリケーションを作成するためのフレームワーク(再掲)

      • そもそも分散処理が必要
      • Sparkでも小さなデータが扱えるようになる。
      • joinが必要な場合はAsakusaFWとか使えば良いと思われる

    余談 ハードウェアとソフトウェアの関係

    • ハードウェアが変わればそれに最適なソフトウェアも変わる
      • HadoopはHDDを念頭においた作りになっている
      • 大きなサイズのブロックアクセスに弱い(HDDはランダムアクセスに弱い)
        • HDDはある程度大きなサイズのブロックの(シーケンシャルな)読み込みの方が効率が良く、ランダムアクセスは効率が悪いです。

    ランダムアクセス - Wikipedia

    余談 ハードウェアの技術動向

    • ディスク HDD SSD
    • CPU クロック数は頭打ち メニーコア化 100コア超 高性能になるともしかしたらディスクもいらなくなるのでは?
    • メモリー 不揮発性メモリー(電源を切ってもメモリのデータが消えない) フラッシュメモリー MRAMなど
      • DBの人はこれに注目してて、DBのログをハードディスクに書き込むなどしているが、メモリが不揮発性になるとこれが要らなくなるのでは

    余談 メニーコアに対する今後の予想

    • Java8 Stream API
      • parallel()を使えばいい(ソース修正が必要)
    • Apache Spark
      • executorはSpark管理下なので、実行環境の指定を変えるだけでいいかも
    • Asakusa Framework
      • リコンパイルするだけで対応できると思われる(現在開発中)

    まとめ

    • DAGを使ってコーディングしているという点では似ている
      • Asakusa FWは難しいという声を聞くが、考え方はStream APIと同じ
    • 使用目的(扱うデータ量 実行基盤)の違い
      • Asakusa FWはリコンパイルするだけで実行基盤を切り替えられる(実装を変える必要がないので、メンテナンスがすごく楽)

    質疑

    • AsakusaFW 設計思想的に例外で落ちることはなく、落ちる場合はバグってる
    • 時系列集計など、やりにくい処理はある? range joinみたいな仕組みがあるので、ちょっとコーディングしたらできる