関心ごとの分離

テーブル設計について現在勉強してます! 今日は学習していて気がついた点を書いていこうと思います。

big table

みなさんは業務にあたっていてこんなテーブルに出会ったことはあるでしょうか? userテーブルで一般userと法人userが同じテーブルに表現されている。法人番号カラムを持っていて、要件として一般userは法人番号を保持しない。 ほんとは、法人番号カラムはnot null制約をかけたいが、一般userは法人番号を持たないという制約でnullableにせざるおえない。 一般userと法人userを識別するフラグカラムまたは、Idに特定の文字列を入れてuserの判別を行う。(法人→AD、一般->GE) これらの例だけではなく、様々なカラムが含まれ肥大化したuserテーブルを僕は扱ったことがあります。 このテーブルを見た時に僕は何が一般userに必要なデータなのか考えました。またそれはソースコードにも影響を与えコードを読む時間も増えました。 ここまでで、適切に正規化ができていなのでは??と考えられますし、その通りだと思います。ですが感じなことはuserという抽象的概念をちゃんと咀嚼して 適切に概念整理ができていますか?というところに立ち返りました。

概念整理と関心ごとの分離

ここまで概念整理が適切にできていないと考えられました。適切に考えると法人userと一般userは概念が違います。 なので適切な粒度としてリソース単位で分離することで、関心ごとの分離も行えます。 また適切な粒度で分離することでnullのデータが減ります。 そしてこれはclassの設計にも言えることですが、1つのclassでいろんなことをやらない、に精通しています。 脱神テーブル!!

終わりに

  • 一つのテーブルでいろいろ表現しようとしない。神テーブルを作らない。
  • 複数の物事が表現されそうになったら、隠れた概念が存在するのかを考える
  • 適切にリソースにテーブルを分けるように設計する

アプリケーションの監視

なぜアプリケーションを監視するのか?

アプリケーションは高頻度で、変更修正を繰り返しながら開発するので監視を行い、透明性を維持することは必須。

どう監視するか?

  • 機能に対するメトリクスを収集する
    • その機能の処理時間(レイテンシ)、処理成功失敗回数などを計測する。
    • 例えばログインの成功失敗回数や処理時間の計測を行う。
      • 処理時間に対して、関数実行時から終了時までの時間を計測して、それをメトリックス化するとかかな。
  • アプリケーション自体が動作しているか?
    • health check patternを用いて特定のエンドポイントに対してgetリクエストを投げる。外形監視でもあり死活監視でもある 
  • ログを収集すること
    • ログで取れる内容はメトリックスにも置き換えられる。なぜログを取るか??知りたいデータが構造化されているから
    • ログはなんでもかんでも取らない。ディスクを圧迫するし、データ転送量も増大するので。リソース消費するから。
  • マイクロサービスでは監視の複雑性が増す
    • マイクロサービスではどこからリクエストが始まり、どこへ到達し、何が問題になる可能性があるかが分からなくなる。というかログの解析が難しくなる。
    • 分散トレーシング
      • リクエストに対してIdを発行することで処理の順番を追跡することができる
      • awsだとx-rayが当該のサービスにあたる。

APMとは

  • アプリケーションパフォーマンス管理の略
  • APMを活用することで、サービスのトランザクションレベルのレイテンシースループットに関するパフォーマンスを可視化することができて、アプリ、DB間のトレーシングもすることができる。
  • new relicの場合だと、1つの機能が遅延してましたとなったら、それをメソッドレベルで特定することができる

監視からobservability

  • システムを観測可能、つまり「いつ、何が、どこで起こっているのかを観測可能に保つ」考え方
  • クラウドネイティブ技術の1つ
  • kubernetesを活用した、マイクロサービスではservice, podのトレースの複雑さ、 nodeに分散されたpodをこれらを観察することは複雑性が増す。
  • 本質はユーザーエクスペリエンスの低下や障害が起きた際に迅速に対応するために必要。

www.youtube.com

まとめ

アプリケーションのメトリックス、ログ監視をすることはアプリケーションのパフォーマンスを把握しトラブルシューティングに有用である。 observabilityに関しての勉強を進めていく

イミュータブルなテーブル設計を目指して

本タイトル通り、不変的なテーブル設計目指すため、学習したことを書いておこうと思います。 今までテーブル設計に関して、正規化を守っていれば万事OKみたいな考えのもと、前職でテーブル設計などを行なっていました。 ことの発端はtwadaさんがインタビューを受けているweb音声メディアでテーブル設計の話しを聞いたことがきっかけで、設計に対する根本的な考えを変えないといけないと思いました。

データと情報

データとは

  • いつ、誰が、どの店で、何を、いくら、購入したという『事実』を表す

データとは事実なのです。DBの本質は適切に事実を保存しておくこと。 〇〇したという事実は一過性で2度の再現性はないのです。

この観点から、事実を改竄(update), 損失(delete)するということは、基本的に一般の世の中では不正的な側面もあり行わないと思います。 なので適切にこれらの事実を保存しておくことが第一歩だと考えました。

また、1つのエンティティに複数の意味を持たせないことも重要です。userが部署コード、〜IDをたくさん持っているとか。あくまでuserを形成している要素だけを持たせておくことが大事。

情報とは

  • 「データ」を選択、加工して当事者が必要とする知識(新たな価値)を取り出したもの
  • 情報の必要性と価値は、当事者によって、時期によって、様々に変化する

常に求められているのは「情報」、そのために「データ」が必要!

「データ」は情報を生み出す宝の山!!

そんなデータを簡単にupdate「改ざん」delete「紛失」をアプリケーションで行っている。。

そして、updateは処理を複雑にする原因でもある。

以上から根本的な設計に関しての考えかたを変えないといけないと思いました。

物(resource)とコト(event)という考えかた

現実世界には「ある消費者(user)がスーパーで豆腐を買う」というactionがあると思います。ここでactionを物とコトで分けて考えると

  • ある消費者(物): who
  • スーパーで(物): where
  • 豆腐(物): which
  • 買う(コト): how

という風に分けることができます。

以上を踏まえ、論理モデリングリングする際に実世界の物事をモノ(resource)とコト(event)に分けてEntityとして抽出する作業を行います`。 この時点ではリレーションシップのことは一旦忘れる様にする。そうすることでデータのあるべき姿をEntityに表現しやすくなると考えてます。

モデリングする際は 5w1hを用いる

5W1Hがエンティティの候補

  • Who 従業員,患者,プレイヤー,顧客,生徒,...
  • What 製品,サービス,コース,曲,
  • When 時間,日付,月,年,年度,...
  • Where 送付先,URL,IPアドレス,...
  • Why 注文,返品,入金,出金,取引,…
  • How 請求書,契約書,注文書,…

また、5W1Hの分類において

  • Who, What, When, Where → リソース
  • Why, How → イベント

なんでもかんでも登録日、更新日をつけない

resourceエンティティに登録日は必要だろうか??自然の流れだと、「userがサービスに登録する」が自然の流れで、 ということはuserというresourceがあり、入会と退会に相当するevent エンティティに該当するテーブルを設けることが自然な流れに感じる。

ここで、イベントはそのアクションが行なった日時時刻をもつ性質があるので、カラムとして持たせるが、必ずしもuserといったresorceエンティティは 日付時刻は必要ないと考える。

終わりに

こんな感じで自分の中のテーブル設計の考え方にインパクトを与えられました。 まだまだ、書き足りないですが参考になったリンクを貼っておきます。

scrapbox.io

別のAWSアカウントの管理下にあるドメインを使用してSSL証明書を発行したよ〜

こんにちは〜 季節すっかり梅雨ぽい感じになってきましたね〜 雨が降るから家から出たくなくなります。。(こうして引きこもりになる)

タイトル通りの内容なんですが、実務でelasticserchに向けてフォワーディングしているALBに SSL証明を当てるタスクに取り掛かってました。 正直SSLの発行と、ALBやcloudfrontへアタッチするのは何度もやってきたので問題なくやれるかなと 思ったのですが、SSLの発行を今回は別アカウントで行わないといけませんでした。

そもそも、アカウント別にprod, stg, devと別れていたのですが、今回証明書発行に用いるドメインの ホストゾーンはprod環境にあるホストゾーンを使用する要件でありました。 どうやるんや??と思ったのですが、先輩に教えていただきながらできました。

どうやってたのか?

まず、各環境のACMでprod環境のホストゾーンベースのサブドメインSSLを発行するんですが、 その際に行うDNS検証で作成されたCNAMEをprod環境のホストゾーンで検証用レコードを作成する。 これで、検証は無事ととおりました。 今回初めて行なったのでアカウントを跨いで、SSL発行できるんだと思いました!!

ついでにprod環境のホストゾーンで他の環境のalbに対してのaliaseレコード作成しました。 業務にあたっていてこんなことできたんだって新たな発見でした。 そして安定のクラメソさんの記事に助けられました!!!

参考にしたclassmethodさんのリンクも貼り付けておきます〜

dev.classmethod.jp

dev.classmethod.jp

監視入門フロントエンド編

こんにちは〜 春の心地よ良い季節ですが、最近は天気が悪くそろそろ梅雨に入ったのかな?と思います。 今回はフロントエンドの監視について書こうと思います。

フロントエンドの監視

  • ページのロード時間
  • 例外を監視する

フロントエンドの監視は主に描画速度だと思う。昨今のフロントエンドではjsのファイルサイズが増大していることや、その他ファイルを読み込むことでレンダリング速度に影響が出たりします。 なので、描画速度の監視も行うことは大切だと感じます。 ですが、技術の流れは急速でSSRやSSG技術が出てきて描画速度に対するアプローチがなされています。 とはいえフロントエンドの特性をある程度理解して、監視の問題棲み分けをする上で知識は必要かと思います。 レイテンシを悪化しているのはフロントエンド側なのか、バックエンド側なのかという具合に切り分けする力が必要でそいった思考を持ってアプローチすることでサイトの信頼性は担保できるのではないかなと考えました。

正直フロントエンドの知識は浅いので、こいつ何言ってんの?思われるかもしれません。。。(どんどんツッコミお願いします!)

本日はここまで!ではまた〜

elsticsearchについて調べたよ

最近、E C2にelasticsearchを建てたもにdatadogでリソース監視を設定しました。 初めてelasticsearchに関わったので、勉強して見ました。

elastic searchとは

分散処理が可能な検索分析エンジン。 Elastic社が提供しているElastic Stockというプロダクト群に含まれる。 elastic searchはその中でも、jsonベースの検索/分析エンジンの位置付けとなっている。 特徴として、スケーラブル、リアルタイム、REST APIの提供がある。

ユースケース

  • アプリ検索
  • webサイト検索
  • ロギングとログ分析 などなど

アーキテクチャ

ここに関したはもっと深ぼって記事にまとめます。 elasticsearchはclusterを形成し1つ以上のnode(elasticsearch server)で構成される。 検索トラフィックが増大と書き込み速度の分散をNodeに分散し対応する。 elasticsearchにはindexというものがあります。これがRDBにおけるデータベースです。 レコードにあたるものが、documentになります。そのdocumentはkey valueの組み合わせで格納されており、 fieldといいRDBにおけるカラムにあたります。 indexはelasticsearchクラスター内で形成され、それを分散させる為に各node間でshardという単位で管理します。

ここまでで、elasticsearchはclusterを形成し、indexは各nodeにshardとという単位で分散管理してます。

elastic seatchはjavaで動いている

elasticsearchはjavaで動いています。 nodeのメモリ管理はGCで管理されています。

ドキュメントを保存する時はindexingする

ドキュメントを保存する時にindexingする。 またドキュメントはnodeのストレージに保存します。 documenを保存する際には保存する内容を一旦buffer memoryへ展開し、すでに保存している内容を取得しメモリに割り当てた上で、 buffer上のものと取得してきたものをmergeしてストレージにコミットします。(間違っていたら、ツッコミお願いします。) ということはすでに、保存された内容や保存対象が大きければメモリを消費しますし、それをストレージにコミットする際や取得の際にi/oに負荷がかかります。 加えて、javaで管理されているので、メモリの管理には注意が必要ですし、リソースに十分なメモリを割り当てを行なっていないとGCが頻回動作し頻回にリソースがロックされたり、 逆に大きすぎるメモリを割り当ててしまうと、GCがうまく動作せずメモリが高知で張り付いてしまうこともあるそうです。

なので、基本的なリソース監視も然り、j VMヒープやディスクの監視(容量やIOPS)の監視がポイント(クエリのレイテンシにも影響しそうだし)なのかなと感じました。

datadogで設定していきながら、理解するのに時間がかかりました。 まだまだ理解が追いついていなかったり、間違っていることもあるかと思いますが、今後も学習を継続していくぞー!!!

自前で建てたelasticseachは自動復旧の仕組みが整ってないため、toil撲滅の為今後対応していきたいです。(となるとコンテナかなー) ではまたー。。

リソース監視について

今回はサーバー監視について書いていこうと思う。 先輩から教わった基本的なリソースの監視項目はCPU, memory使用率、IOPS、ロードアベレージをとのこと。

CPU使用率

文字通り、CPUがどれだけ使用されているかを監視している。 基本的にtopコマンドで確認ができる。 us + syを合わせたものがCPU使用率になる。 cloudwotchだとよしなに、値を取得してくれている。 現場ではCPUが80%とかでアラート設定している。ただし、CPUが80%だからといってすぐに対応しないといけない訳ではない。実際にはアラート踏んでオートスケール発火しそうだけど。 というのも、この状態にサイトに影響があるかを把握することが大事。レスポンスタイムが低下していないか、スループットに影響していないかを見極めることが大切。 逆に言えば、リソースを上手く使ってくれている状態であるということ。(いつまでも高値に張り付いていたら、さすがに対応必要だけど。) 逆に低すぎるのも、リソースを上手く使ってくれてない証拠。(となるとロードアベレージの値が上昇するのかな??)

メモリ使用率

文字通りメモリ使用している割合をさす。 上昇の原因としてはGCがうまくいってない。かなり大きい プロセスをヒープに割り当てた。などなど。 こうなっては、カーネルさんはディスクを使ってスワップアウトしちゃいます。 アプリケーションとして高レイテンシーでサイトがカクカク状態になります。 javaなんかは注意が必要だと、先輩はおっしゃってました。GCの影響で上手くメモリを解放できなかったパターンとかよくあると。 直近ではEC2に自前で立てた、elasticsearchがメモリ使用率が高値に張り付いて障害が発生しました。 elasticsearchはjava で動いていてます。

ディスク監視

ディスクの空き容量を監視したり、IOPSを監視したりします。 IOPSとは秒間あたりディスクへの書き込み読み込みがどれくらい行えているかを見る指標になります。IOPSのメトリックスが急に下がり始めたら、ディスクへのアクセスが低下し何らかの問題があると考えられます。

ロードアベレージ

現在のCPUコアに割り当てられていない、待ちプロセス数を表している。(1分の平均、5分平均、15分平均からなる) 物理コア分の待ちプロセスがあったとしたら、それは全然問題ない。上手くコアに割り当てられている証拠。 15分平均のロードが500を超えているWebサーバーがサイトには影響がないパターンもあるらしい。なので、サイトに影響があるかをアセスメントが必要。

以上が学んだことです〜 elasticsearchの監視をDataDogで早く設定しなきゃ〜 最後に参考にした本を記載しておきます〜

ではまた〜