地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Nginx】ログの出力可否

特定UAの場合ログに書き込みたいくないみたいなケースがあってどうにかならないかみていたらaccess_logはifで状態を取れるらしいことに気づいた。

nginx.org

Syntax:  access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default:    
access_log logs/access.log combined;
Context:    http, server, location, if in location, limit_except

サンプル通りやるならmapで変数を使うやり方

map $status $loggable {
    ~^[23]  0;
    default 1;
}

access_log /path/to/access.log combined if=$loggable;

ステータスコードが200系 or 300系ならログに書かないやり方。uaも同じように書けば特定uaだけログに出力しないみたいなことが可能

【DB】ACIDの話

Atomicityとは

トランザクションが残す結果が、すべてのトランザクション内操作が成功したか、もしくはすべて無かった事になったかのAll or Nothingになる特性の事をいう。不可分だとかは関係ない(というかトランザクションの個々の操作はインターリーブされることを前提として考えるので可分かどうかは主題ではない)。 複数のデータに読み書きをするにしても、全部のデータに対する更新が成功したか否かが中途半端な結果にならずに終わるという性質である。

Consistencyとは

予めシステムに与えた制約条件(存在しない外部キーを参照してはならないとか)を破るようなトランザクション成功しないという特性である。Atomicに操作が行われてるならConsistencyが破られる事はないんじゃない?という疑問を浮かべる人もいるが、トランザクション操作というのは容易に制約(Constraint)を破る。この用語が提唱された頃はシステムに与える制約条件として詳細なアプリケーションのドメイン知識を埋め込めばトランザクションに乗っかるだけで全部ハッピーというような構想があったようにも見えるが、イマドキの開発ではUNIQUEとかNOT NULLとか結構限定的な制約しかロクに使われていないように見える。 ActiveRecordなどはユーザレベルで制約条件に相当するような仕組みを作りこんでおり、どこまでがDBの責務であるべきかというのは結構難しい問題である。 Peter BailisらによるFeral Concurrency Control: An Empirical Investigation of Modern Application Integrityの論文なんかでは「DB開発者がせっかくトランザクションの仕組みを作りこんだ割にアプリ開発者たち(とORマッパ作者たち)はほとんどトランザクションを使わず、データのValidationやらユーザレベルでの不変条件保護に労力を割いている。本当に必要なのは現状のリレーショナルモデル+トランザクションではないのでは?」と問題提起をしており大変興味深い。長くなってしまったので詳細はまた別の記事で。

Isolation

トランザクションを実行する過程が外のトランザクションから独立して見えないという性質を言う。Atomicityは結果についてしか議論していない一方で、Isolationは過程の可視性に関する議論である点が多くの人にごちゃまぜに認識されやすい箇所である。 さて、トランザクションの実行過程が外のトランザクションから見えてはダメかというと厳密な事を言うと過程が外のトランザクションから見えてしまっても問題はないケースは考えられうる。極端な話、VSRであれば自分以外のトランザクションによる未コミットな値を読んでしまってもそっちのトランザクションがコミットした後に自トランザクションをコミットに持っていくのは有りであるし、Serializableであればどうとでもなる。 また、世の中の一般的なDB(Oracle, MySQL, PostgreSQL, SQL Server, DB2などの有名ドコロ)のデフォルトのIsolation Levelは最弱より1〜2歩強いだけでありこれをもってして「ACIDのすべてが守られています」なんて言うと顰蹙を買うことになる。よってACIDのうち一番ないがしろにされがちな不憫な特性である。 Isolation Levelに関する詳細は明日まとめて書く。

Durability

トランザクションがクライアントに完了をひとたび報告したなら、そのトランザクションの結果は上書きされない限り例え電源が消されようと残る、という性質である。どの永続デバイスにどのように保存されるかは規定しておらず、ディスク上のDBに変更が反映されているかも知れないし、Redoログの形で残っているだけかも知れない。 大学の時この話を聞いて「じゃあHDDが物理的に壊れても残るの?」と素朴な疑問を抱えたものだが、結論から言うとデータベースを格納しているHDDが突然吹き飛んでもメディアリカバリという仕組みで復旧できる所までセットでのDurabilityのようだ。メディアリカバリはログデータを必要なだけリプレイすることでメディアのデータを再生成するわけで、ログデータは常に安全な場所に(永久に)保管されて消失しない前提を暗黙に置くことが多い。とすると「ForceするタイプのDBはRedoログは要らない」と僕は過去に書いたが、ログからのメディアリカバリの為に結局Redoログをアーカイブに保存する必要がある事になる。 このDurabilityという特性はナイーブに実装するとパフォーマンスが全く出ない。それを改善するために人類が積み上げてきた最適化の歴史が面白いからいろんな人に知ってほしいというのがそもそもこの1人アドベントカレンダーを書いている主たるモチベーションであり、いろんな人に伝わったら嬉しいなと思っている。

【AWS】Amazon Web Service 負荷試験入門の読書メモ

概要

Amazon Web Services負荷試験入門 ――クラウドの性能の引き出し方がわかる Software Design plus | 仲川 樽八, 森下 健 | 工学 | Kindleストア | Amazon

この本を読み始めたので気になったところとかをメモしていく

目次

負荷試験PDCAサイクル

負荷試験におけるPDCAはざっくり以下の流れ。一回で終わらせるのではなく回していくのが大事

  • Plan 負荷試験計画の立案
  • Do 負荷試験の準備及び実施
  • Check 計画時に立てた目標値と前提条件をクリアしたか
  • Action 負荷試験レポートの作成、システムの改善

試験なので合否を出してレポートまとめて終了みたいな場合が多くなりそうだが小さなPDCAを継続的に改善していくのが大事。

1章 間違いだらけの負荷試験とWebシステムの失敗事例

間違いだらけの負荷試験負荷試験は試験内容的にも後回しにされがちで最後の最後にさっとやって終わらせるケースが多い。負荷試験で問題が起きるとボトルネック次第では手戻りが大きくなるのできちんとスケジュールを組み込んでおく必要がある。

あとは基礎知識がない状態で負荷試験に挑むとレポートが実は誤りだらけであまり意味のないレポートが出来上がってしまい運用時に困るケースがある。間違った試験に気づかないまま試験完了とならないようにきちんとレビューなりで試験項目やレポートを確認する必要がある。

2章 Webシステムの設計手法

システムの設計手法

オンプレ時代/クラウド時代のwebアーキテクチャの説明とそれぞれの特性の違いなど

可用性に影響する起因

  • ネットワーク
  • 電源
  • ハードウェア

などなど可用性はソフトウェアだけで語れる部分と語れない部分が存在する。可用性の計算はシステムが直列になっている場合はそれぞれの積になる

単一障害点

システムは冗長化することで単一障害点をなくすことができる。別系統であるのが重要とされているが別系統ってみるレイヤ次第でどこまで変える必要があるのかなど考慮点は多いと感じた。(AWSでいうMulti-AZなど)

冗長度は以下の式で求めることができる

1 - (単一機器の利用不能率)^冗長度

冗長度を上げることで可用性が向上する

クラウド時代のシステム構築

ここでのクラウドとはオンプレ時代と違って自社でハードウェアリソースを調達せずにクラウド事業者の所有するリソースを時間単位で借りて利用できるシステム。

(馬鹿でかい会社だとプライベートクラウドのような概念も存在して自社でハードウェアを調達するがアプリケーションエンジニア視点では意識しないのでこの書籍でのクラウドにはプライベートクラウドも該当すると思って読んでいる)

この章はあとは代表的なクラウドデザインパターンの紹介と特性の説明となっていた。以下のサイトも詳しいので補完的に読むのに良さそう。

aws.clouddesignpattern.org

堅牢性とは

可用性と似た言葉に堅牢性という言葉がある。可用性とは違った概念を指していてデータ欠損が発生しない数値を示す。

3章 負荷試験の基本知識

負荷試験の基本知識

クラウド時代の負荷試験の目的

この章がとても刺さった。

クラウド時代の負荷試験はいわゆるオンプレ時代のようなハードウェアの選定や性能改善に必要な数値の割り出しの他にスケール性の評価が重要だということ。スケーラビリティはオンプレではあまり意識することなかったがクラウドはスケールが簡単に行えるので例えば単体サーバでの性能は重要ではあるが重要度はそこまで高くなくてサーバをスケールアウトやアップすることでサービス提供能力が高まることの方が大事。

スループット とレイテンシ

  • スループット -> 単位時間に処理を行う量のこと
  • レイテンシ -> 処理時間

それぞれ明確に意味は異なるがどちらかを改善するともう一方も改善したりと関連性はあったりする。またそれぞれ依存するサブシステムが存在する場合はそこの数値のうち最小値がボトルネックとなり得るので意識する必要がある

悪い負荷試験

  • 試験対象システムに負荷が集中していない
    • 試験対象外の場所に負荷が集中している状態
  • ボトルネックを特定できていない
    • 負荷試験の目的としてどこをスケールさせれば性能が出るかなどを知るためにやったりもするのでこの観点は大事

4 負荷試験のツール

負荷試験を行うためのツールである攻撃やプロファイリング/モニタリーングツールに関しての選定基準など。選定基準には攻撃力についてなんかもためになった

  • 攻撃ツール -> システムに負荷を与えるツール
  • モニタリングツール -> システムのリソース状況を観測し可視化するツール
  • プロファイリングツール -> ミドルウェアやアプリの内部の動作を可視化するツール

(プロファイリングは使ったことないけどflaskとかspringにあるような高機能なものはいつか使ってみたい)

攻撃ツール

モニタリングツール

プロファイリングツール

5 負荷試験の計画

計画の立て方や目標値の設定方法など

6 負荷試験の準備

事前に必要な準備について

7 負荷試験の実施1―試験実施とボトルネックの特定

8 負荷試験の実施2―原因分析とシステムの改善作業

9 負荷試験レポートの作成

10 負荷試験実践のケーススタディ

11 巻末資料

その他

負荷テストの目的