第7回 Software Architecture: The Hard Parts 読書会@リモート
第7回 Software Architecture: The Hard Parts 読書会 - connpass
- JavaEE勉強会の読書会
- 開催場所はDiscordのjavaee-study-jp
- Neal Ford, Mark Richards, Pramod Sadalage, Zhamak Dehghani さんの Software Architecture: The Hard Parts [Book] を読んでます
- 今回は
9. Data Ownership and Distributed Transactions
から読み始めます - 今回は
9. Sysops Squad Saga: Data Ownership for Ticket Processing
まで読み進めました - 次回は
10. Distributed Data Access
から読み進めます- 次回は 2022-05-21(土)です。
- 第8回 Software Architecture: The Hard Parts 読書会 - connpass
- 参加者トピック
- ディスカッション
- 9. Data Ownership and Distributed Transactions
- Table Split Technique
- Data Domain Technique
- Delegate Technique
- Service Consolidation Technique
- Data Ownership Summary
- Distributed Transactions
- Eventual Consistency Patterns
- Sysops Squad Saga: Data Ownership for Ticket Processing
- Chapter 10. Distributed Data Access
- 参考情報
参加者トピック
- 誰にでも勧められないサービスに手を出した STEPN is a Web3 lifestyle app with Social-Fi and Game-Fi elements
- 運動して、お金を稼ごう!(ただし初期費用は高い)
- Go Conference 2022 Spring Online - connpass で話してきた
- ACM 会員の特典だった O'Reilly Learning が来月に終了するのでたぶん再入会します
- ACM 会員の継続は自動じゃないから安心
ディスカッション
9. Data Ownership and Distributed Transactions
- 「複数のサービスが同じデータベーススキーマにアクセスするのはOK、1つのサービスが複数のデータベーススキーマにアクセスするのはNG」
- そういう割り切りありだなって思った
- 普通はテーブルの所有権って考えるものなのか
- モノリシックアプリケーションならともかく、マイクロサービスアーキテクチャを考えているなら考えるものだと思う
- 仕事ではサービス=プロジェクトとして管理している
- 誰が所有してるかはすぐ分かるようになっていて欲しい
audit
だけ用途が違うから、別に複数のサービスが書き込んでいるとしても、複雑になってないと思ってしまった- Q 所有権って概念って一般的?
- A モノリシックサービスが分解される過程で、データアクセス元のサービスを意識するようになった結果生じた概念では?
- ...自分もそんな気はする。モノリスなサービスしか経験してないので誰が所有しているかはっきりしなくてもいい現場感?的な。
- 共同所有権シナリオ、いい思い出がないので感情的に否定しがち
- 経験談
- Inventory Serviceで管理する在庫は自社在庫じゃない場合があった
- 他社の在庫管理システムで扱ってる在庫の扱いが違うとかで大変
Table Split Technique
- やっぱりVertical Partitioningしてる
- リレーショナルデータベースが実現していた制約条件を、アプリケーションレイヤで実現する感じになるのが不穏
- マイクロサービスのアプローチだと、この手の設計が定石
- 2022年にCAP定理がこう言っている、みたいな文章見るのは新鮮
Data Domain Technique
- どの辺がテクニックなんだろうと思ったけど、テーブルを宙に浮かせないで、境界づけられたコンテキストに納めて人間が認識できるようにするところがテクニックなのかな
- その行を追加・更新したプログラムID、みたいな列があるのを今までのすべての会社で経験してて、ガバナンスやなって思いました
Delegate Technique
- (全体的に)トレードオフ分析の表は、メリットとデメリットを対比してるわけでもないし、それぞれに重みがあるわけでもないし、この表だけで分析するのは難しそう
operational characteristics
ってちょうどいい言葉(訳語)がなさそうで、「運用特性」以外の言葉が生まれて欲しい
Service Consolidation Technique
- データの所有権を考えていたらサービスが肥大化する場合があるテクニック
- デプロイ/リリースサイクルの向上が大正義な文脈では採用しにくいやつだ
Data Ownership Summary
- どちらも永続化するのに、テーブルとキューで扱いが違うの面白い
- テーブル:できるだけ境界づけられたコンテキストに配置する
- キュー:境界づけられたコンテキストの外側に配置されている
Distributed Transactions
Eventual Consistency Patterns
Background Synchronization Pattern
- トレードオフ
- すべてのデータソースが結合する
- 関連するサービスが共同所有権を持つようになってしまう
- 境界づけられたコンテキストが守られない
- きっかけは顧客プロファイルサービスでも、サポート契約、支払い請求について独自のビジネスルールがあるかもしれない
- すべてのデータソースが結合する
このパターンが有効な場面は、互いに通信せず、データも共有しない閉じた(自己完結した)異なる種類のシステムである。
- 異なるサービスで同じデータを適用、参照できるのに綺麗に分離されてるってほんとかな
- プロファイル、契約、請求が、外の世界の別々のサービスになっている様子を考えるとありそうな気がしてきました
Orchestrated Request-Based Pattern
Event-Based Pattern
Sysops Squad Saga: Data Ownership for Ticket Processing
- 境界づけられたコンテキストとかドメインとかの言葉がどの文脈で使われてるかわからないので、なんか言葉に振り回されている感じがすごい
- そのせいで、「チケット完了サービス」という単語がじわじわ面白くなってきてしまった
Chapter 10. Distributed Data Access
“分散システムにおけるデータの扱いについては、『データベースリファクタリング』の共著者であるPramod Sadalage、『Data Mesh』の刊行を控えたZhamak Dehghaniを共著者として迎え” 気合が入っている章らしいです
参考情報
- Excalidraw | Hand-drawn look & feel • Collaborative • Secure
- ウクライナでも活躍する「スターリンク」は何がスゴイ? - Impress Watch
- Elon Musk on Twitter: "Processing is not an issue. Lasers links alleviate ground station constraints, so data can go from say Sydney to London through space, which is ~40% faster speed of light than fiber & shorter path. Also, no need for ground stations everywhere. Arctic will have great bandwidth!… https://t.co/5LB190vIUg"
- StackPath
ALONE〜孤独のサバイバー〜シーズン2を観た
邦題「ALONE〜孤独のサバイバー〜」を一気に観た - yujioramaの日記に続いてシーズン2も観た。シーズン3以降は有料。
シーズン1と違って参加者のスキルが高くなっていて、やり方の違いより、効率性を追求してるところが見どころだった。
筋トレ始めたり、トレーニング設備作って楽しんでる人もいれば、最初からずっと辛いひもじいを続けてる人もいて、多様性があるなぁと思った。
開始地点に平地が無くてずっと困ってるところや、熊の親子と共存してるところにアザラシが割り込んで食料の取り合いになってしまうところは、生存競争してる感じで印象深い。
Perl Carton Buildpack のプロトタイプで遊んでた
背景
- Heroku や Cloud Foundry などで利用されている Cloud Native Buildpacks という技術がある
- いわゆる S2C (Source Code to Container Image)
Dockerfile
の関門をスキップできる
- .NET Core/Go/Java/Node.js/Python/PHP/Ruby には対応している
- Getting Started - Paketo Buildpacks
- Perl には対応していない!
- 入門ドキュメントは一通り読んでるし、自作できるのでは?
できたもの
yujiorama/perl-carton-buildpack
- シェルスクリプトでいろいろ書かれている、テストのないプロトタイプ
- Perl アプリケーションのコンテナイメージを1コマンドで作成
- Carton に対応
.perl-version
によるバージョン指定に対応- Plack に少し対応(
plackup
する)
コンテナイメージ your-app
を作成する様子(一部)。
$ pack build your-app \ --builder paketobuildpacks/builder:full \ --buildpack yujiorama/perl-carton-buildpack \ --path /path/to/your-app full: Pulling from paketobuildpacks/builder Digest: sha256:4cfa401f11219ac10e8f756c244a6acc2d7cdd7aca42759a4e2aa616da7f1dfa Status: Image is up to date for paketobuildpacks/builder:full full-cnb: Pulling from paketobuildpacks/run Digest: sha256:4f113e8c504574b4f298ed7fc14dcfe25f347cf51a6bbd77e7765f896b668e60 Status: Image is up to date for paketobuildpacks/run:full-cnb ghcr.io/yujiorama/buildpacks/yujiorama_perl-carton-buildpack@sha256:ce9edb0104d2b03e29c0aef75e02e22d264d81285b34853fea360b1f4a43c00a: Pulling from yujiorama/buildpacks/yujiorama_perl-carton-buildpack 614925ba7a2b: Pull complete Digest: sha256:ce9edb0104d2b03e29c0aef75e02e22d264d81285b34853fea360b1f4a43c00a Status: Downloaded newer image for ghcr.io/yujiorama/buildpacks/yujiorama_perl-carton-buildpack@sha256:ce9edb0104d2b03e29c0aef75e02e22d264d81285b34853fea360b1f4a43c00a ===> ANALYZING Previous image with name "hello-world-plackup" not found ===> DETECTING yujiorama/perl-carton-buildpack 0.0.2 ===> RESTORING Restoring metadata for "yujiorama/perl-carton-buildpack:xbuild" from cache Restoring data for "yujiorama/perl-carton-buildpack:xbuild" from cache Restoring data for SBOM from cache ===> BUILDING ---> Perl-Carton Buildpack ---> Configure xbuild layer
やったこと
所感
- 標準化された仕様にたどり着くまでが長かった
- 最初に Reference を読み飛ばして進めたのが敗因
- 最終的に buildpacks/spec を読めばいいことが分かっていろいろ捗った
- 既存の Buildpack が使用しているAPIバージョンは必ずしも最新化されておらず、見るものによって仕様の記述と合わなくて混乱していたのも敗因
- 具体例のない仕様に手こずった
- 特に buildpacks/rfcs - 0031-bionic-mixins
- ビルドフェーズで
make
やgit
を利用するために必要だった - Buildpack API には記載されているけど使い方とかが何もわからないという
paketobuildpacks/run:full-cnb
などのイメージラベルio.buildpacks.stack.mixins
に指定できる要素が並んでいるところを発見したりした
- APIが明確でテストも書きやすい Go で作ったほうがいい
- 既存の Buildpack はだいたい Go で書かれていたのだけど、本質的には Go じゃなくてもいい
- 特にテスト容易性が高まるので Go で書いた方がいい
邦題「ALONE〜孤独のサバイバー〜」を一気に観た
舞台は野生の熊や狼が徘徊する無人島。ヘリコプターでばらばらの場所に配置された十人の参加者が、最後の一人になるまでサバイバルし続けている。
YouTubeでブッシュクラフトの動画を見るのが好きなんだけど、こういう作られた感を排除した作り話も好きです。
序盤はみんな元気で、それぞれなりにブッシュクラフトしているのが面白い。熊や狼の存在がアピールされるのはこの辺だけで、ひやひやしながらも安心して見れる。
脱落者が出てくる頃になると、泣きながら家族に会いたいと言っていた翌朝にはまだ頑張れるぜ、と意気込んでいたりするので、見てる方の感情を無駄に揺さぶられる感じになってくる。食料を求めて海岸をさまよったり網漁したり設置罠しかけたり、いろんなアプローチが見どころかな。
終盤は逃げていた過去に向き合ったり、新しい自分を見つけてしまったり、神に感謝したり、いろいろなことが起き始める。人数が減ると一人ひとりの時間が長くなるので、30分くらい自分語りしてる回もあった(気がする)。大雨、暴風、昼間でも氷点下、ととにかく環境がひどいことになっているので、見ていると不安になってくる。
ほとんどの参加者はやりきった、あるいは、やることを見出して去っていくんだけど、その後の様子が収録されてないのは残念だった(最後まで残った人のエピソードはあってよかった)。
心の中のもやもやを解消する方法
背景
- 常用してるIntelliJ IDEAを開発してるJetBrainsから開発者向けアンケート調査が届いていた
- 暇つぶしに回答してたら「メンタルヘルスを解消するためにやってることを教えて」みたいな項目があった
- 「知らん、何もやってない」と回答した後に、やってることがあったので今この文章を書いているけど、普通のことしかやってなかった
心の中のもやもやを解消する方法
1. 寝る
- ただ寝るだけでもかなり効果がある
- 人間なら寝ない日はほとんどないはずなので、基本的には毎日もやもやが解消されているはず
- 解消しない場合は異常事態なので次の手段に進む
2. 人に話を聞いてもらう
- 相談ではなく「話を聞いてもらう」ことがポイント(だと思ってる)
- 自分で解消できないからもやもやしているので、アドバイスいただいたり応援していただいても、たぶん残ってしまう
- 相手がいることで、謎のおもてなし精神が活発化し、見逃していた条件や論理矛盾が発見される(場合がある)
- 解消しない場合は最終手段に進む
3. 文字にする
TLA+に再挑戦(2022.4)
英語のドキュメント を読んだけどあまり理解できてなかったので 日本語 で再挑戦する会。
進捗
- 前回
- 「6章 時相論理」を読んだり試したり
- 「7章 アルゴリズム」を読んでいちゃもん書いたり
- 今回 2022.4 実践TLA+もくもく会 - connpass
- 「7章 アルゴリズム」を読んだり試したり
- 「8章 データ構造」を読み始めた
- 次回 2022.5 実践TLA+もくもく会 - connpass
- 「8章 データ構造」を読む(何周かしないと意味が分からなそう)
7.4 アルゴリズムの特性
二分探索を例に、性能や境界条件を検査する。
- 補助関数
OrderedSeqOf(set, n)
- set を値域とする要素数 n のシーケンスのうち、すべて昇順になっているシーケンスを生成する
Range(f) == { f[x] : x \in DOMAIN f }
DOMAIN f
は f の取り得るすべての入力f
がシーケンスならすべての添え字になる
- つまり
f
のすべての値を返すようになっている - 途中でいきなり
PT!Range(f)
に置き換えられている…
- 入力
found_index
- 初期値の
0
は要素が見つからないとき
- 初期値の
- 出力?
if target \in Range(seq)
がわからない- なんで
if target \in seq
じゃないんだろう - →
\in
に渡せるのは集合だけど、seq
はシーケンスだから- 型変換しているだけだったというオチだった
- 時間計算量の検証
- 二分探索の時間計算量は
O(log(n))
になるはず - 逆にループ回数を計測して
2^n < length(n)
で判断することもできる- 実際には
2^{n-1}
で判断する
- 実際には
- 二分探索の時間計算量は
- 二分探索アルゴリズムの有名なバグ
(low + hight) \div 2
はMaxInt + 1
になってしまう場合がある- Google AI Blog: Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken
- 値域が有限の変数があるときは、不変条件にオーバーフローのチェックを入れた方がよい
---------------------------- MODULE binarysearch ---------------------------- EXTENDS TLC, Integers, Sequences PT == INSTANCE PT \* set を値域とする要素数 n のシーケンスのうち、すべて昇順になっているシーケンスを生成する OrderedSeqOf(set, n) == { seq \in PT!SeqOf(set, n): \A x \in 2..Len(seq): seq[x] >= seq[x-1] } MaxInt == 7 (*--algorithm binarysearch variables seq \in OrderedSeqOf(1..MaxInt, MaxInt), low = 1, high = Len(seq), target \in 1..MaxInt, found_index = 0, counter = 0, m = 0, lh = 0; define Pow2(n) == LET f[x \in 0..n] == IF x = 0 THEN 1 ELSE 2 * f[x-1] IN f[n] NoOverflows == \A x \in {m, lh, low, high}: x <= MaxInt end define; begin Search: while low <= high do counter := counter + 1; lh := high - low; m := high - (lh \div 2); if seq[m] = target then found_index := m; goto Result; elsif seq[m] < target /\ m < high then low := m + 1; else high := m - 1; end if; end while; Result: \* 計算量を評価 if Len(seq) > 0 then assert Pow2(counter - 1) <= Len(seq); end if; \* 結果を評価 if target \in PT!Range(seq) then assert seq[found_index] = target; else assert found_index = 0; end if; end algorithm; *)
7.5 マルチプロセスアルゴリズム
- すべてのプロセスが終了する前にアサーションを検査する
- ハードコードするのではなく、活性要件(不変条件と違う?)として記述する
<>[]
でアルゴリズムが確実に終了することを検査する
- ステップを
Get
とIncrement
に分けると検査が失敗する- 複数のプロセスが同時に
Increment
へ進入すると、いずれかのプロセスによるcounter
の更新が上書きされてしまう Get
とIncrement
を統合するか、クリティカルセクションを設けるしかない
- 複数のプロセスが同時に
counter: 0 goal: 3 pc: <<"Get", "Get", "Get">> ---- counter: 0 goal: 3 pc: <<"Increment", "Get", "Get">> ---- counter: 1 goal: 3 pc: <<"Done", "Get", "Get">> ---- counter: 1 goal: 3 pc: <<"Done", "Get", "Increment">> ---- counter: 2 goal: 3 pc: <<"Done", "Done", "Increment">> ---- ---- counter: 2 goal: 3 pc: <<"Done", "Done", "Done">> ----
8.1 リンクリスト
- ユースケース
- データ構造は関数、構造体として表すのが一般的
- データ構造の名前と同じ演算子を定義する慣例になっている
LinkedLists(Nodes)
- データ構造の名前と同じ演算子を定義する慣例になっている
Nodes はメモリアドレスの集合である
なんでいきなりメモリの話してるの?リンクリストは関数集合 [ Nodes -> Nodes ] の集合になる
構造体の表記を関数と呼んでいる?
参考リンク
- Practical TLA+ | SpringerLink
- 原著
- 実践TLA+ 電子書籍|翔泳社の本
- 翻訳
- The TLA+ Home Page
- TLA+ の総本山的なWebページ
第6回 Software Architecture: The Hard Parts 読書会@リモート
第6回 Software Architecture: The Hard Parts 読書会 - connpass
- JavaEE勉強会の読書会
- 開催場所はDiscordのjavaee-study-jp
- Neal Ford, Mark Richards, Pramod Sadalage, Zhamak Dehghani さんの Software Architecture: The Hard Parts [Book] を読んでます
- 今回は
Chapter 8. Sysops Squad Saga: Shared Domain Functionality
まで読み進めました - 次回は
9. Data Ownership and Distributed Transactions
から読み進めます- 次回は 2022-05-21(土)です。
- 第7回 Software Architecture: The Hard Parts 読書会 - connpass
- 参加者トピック
- ディスカッション
- Part II. Putting Things Back Together
- Chapter 8. Reuse Patterns
- Chapter 8. Code Replication
- Chapter 8. Shared Library
- Chapter 8. Shared Service
- Chapter 8. Sidecars and Service Mesh
- Chapter 8. Sysops Squad Saga: Common Infrastructure Logic
- Chapter8. Code Reuse: When Does It Add Value
- Chapter 8. Sysops Squad Saga: Shared Domain Functionality
- 参考情報
参加者トピック
- ACMプロフェッショナル会員の特典だったO'Reilly Learning Pathの無料アクセスが6月に終了する
- ブラックフライデーに割引クーポンが出がちなのでそれを待とうかな
- 本はともかくAudio Bookが代替できなくて辛い
- 人間が読んでいる
- 有明テニスの森公園でテニスやってくる
- 原因不明の体調不良が続いてたので、運動不足を疑っている
- 卓球フィットネス始めた、全球スマッシュを強要するのでとても体力を使う
- Oculusで遊べるテーブルテニスVRお勧め
- BlueMix経由でO'Reilly Learning Pathを利用してる
- VPで遊んでいると筋肉が増える
ディスカッション
Part II. Putting Things Back Together
Chapter 8. Reuse Patterns
- Don't repeat yourself - Wikipedia
- WETとは?
- Write every time
- Write enything tiwce
The opposing view to DRY is called WET, a backronym commonly taken to stand for "write everything twice"
- FOAM DRY + WET - YouTube
- 必ずDRYにしないといけない、なんてことはない
Chapter 8. Code Replication
Chapter 8. Shared Library
- バージョン管理のところは、セマンティックバージョニングを前提にしているよね
Chapter 8. Shared Service
- 仮にそれぞれのサービスがマイクロサービスになっているとして、なんで
Shared Service
にアクセスしないといけないのか理解できない- どういう役割なのかわからない
- 誰がオーナーなのかわからない
- 個人的に最高のアンチパターン
- 後方互換性を保つために必要なコスト
- 古いバージョンのアプリ用のコンテナ動かし続けるの大変そう
- サービスの動作を保証し続けるのも大変そう
Chapter 8. Sidecars and Service Mesh
- 前の章とつながってない
- 値引き機能みたいな具体例がいなくなっているのはなんでだろう
- バージョン管理とか後方互換性の話がなくなっているのはなんでだろう
- ヘキサゴナル・アーキテクチャとサイドカーを結びつける論点が弱い
Chapter 8. Sysops Squad Saga: Common Infrastructure Logic
- 結局
JSONtoXML
ライブラリをサイドカーに入れたのか入れないのか- 入れてない
- サイズは重要(たいした大きさじゃないからよしとする)
- 利用したいチームが全体の半数を超えてないから入れない
- 17チームいて半数に満たないってどれだけ巨大な組織なの…
- 質問にちゃんと答えてない感じがする
- Sysops Squad Saga 全体的に納得いかないところが多い
Chapter8. Code Reuse: When Does It Add Value
- ソフトウェアアーキテクチャの基礎第16章と同じ話だった
過剰な再利用がもたらす危険性は、20世紀に流行したオーケストレーション駆動のサービス指向アーキテクチャで、多くのアーキテクトが学んできたことだ。
- 再利用が問題視されていたのは、オブジェクト指向プログラミングのほうの文脈じゃない?
- 共有にしたサービスが知らない知識を取得するため、さらに他のサービスに依存してしまう、みたいなところはたしかに問題っぽい
Chapter 8. Sysops Squad Saga: Shared Domain Functionality
- Taylenの主張が面白い
Taylen: それがどうした。どれもバックエンド機能だから気にする人なんていない。バックエンド機能が高速に応答する必要はないし、失敗したとしてもすぐに復旧するはずだ。