Github製エディタAtomでパッケージを作ってみた

先週にpublic betaが始まったgithub製のエディタのAtomを使ってみたので、旬な内にパッケージ (他のエディタでいうところの拡張とかプラグインとか)を作ってみました。 公式ドキュメントが充実しており、開発が活発(バージョンも毎日にようにあがっている)で変化も大きそうですので、ちゃんと触りたい方はそれを読んだほうが良いと思いますが、雰囲気を知りたい人向けの解説を書いてみました。

Atomのエディタとしての基本的な使い方は、次のリンクをどうぞ http://qiita.com/spesnova@github/items/d3096d062d70e7385e9d

Invite権もまだ残っているので、欲しい方は@stanakaまでmentionしてみてください。→権利終了しました

パッケージ作成の基本

パッケージ作成の基本は、次の二つの公式ドキュメントを読むと分かります。 - https://atom.io/docs/v0.64.0/creating-a-package - https://atom.io/docs/v0.64.0/your-first-package

特徴をざっと並べると次のようなものです。 - coffee scriptでnode.jsのmoduleとして書く - activate, serialize, deactiveのメソッドを用意する (後ろの2つはoptional) - activateのところで、コマンドに対応するメソッドの登録などを行う - package.jsonがパッケージのメタデータで名前やらバージョンやら依存ライブラリやらを記述する - スタイルシートやキー/メニュー設定もここに記述

開発者向けエディタだけあって、プログラミング言語のサポートも標準であり、syntax-highlightも実装しやすくなっています。

カーソル上の単語をDash.appで検索するためのパッケージを書いてみたのですが、本体のコードはコンパクトにあっさりと書けました。

module.exports =
  activate: (state) ->
    atom.workspaceView.command "dash-on-cursor:open", => @open()

  open: ->
    editor = atom.workspace.getActiveEditor()
    return unless editor?

    token = editor.tokenForBufferPosition(editor.getCursorBufferPosition())
    return unless token?.value

    grammar = editor.getGrammar()
    docsets = grammar2docsets[grammar.name] if grammar
    if docsets
      shell.openExternal("dash-plugin://keys=#{docsets}&query=#{token.value}")
    else
      shell.openExternal("dash://#{token.value}")

またパッケージの雛形も「Package Generator: Generate Package」で生成されますので、書き始めもイージーです。テストも標準でサポートされており、モダンですね。

標準機能の多くもパッケージとして実装されており、 https://github.com/atom で公開されいます。こういう機能はどう実装すればいいのかな、と悩んだ時に参考になります。

パッケージを公開する

Atomにはapmというパッケージを触るためのコマンドが付いてきて、それで簡単に公開することができます。これも詳細は次の公式ドキュメントを参照してください。 - https://atom.io/docs/v0.64.0/publishing-a-package

公開手順はgithub上にリポジトリを作っておいて、

apm public minor

とするだけで公開されます。

実行結果は次のようになります。

% apm publish minor
GitHub Username or Email> stanaka
Password>
Saving token to Keychain ✓
Registering dash-on-cursor ✓
Preparing and tagging a new version ✓
Pushing v0.1.0 tag ✓
Publishing dash-on-cursor@v0.1.0 ✓
Congrats on publishing a new package!
Check it out at https://atom.io/packages/dash-on-cursor

実行するとこんなコミットとタグの付与が自動的に行われます。 https://github.com/stanaka/dash-on-cursor/commit/07643903b7e5a3129c269b04d50123e9c694dfc0

githubのidとパスワードの入力が求められるので、ちょっとヒヤッとしますが、version番号の管理までされるのは便利です。

というわけで、カーソル上の単語をDash.appで検索するためのパッケージを公開してみました。 https://atom.io/packages/dash-on-cursor

DashとAtomを使っている方はよろしければお使いください。

「インフラデザインパターン」を読みました

「インフラデザインパターン」を献本いただきましたので、ざっと読んでみました。いつもありがとうございます!

インフラデザインパターン ~安定稼動に導く127の設計方式 (WEB+DB PRESS plus)

インフラデザインパターン ~安定稼動に導く127の設計方式 (WEB+DB PRESS plus)

「インフラデザインパターン」は、NTTデータの人による各種システムのインフラを設計する上でのいろいろな設計方法をパターンとして整理した本です。内容は、可用性、セキュリティ、性能、保守性や、サーバーネットワーク構成、クラウドまで言及されていて、網羅的に書かれています。 例えば、DBサーバの可用性のところは、FTサーバー、並列DBクラスタ、N+1クラスタ、相互待機クラスタと、それぞれの定性評価がかかれていて、確かにこれぐらいの選択肢はあるよね、ということが一通り書かれています。NTTデータの人が書いているだけあって、世の中の数あるシステムの様々な要件を満たすために必要なパターンが書かれています。

AWSのようなクラウドを主体としてWebサービスを構築する上では、選択肢にはなり得ない技術(典型的にはFTサーバ)もあって、教養として知っておくのは良さそうです。ただ、Webサービスの可用性や性能を挙げるための観点でいくと、ちょっと低レイヤーの技術/機能に寄りすぎの印象です。もっと上のレイヤーのアプリケーション自体やミドルウェアの機能を有効活用して、可用性とスケーラビリティを担保するほうがモダンな設計だと思います。もちろん、それぞれ適材適所ということです。

というわけで、ウェブに限らず、世の中のシステムで可用性などがどのように確保されているかの一端を知るのには読んでおいても良い本だと思います。

デザインパターンの粒度

ちなみに余談ですが、一部のパターンで特定の技術、例えば「生体認証パターン」で生体認証を使うとだけあって「えっこれもパターン??」となるところもあり、パターンという言葉を多用し過ぎなんじゃないかと思いました。オブジェクト指向の継承を、継承パターンと呼ぶような違和感ですね。GoF本ではあの厚さで23パターンですし、デザインパターンと称するならもうすこし汎用性と抽象度を挙げたほうがいいんじゃないかと思いました。

2014年のウェブシステムアーキテクチャ

(Monitoring Casual Talk in Kyotoで発表してきたので、ブログエントリにまとめ直しました)

2013年はインフラ周りの技術的な進化が大きく、いくつかのエポックメイキングな概念と実装が産まれました。個人的には特に以下の2つが大きいと思っています。

  • AWSの本格普及期
  • DockerとImmutable Infrastructure

これらを踏まえて、2014年のウェブシステムの進化の方向性を考えてみます。また、それによるモニタリングへの影響もあわせて考えます。だいぶ長くなってしまったので、急ぐ人は最後に結論をまとめましたので、そちらからどうぞ!

2013年という時代背景

AWSが本格普及期を迎えているのは、言わずもがなのことで、Re:Inventでの246件という膨大のセッション数などにその勢いが表われています。 また、DockerはLXC (LinuX Container)をベースとしたコンテナ型仮想化技術で今年の夏前にリリースされ、現在、開発が活発に進められています。Immutable Infrastructureは、このところを周りで話題になった概念で一度構築したサーバに変更を加えず使いすてにしよう、という概念です。詳しくは、今さら聞けない Immutable Infrastructureに良くまとめられていますので参照してください。

これらを踏まえると、2014年のウェブシステムアーキテクチャは、状態を持たない Stateless Server と状態を持つ Stateful Server の2種類で扱いが変っていくだろうと考えています。

Stateless Serverの扱い

状態を持たない Stateless Server は、アプリケーションサーバーやリバースプロキシサーバー、キャッシュサーバー、ロードバランサーなどのことです。これらのサーバーは、本質的には状態を持つ必要がないため、いつ壊れてもよいし、再作成も容易にすることができます。そのため、負荷に応じて必要十分な数だけフレキシブルに増減させることが、もっとも効率的です。サーバーを増やしたり、減らしたり、設定を更新したり、切り戻したりするオペレーションコストをいかに減らすかが勝負どころです。

前述したImmutable Infrastructureという概念は、これらの状態を持たないサーバーに対し、変更を加えない、という制約を加えることで、このオペレーションコストの最小化を狙っています。これにより、自動的にサーバーを増減させる Auto Scaling や、アプリケーションをデプロイする際にアプリケーションサーバーを全て入れ替える Blue-Green Deployment といった手法が現実的に使えるようになります。

また、これまで Provisioningツール(サーバーをセットアップするためのツール)として、Chefpuppetなどが登場し進化してきましたが、これらのツールが目指していた冪等性(再実行しても結果が一定になる性質)の保証が不要となり、Chefやpuppetの設定を構築、維持するためのコストを減らすことができます。

冪等性が保証されている状態を構築したり維持することは、設定がすっきりと記述されて気持ちよいのですが、多くの人が使うにはそのためのコストは高すぎるという問題があると感じていました。そのため、Immutable Infrastructureという概念を取り入れることで、冪等性を気にする必要がない手法が使われるようになり、よりシンプル、かつ汎用的なツールによる環境セットアップ手法に回帰すると考えています。また、configspecのような軽量で多少抽象化されたツールが普及する可能性もあります。

Dockerの登場

AmazonNetflixで実践されているImmutable InfrastructreやBlue-Green Deploymentは、EC2上でAMIをイメージを作りつつ、インスタンスを起動停止させているようです。しかし、次のような問題があります。

ここにDockerを使うことで、起動・停止の高速化とコストの最適化を図ることができます。

Dockerを利用した開発プロセス

またDockerを利用することで、開発、テスト、プロダクション環境を全て同一のDockerイメージを使うことが可能となります。具体的なフローとしては、次のようになります。

  • 手元で開発しつつ、Dockerイメージを作成
  • Dockerイメージをイメージリポジトリに登録
  • JenkinsでCIテストする
    • テストが通るとデプロイ可能な状態に
  • Dockerイメージを本番サーバにデプロイ
  • 本番サーバで起動イメージを差し替えてDocker再起動

本番サーバへのデプロイや、Docker再起動、ロードバランサーへの組込みは、複数のホストを効率的に管理するためのクラスタ管理ツールの役割りとなります。

Cluster Management / Orchestration

Immutable infrastructureの実践により、サーバ増減や切り替えが頻繁に発生するようになり、クラスタ管理ツール(最近の用語だとOrchestration tool)の重要性が増大します。クラスタ管理ツールは、重量級のものから軽量級までいろいろな選択肢がありますが、基本的には、次の機能が求められます。

  • 同じ役割りを担う複数のホストを管理する
  • ホストが増減した時に、周辺システム(ロードバランサーなど)との協調動作させる

この領域は、現在様々な実装が表われてきているところで、どれか一つに集約する、というよりは、それぞれの環境に合わせて、いくつかのツールが共存することになるのでは、と予想しています。ここでは、個人的に注目しているツール群について紹介します。

  • Serf
    • シンプルなクラスタ管理ツール
    • ゴシッププロトコルによる協調動作
    • クラスタに組込む/外すなどのイベントをトリガーに任意のコマンドを実行できる
  • Apache Mesos
  • Flynn
    • Dockerを利用したPaaSのOSS実装
    • Mesosより軽量な実装
  • SmartStack
    • SOAによるアーキテクチャの構築を容易にするツール
    • Nerve .. サービス登録/発見
    • Synapse .. HAProxyベースでのルーティング

使い勝手のよいクラスタ管理ツールは、ロードバランサー(LVS, HAProxy, ELBなど)との協調動作が容易で、筋の良いオートスケーリングとService Discoveryのサポートがされたものになるだろうと考えています。実際にプロダクション環境に適用すると、Deploy直後の負荷の吸収など種々の実装上の問題を解決する必要が出てきますが、このような問題をうまく解決できるようなツールが生き残っていく可能性が高いと思います。

ログ管理

Immutable Infrastructureを実践するには、各ホストで状態を持ってはいけないので、ログのようなまさに状態が保存された要素はできる限り速やかに外に出す必要があります。そのためには、fluentdのようなログ転送ツールが全てのホストに配置されることは必須になるでしょう。

なにか問題が発生した際には各サーバにログインするのではなく、集められた中央ログサーバで処理することになりますので、ElasticSearch + Kibanaのような便利なデータ可視化ツールの重要性も増してくるでしょう。

Stateful Serverの扱い

これまで状態を持たないサーバについて考察してきましたが、状態を持つ Stateful Server となると状況は一変し、まだまだ泥臭いオペレーションが必要とされます。 Stateful Serverは、DBサーバ、ファイルサーバなどのデータソースですが、2014年以降は状態を持つサーバー群をいかにうまく扱うかが焦点となるでしょう。

ただ、ここ数年のハードウェア進化、特にSSDの普及と成熟化により、小〜中規模の用途においてはスケールアップで対処することが一般的となってきています。従来は、master-slave構成としていたものが、slaveへの参照を不要としmasterのみでの運用とすることで、開発上の懸念を減らしたり、オペレーションコストを下げる選択肢も一般的になりそうです。(参考: データベースのmasterとslaveの使い分けの話。2014年版 )

また、Amazon RDSで十分な用途もあるでしょう。Amazon RDSはマスターフェイルオーバーの時間が遅いことが最大の問題ですので、ここが克服されれば応用範囲はさらに広がりそうです。

一方、大規模な用途においては、やはりスケールアウトさせるしかなく、いかにデータ分割するか、参照負荷を分散させるか、というこれまでのオペレーションが鍵となります。

この領域で2013年に注目されたものは、FacebookMySQL Pool ScannerMySQLオペレーションの自動化を行うという未来を見せてくれています。具体的には、「レプリ投入」「マスタフェイルオーバー」「キャパシティプランニング」「開発用スペアの用意」といったあたりが自動化されているようです。

当面、MySQLのようなデータソースの扱いは鍵となりますが、MySQL Pool Scannerのようなものを構築管理することな並大抵のことではなく、人員を含め、相当にかっちりとした運用体制が必要となりそうです。

2014年はPercona Toolkitを核に、各種オペレーションをサポートするツールがいろいろ出てくることになるだろうと思います。

安定的なDBクラスタ運用を行うためのDBAの悩みはまだまだ続きますね。

2014年のモニタリング

最後に2014年のモニタリングについて考えます。モニタリングについても、Stateless ServerとStateful Serverで考え方を多少変えることが必要となりそうです。

Stateless Serverのモニタリング

Stateless Serverのモニタリングは、Auto-scaling機能、つまりホストの増減とそれに対応したロードバランサーとの協調動作が重要になります。各ホストのCPU usage, load average, memory usage, network loadなどを監視し、それをトリガーとして、ホスト増減を行い、合わせてロードバランサーとの協調動作を行う必要があります。また、ホストがどんどん新しくなるので、負荷観測の連続性をどのように確保するか、などメトリクス情報の保存や可視化に関する課題もあります。

アプリケーションサーバーのデプロイを管理するために、Dockerイメージ(やAMI、gitのハッシュ値)のバージョン管理や、CIによるテストの統合があるとより便利となるでしょう。ただし、このあたりは先のクラスタ管理システムと機能的に重複しますので、統合か棲み分けが必要となりそうです。

Stateful Serverのモニタリング

Stateful Serverについては、包括的な解が当面は存在しなさそうですので、従来通り、きっちりとモニタリングすることが重要となります。特にスケールアップ/アウトが必要なタイミングを察知することは重要です。

また、各種オペレーション用のツールセットとの連携ができるとより有効になるでしょう。例えば、ホスト障害が発生した際のレプリカ作成やバックアップからの復元を容易にしたり、サービスリリース前のキャパシティプランニングのサポートなどが求められます。

ここでの進化は、もうしばらく連続的なものとなりそうです。

システム全体でのリソース管理の重要性の高まり

またクラウド時代になり、リソース増減の柔軟性は上がっているため、システム全体でのリソース管理の重要性はますます増大するでしょう。例えば、負荷に対応したリソース消費増が容易となっているのですが、一度増強したシステムが改善されずに、その状態で放置されてしまう、というようなことが想定されます。また、EC2の例で言えば、適切なインスタンスタイプの選定、Reserved Instanceをタイムリーに調達することも、選択肢が増えている分、頭の痛い問題となりつつあります。

そのため、Stateless Server、Stateful Serverの両方について、リソース管理を適切に行ない、リソースが必要十分な状態を保持しつつ、投入したリソースが効率的に消費されていることを管理することが重要となります。アプリケーションについてスケールアウトで満足するのではなく、リソース単位あたりのパフォーマンスも重視されるようになると考えています。これまでアプリケーションをリソース単位あたりのパフォーマンスを管理することはそれほど重視されてきませんでしたが、2014年には徐々に重視されるようになるでしょう。

まとめ

長々と書いてきましたが、ここ数年のインフラ・クラウド周りの進化が2014年にはだいぶ形になるだろうな、と予感しています。ざっとまとめると以下のような予想を立てています。

  • アプリケーションサーバーなどの状態をもたないホストは使い捨て可能なImmutableなものになり、開発プロセスにも組込まれていく
  • データベースサーバーなど状態を持つホストは、まだまだ従来からの連続的な進化が続く
  • クラウドでリソースを柔軟に使えるようになったが、リソースを効率的に使うための取り組みが注目されるようになる

さて、2014年も引き続き注目ですね!

The Benchmark with Go REST API Server

I gave a presentation about lightweight REST API Server by Go, and performance comparison with Go, Perl and Ruby at GoCon 2013 autumn.

The slide about benchmarking result is as follows. This shows milliseconds per request with 10,000 sequential requests at various conditions, which are go/perl/ruby, messagepack/json, and mysql SQL query/innodb memcached plugin.

"direct memcached (innodb)" is direct accesses with memcached protocol to mysql, using innodb memcached plugin. "direct mysql" is direct accesses with SQL query to mysql. The target server was invoked on AWS m1.large instance, and a benchmark tool was invoked on another m1.larget instance. detail conditions of this benchmark are shown in the above slides. Also I uploaded these server implementations and the benchmark tool to https://github.com/stanaka/go-rest-api-server .

Conclusion

  • Go + memcached plugin + messagepack = Fastest!!
    • except direct query and direct memcached (innodb)
  • Go shows good performance and small footprint.
  • mysql library of Go needs to be improvement.
  • innodb memcached plugin works well especially for read queries.

Feedback

If there is objection or vagueness at benchmark conditions, please let me know. There may be mistakes about treating mysql libraries of go and ruby, which causes significant performance reductions. I'll revise the results if it would be considerable.