kmuto’s blog

はてな社でMackerel CREをやっています。料理と旅行といろんなIT技術

『Software Design』2023年2月号を読んだ

gihyo.jp

今回もメモで。「AWS活用ジャーニー」が、今勉強しているところと重なって特によかった。

  • 結城浩の再発見の発想法」
    • フィルタのお話。すべてそろってから処理をするのではなく、ストリームのような流れとして考える、なるほど。そういえば、いつのまにか tail -f /var/log/syslog | grep hoge みたいなのでgrep--line-buffered を付けなくてもよくなったのかな。データにもよるか。
  • ドメイン駆動設計入門」
    • 特集1記事。いわゆるDDDの話。ドメインは、ソフトウェアが対象とする領域のこと。ドメイン駆動設計では、事業活動とソフトウェア設計を直接強く関連付けることを目標とする。事業活動は複雑な業務ルールからなり、ドメインの複雑さがソフトウェアの複雑となる原因。
    • ドメインモデル。複雑な業務ルールを動くソフトウェアとして実現して変更を楽で安全なものにする手法のためのモデル。ドメインの事業活動の複雑さの要点を整理・簡略化したもの。「カジュアルな会話」「ラフスケッチ」を重視。ソースコードで表現。3つの目的「設計の基本構造」「抽出した業務知識」「意図伝達の中心となる言葉」。
    • 知識をかみ砕く。業務のやり方や決め事を理解し、重要な点を見い出し、コード化する。
    • 業務を書く理解していくことで、重要な経営課題を捉え、設計に反映する。
    • 用語の部門や人による違いを、一貫した同じ言葉であるユビキタス言語にして解決する。当面の課題にとって重要な言葉から選び、意識して使う(全員の会話、クラス名やメソッド名、コミットログなど)。選び抜かれた軸となる言葉の集まりがドメインモデルとなる。
    • 当面の課題に必要・重要な情報だけを抜き出す=モデルを作り出す。
    • モデルと実装を一体化、バインドする。「設計にそのまま使えるモデルを使って知識の整理や意図の伝達も」「設計、知識の整理、意図の伝達の3つの用途に役立つ1つのモデルを見つけ、成長させていく」。バインドのパターンとして値オブジェクトや集約。
    • アプリケーション開発での適用。複雑な業務ロジックに関心を当てる。複雑な業務ロジックを独立した構成要素として分離。アプリケーションのほかの構成要素を業務ロジックを表現した構成要素に依存させる。複雑な業務ロジックに直接関係する部分に焦点し、そうでない部分は周辺的な関心事として分ける。
      • ドメインモデルで業務ロジックを独立させる。
      • ドメインモデルを中核に、周辺要素(画面、データベース、通信など)がある。つなげ方には、ドメインモデル+3層構造、ドメインモデル+ポート&アダプター、クリーンアーキテクチャといった考え方がある。
    • 複雑な業務ロジックとそうでない要素の混在を分離する。表現クラスを厳密に分離、複雑な業務ロジックを表現するクラスだけをドメインモデルに置く、両方のクラスを合成するクラスを作成する、合成用クラスのオブジェクト組み立てや業務ロジッククラスオブジェクト抽出を処理するクラスをドメインモデルの外に置く。混在はよく起こるので、こまめにリファクタリングする。積み重ねることで、業務知識の深い理解となり、隠された概念を明示的にする方法を発見できる。
    • ドメイン駆動設計とXP(特にリファクタリング、顧客との頻繁な対話)とは相性が良い。アジャイルウォーターフォールでもある程度は取り入れられるが、効果や速度などに差が出るだろう。
    • 2章以降はかなりガッツリDDD実践。ちょっと腰据えて読まないと理解できなさそうなので、後回しで。
  • 「今さら聞けないログの基本」
    • 特集2記事。syslog、journald、Apache/nginxのアクセスログの見方と、自作のアプリケーションからログを書き出すときのメッセージプラクティス。ログフォーマットはぜひ機械処理しやすいものでお願いしていきたい。
  • 「画像生成AIのしくみ」
    • DALL-E2やStable Diffusionなどのテキストからの画像生成(text-to-image)AIの仕組みの話。テキストエンコーダと画像生成器からなる。エンコードされたテキストは低次元(数百次元程度)ベクトル化される。意味的に近いベクトル同士は空間的にも近く、単語に対応するベクトルと、その単語の画像に対するベクトルは近いと期待される。類似品も近くなるし、かけ離れたものだと遠い。
    • DALL-EはテキストエンコーダにTransformer、画像生成にVQ-VAE。モデルパラメータは120億(従来は数千〜数億程度で圧倒的)。画像とALTテキストのクロールで2.5億の画像・キャプションペアを収集。質を量で圧倒。
    • DALL-E2・Stable Diffusionでは大規模text-to-imageに適したアーキテクチャを追求し、テキストエンコーダに事前学習済みTransformer、画像生成に拡散モデル。
    • 自然言語の理解、テキストの適切なベクトル化。言語モデリングによる事前学習。トークンに分割して確率分布をモデリングする。CLIPテキストエンコーダは画像との対照学習で訓練されている。
    • 訓練データを増やすほどモデルの精度が高くなる。スケーリング則。大規模言語モデルの例がBERT、T5、GPT-3。
    • わかりやすい指示により回答の精度を上げる。プロンプトエンジニアリング。
  • 「『らしさ』の本質に迫るGo言語」
    • H.Sakiさんの新連載。Goが守りたいシンプルさは「明確で過不足がないこと」。書き手の意図が明確であること、コードがどのように動作するか明確であること。
    • Goはコンパイル前のコード段階だけでなく、コンパイル後の段階まで含めてのシンプルさ・明確さを要求。
    • 過不足がない。1つだけあるベターな書き方を提供する。スケーラビリティを確保した、優れたプログラムを書くために必要、という軸。長期的に見てメリットがあるよう設計された取捨選択。
    • コードに信頼性、開発に生産性をもたらす。
  • 「最強の開発環境探求の道」
    • fzfの使用方法。使ってなかったけど、便利なのかなこれ。「| fzf」を付けたり、xargsを書いている間に試行のほうが早いこともありそうなので、使い勝手が難しめか。historyと組み合わせるのは確かにありかも。
  • 「リソースから考えるBCPの手引き」
    • 組織的リソース=人・組織・建物・金。脅威に対して事前に準備・対策を考えられる。脅威により対応の時間的余裕が異なる。事前予測できる脅威に対して備え、事業への影響を最小限にする。
    • 組織的リソースそれぞれの観点での、被害を極小化するための事前対応、被害拡大を防ぐための初動対応、事業復旧のための復旧対応。
    • リソースの「代替」がBCPでは大事。「〜がないからできない」では継続できない。
    • 地震の場合は1〜3日を災害対応、4日以降から事業継続へシフトしていく。
  • AWS活用ジャーニー」
    • 今回はDynamoDB。フルマネージドなキーバリュー型NoSQL DB。NoSQLなので、少ないテーブルに収納することがベストプラクティス。1アプリケーション1テーブルくらいを目指したい。CRUDに相当するAPIがあるが、Scanはフルテーブルスキャン相当で効率が非常に悪く、できるだけ使わない。PutItem、GetItem、UpdateItem、DeleteItem、BatchGetItem(最大100個)、BatchWriteItem(最大25個)、Query、Scan。
    • テーブルはスキーマレス。プライマリキーはある。パーティションキーのみのシンプルプライマリキー、パーティションキーとソートキーの組み合わせの複合プライマリキーの2種類をサポート。
    • キーに紐付けて項目を保存する場所がパーティション。カーディナリティが低い(データの種類が少ない)属性をパーティションキーに選ぶと特定パーティションにアクセスが集中するホットパーティション問題が発生する。
    • 読み取りAPIが限定的なので、LSI(ローカルセカンダリインデックス)を使う。テーブル属性→インデックスコピーを射影という。属性が不足すると追加データ取得が必要、不要な属性が多いとストレージ消費。同じパーティションキーを持つ項目の合計サイズは10GB。LSIを作成できるのはテーブル作成時のみで、5個まで。
    • GSI(グローバルセカンダリインデックス)。非キー属性に対するクエリに強い。常にQueryかScanを使用。GSIは20個まで、テーブル作成後でも作成できる。
    • 読み書きに応じてのキャパシティユニット消費(RCU/WCU)。料金モデルを決定するのがキャパシティモードで、プロビジョンド(秒あたりのRCU/WCUを指定し確保。リザーブドもあり)とオンデマンド(実際の消費ぶん)がある。プロビジョンドで足りないとスロットリングする可能性。
    • テーブルクラス。標準、標準-IA(アクセス低頻度用。保存料金安・RCU/WCU高)。
    • 標準バックアップ。PITR(ポイントインタイムリカバリ)は過去35日の任意の時点に復元可。オンデマンドバックアップは35日以上の長期保存向き。実際には巻き戻しではなく新しいテーブルが作成される。復元後、手動設定をする必要あり(Auto Scaling、PITR設定など)。
    • AWS BackupはDynamoDBとも統合。
    • 項目のイベントに対してストリーミング。DynamoDB StreamsはLambdaとDynamoDB Streams Kinesis Adapterに対応。Amazon Kinesis Data Streams for DynamoDBはLambda・Kinesis Data Analytics・Kinesis Data Firehose・Glue Streaming ETLなどに対応。全文検索をOpen Search Serviceに投入するなど。
    • DynamoDB Acceralator、インメモリキャッシュサービス。マイクロ秒単位の応答対応。API互換なので透過的、アプリケーションはエンドポイントを切り替えるだけ。
    • DynamoDBグローバルテーブル、マルチリージョン化。自動でレプリケーションされる。
  • 「魅惑の自作シェルの世界」
    • 終了ステータスとシグナルの実装。execでEACCESとENOENT以外のケース、どういうものがあったっけかな。
  • 「現場を支えるPlaybook」
    • Ansibleで個々のタスクに分かれがち・作りっぱなしだったのを、Roleで再利用しやすい単位に再構築してみた話。Terraformあたりでも類似のケースありそう。
  • Kubernetesネットワークのしくみ」
    • 最終回だった。minukubeでローカルKubernetesクラスタを作り、サービスメッシュのIstioを実行する。外部からのアクセスはminikube tunnelを通してIstio Ingress GatewayGateway→VirtualService→Service→Podという流れをたどる。IstioのKialiアドオンツールを使うと、マイクロサービスの状況をダッシュボードで確認できる。
  • 「エンジニアも知っておきたい法律知識」
    • 個人情報の定義。氏名や生年月日など、特定の個人を識別できる場合、氏名や生年月日の部分のみならず、氏名や生年月日を含む「情報全体」が個人情報に該当。個人情報にあたるかどうかと、公開情報かどうか・プライバシー性があるかどうかは関係がない。
    • 他の情報と容易に照合できることによって特定の個人を識別できる、つまりDB A(個人情報)とDB B(氏名等を削除したもの)をキーなどの照合で容易にできていると、「容易照合性がある」ものとしてBも個人情報。
      • Bだけを第三者に提供する場合、第三者側は個人の識別はできない。しかしAは依然として容易照合性があるため、「Aは個人情報を第三者に提供した」と見なし、本人同意が必要。
    • 顔や指紋のようなデータ、あるいはパスポート番号や運転免許証番号などの法令で具体的に定められた「個人識別符号」を含む情報は個人情報。携帯電話・クレカ番号・クッキー・広告IDは個人識別符号ではない、が氏名や生年月日といった情報と併せて管理されていたら識別子を含めて個人情報。
  • SD Staff Room
    • 目次下部の本文デザインも併せて毎回ここも拝見しているのだが、池本さんの肩書きがとうとう猫編集長になってしまった…。

GoogleのセキュリティキーTitan Security Keyを試した

世の中2要素認証でスマホがほぼ必須(SMSなりAuthenticatorなり)になってしまっているけれども、海外で盗まれやすそうなもの第1位もスマホというところはあり、あまりスマホに2要素を委ねたくないなぁ……と思っていた。

とつぶやいていたら、「セキュリティキーいいよ」と@Henrichさんからアドバイスを受ける。

面白そうなので、相方にねだって、昨年のクリスマスプレゼントとしていただいた。

store.google.com

タイプはUSB-Cのもの。スタイリッシュな感じはなかなかよい。差し込み口がむき出しなので、雑にポケットに突っ込んだりすると折れるかもしれない。上部はキーホルダー用の穴が空いている。

セットアップは簡単で、たとえばGoogleアカウントの場合はセキュリティ設定でセキュリティキーを選び、USBポートにキーを挿してボタンを押すだけ。これで紐付けがなされる。 2要素認証が必要なときには、同様に挿してボタンを押せばよい。

Titan Security Key

逆に言えば、スマホ指紋認証や顔認証と違って生体認証が事前に行われることはなく、指紋認証のないただの物理ボタンなので、押すだけで通る。もちろんその前にパスワード認証はあるので、正しく2要素認証ではあるのだが若干不安がある。

NFCのほうはまだ試していないけど、こちらはUSB接続することなく、iOSAndroidに近づけてボタンを押すだけで済むようだ。うらやましいのでPCでもそうしたい。macのCポートは貴重で埋まってるし、Linuxマシンは背面にCポートがあるので微妙に使い勝手が悪いのだった。前のSecurity KeyはBluetoothだったのがセキュリティ的にいろいろマズくてUSB+NFCだけになったんだね。

いくつかのサービスを試しに登録してみたけど、セキュリティキーが使えるサービスは今のところさほど多くない(SMSとAuthenticatorアプリのみ、みたいな)。 もともと「これ用に」と思っていた用途については現状非対応で今後もどうだろうなぁという感じがしているので、使い道を変えないといけなくなっている。

旅行だと、スマホを持ち歩きつつ、別途キーはバックアップとして隠し持っておく、といった使い方がいいんだろうか(しかし海外いつ行けるかねぇ…コロナもあるけど、有給休暇をだいぶ大事に使わないといけないので、前職のときのような気軽には行きにくくなっている)。