Thursday, February 2, 2012

PACELCで理解するCAPの定理(2)

第一回目は、CAPの定理をおさらいしました。今回は、いよいよPACELCについて見ていきます。



CAP定理の問題

Abadi氏は、CAPの定理には次のような問題があると言います。

CA型とCP型のシステムは、事実上区別できない。つまり、CAP定理では、あたかもCA, CP, APの計3種のシステムが存在するような印象を受けるが、実際にはCA/CP型とAP型の2種類しかない。

まずはこれについて考えてみましょう。CA型のシステムとは、ConsistentかつAvailableなシステムですが、Partitioningが起きたら、機能を失ってしまうシステムです。CP型のシステムとは、Consistentで、Partitioningが起きても機能を失わないが、その代わりAvailableではないシステムです。

なんだか、確かに分かりにくいですね。よりCAP定理の定義に忠実に従って正確に書いてみましょう。
  1. CA型のシステムとは:
    • Partitioningが起きない限り(=普段は)、ConsistentかつAvailableである
    • Partitioningが起きると、システムは機能を失う

  2. CP型のシステムとは:
    • 普段はConsistentである
    • Availableとは、「ノードがfailureしていないかぎり応答を返せること」なので、実は、普段(=Partitioningが起きていない時)はCP型のシステムもAvailableである
    • Partitioningが起きると、Availableではなくなるが、Consistentであり続ける

まだ分かりにくいので、具体例で見ていきましょう。

  2つのノードで同期的にレプリケーションを行っているリレーショナルDBを考えましょう。どのWriteも、両方のノードのディスクに書き終わらない限り完了しないという設定で組んでいるとします。もし2つのノード間で通信が途絶えてしまったら、両方のディスクに書けないのでシステムは機能を失ってしまいます。これが、CA型のシステムですね。  これではシステム全体の可用性が少なすぎるとしましょう(どちらかのノードが壊れるか、通信が途絶えるかするだけでシステムが停止するので)。そこで、「通信が途絶えたら、IPの若い(順番が)方が自分のディスクだけをつかってオペレーションを継続する」という約束をすることにしましょう。こうすれば、通信が途絶えてもIPの若いほうが生きてさえいればオペレーションを続けることができます。
  IPが古い方のノードは「failしていないのに応答できない(正確には『リクエストを実行できない』というエラー応答となるわけですが)」ことになり、「failしていないノードはリクエストに応答しなくてはならない」というAvailabilityの条件を満たさなくなります。
  もし、どうしてもAvailabilityを保持したかったとしたらどうでしょうか?その時は、レプリケーションを非同期にする必要があります。お互いのDBが、発生した変更をキューに貯めておいて、通信が復活したら相手に伝達します。  その間は、お互いDBの中身が違うので、Consistencyは守られません。
  つまり、事実上、CA型のシステムとCP型のシステムがあるわけではなく、Pが起きたときにCを選ぶか、Aを選ぶかという選択があるのです。
  ここまでが、「CA型とCP型のシステムは、事実上区別できない」とするAbadi氏の主張の説明です。Abadi氏はこの論理から、PACELCの"PAC"を提唱しています。「もしPが起きたら、AとCどちらを選びますか?」という意味です。  次に、残りの"ELC"について見てみましょう。先に説明しますと、ELCとは else Latency xor Consistencyです。PACから書くとこうなります。
if P then Availability xor Consistency else Latency xor Consistency
日本語で書くとこうなりますね。
もしネットワーク分断が起きたら、Availabilityを選びますか?それともConsistencyを選びますか? あと、ネットワーク分断が起きていない時は、Latencyを選びますか?それともConsistencyを選びますか?
Latencyという要素が急に入ってきましたが、これはなんでしょうか?これが、Abadi氏が主張するCAPの定理の2つ目の問題です:
CAPの定理は、LatencyとConsistencyのトレードオフを考慮していない。
PACだけに注目すると、じゃぁPが発生していないときはAvailabilityとConsistencyどっちも取れてハッピーハッピーになるはずなのですが、世のNoSQLデータベースは普段からConsistencyを犠牲にしています。
  どうしてそんなことをするかというと、Latency(≒レスポンスタイム)を短くする為です。例えば、負荷分散のために10台のリレーショナルDBをレプリケーションして使いたいとしましょう(みんな同じ中身)。Consistencyを達成するためには、Create/Update/Deleteを行う時は10台全てにリクエストを発行して、完了するまで待たなければいけませんが、そんなことをしたらLatencyはかなり悪くなってしまいます。2台選んでリクエストを完了し、後からこの2台が他のノードにリクエストを非同期で発行するのはどうでしょうか?これなら運悪く1台が死んでももう1台がいますから1台にだけ発行するのに比べると信頼性がアップしますし、10ノードに発行するのに比べれば、Latencyが改善します。Cassandraなどは、実際にこれに似たようなことをやっています。
  話が少し横にずれてしまいましたが、要するに、LatencyとConsistencyはトレードオフの関係にあり、システムはどちらかを選ぶ必要があるということなのです(実際にはイチゼロじゃなくて、どちらをより優先するか連続的なスペクトルから選ぶ感じですが)。
  では、いくつか実例を見てまとめとしましょう。PCECシステム(if Partition then Consistency, else Consistency)はどんなシステムでしょうか?何回か例に出てきた、2つのノードが同期的にレプリケーションを行っているリレーショナルDBなどが考えられます。このシステムは、ネットワーク分断が発生すると、生きていてもリクエストを処理できないノードができてしまいます(if P then Availability喪失)。普段も、2ノードでWriteが完了しないとリクエストが完了しないので、Latencyも悪いです(elseの時、 Latency無し)。その代わり、普段はConsistencyが守られていますし( else Consistency)、Pが起きてもConsistencyを守り続けます。つまり、if P then Consistency (and not Availability), else Consistency (and not Latency)、よってPCECです。
  PAELシステムはどうでしょうか?これも前出てきたDNSが当てはまります。普段はそのDNSサーバのテーブルがアップデートされてさえいれば、他のDNSサーバがアップデートされているかなど考えずに応答を返すので、Latencyはいいです(else Latency)。DNSサーバ間で通信が途絶えて、同期が行えなくなっても各自応答は返し続けるので、if P then Availabilityとなっています。その代わり、要求を処理するDNSサーバによって結果が変わることがありえるので、Consistencyは失われています。
  他の組み合わせはどうでしょうか?Abadi氏は、PCELなシステムの例としてYahoo!のPNUTSを挙げています。PNUTSは、普段Latencyを得るため伝統的なリレーショナルDBなどに比べて弱いConsistencyを使っていますが、Pが発生すると、Availabilityを犠牲にしてでも、そのレベルのConsistencyを守り続けます。(Consistencyといっても様々なレベルがあるので、ここは分かりにくいですね。。)


  PAECシステムだと、普段はConsistencyを維持していますが、Pが起きるとAvailabilityを守るためにConsistencyを犠牲にし始めます。たまにConsistencyが破られる可能性があるというのは、Consistencyがないのに近いので、PAECなシステムが本当にあったとしたら、非常に使いにくそうですが、後からある程度のコストでコンフリクトを解消できるような局面では、あり得ない選択ではないかもしれません。


以上、PACELCで理解するCAPの定理でした!

PACELCで理解するCAPの定理(1)

CAPの定理が何故最近話題になっているかについての説明などは他サイトに任せることにして、このエントリではCAP定理の技術的な解説、および、CAP定理をより分かりやすく、かつ(簡単に言えば)より正確にした「PACELC定理」の解説を行います。

PACELCの定理とは、エール大学のAbadi氏が提唱しているもので、CAPの定理のいわば発展形です。CAPの定理の「難しい版」と思われていることがあるようですが、そんな事はありません。むしろ、多くの学生がCAPの定理で苦労するのを見たAbadi氏が、学生に分かりやすく説明するために考えたものなので、CAPの定理をより分かりやすくしたものと言えます。ただ、それだけでなく、CAPの定理には入っていなかったLatency(≒レスポンス時間)の概念も合わせて捉えることで、より正確に分散データベースの特性を考えられるようになっています。

ではまず、第一回目はCAPの定理をおさらいしましょう。


CAPの定理:次の3つの特性を、全て同時に示す分散システムを実現することはできない。

  1. Consistency(一貫性, C)
  2. Availability(可用性, A)
  3. Partition-tolerance(分断耐性, P)

すなわち、どのような方法をもってしても、ある時点でシステムが示すことができる特性は、C, A, Pのうち任意の2つまでである。


Consistencyとは

ここでは広義に使われており、ACIDのCと同義ではありません。説明をわかりやすくするため、ここでは単純な分散Hash mapを具体例として見ていきましょう。

最も単純なConsistencyには、AtomicityとVisibilityがあります。Atomicityのうち、最も単純なのは、「全てのReadは、Write処理が完了する前の状態か、または完了した後の状態のいずれかしか見ることがない」という性質です。プログラミングで例えるなら、map.get(key)を呼んだら、値が返ってくるか返ってこないかの2択しかしかなく、「値が半分だけ」返ってくることが絶対にないということです。「半分だけ」値が返ってくるってどういうことよと言われてしまいそうですが、この例では例えば正しくメモリ上に書き込みが終わっていない値が返ってくることが想定できます。イメージとしては、本当は10100010が返されなければいけないのに、まだ書き込みが終わっていないために00000010が返ってしまう感じです。この単純なAtomicityが実現されているということは、これが起こることがないという保証があるということです。※一般的にアトミックと言うとリレーショナルDBでいうAtomicityを考えると思いますが、今回の説明ではこの最低限のAtomicityで十分なので、単純化しています。



Visibilityとは、全てのユーザ(例えばスレッド)が同じ状態を「見る」ことができることです。もう少し具体的に言うと、あるWriteが完了したなら、その後に発行されたReadは全て「最悪でも」このWriteの結果を返すという約束です。当たり前に聞こえますが、後述するように、パフォーマンスなどを考えて、「Writeが起こった直後は書いた人にしか見えないが、じわじわと他の人にも見えていくようにする」ことを許す場合があります。これがよく分散データベース("NoSQL")で言われる"Eventual Consistency"の一種です。すぐみんなが同じ状態を見れはしないけど、いずれは見ることができるようになる、という意味で"Eventual"なのですね。意図せずにこれを許してしまうのがVisibilityバグで、マルチスレッドプログラミングでよく起こるバグの一つです。

ところで「最悪でも」ってなんやねんという話なのですが、これは、Write1→Read1→Write2の順にオペレーションが発行されたときに、Read1がWrite2の結果を見るのはOKということです。別にWrite2の結果が見えたほうがいいということではないので「最悪でも」という言い方は誤解を招くかもしれませんが、「少なくともWrite1までのアップデートを逃すことだけはNGにしましょうね」ということです。「Read1が、Write2ではなく、必ずWrite1の結果を受け取らなければいけない」というのはもう一つさらにきついレベルのConsistencyです。ここでは最低限のConsistencyについて考えたいので、よりゆるい、Write2の結果が返ってしまうことを許すvisibilityを考えます。



「Writeの結果がすぐに全員に見える」のと、「ちょっと後に全員に見えるようになる」のと何か本質的な違いはあるのでしょうか?これについて考えるために、「同じ値(value)を許さない」Hash mapベースのアプリを考えてみましょう。どのスレッドも、一旦挿入したい(kx,vx)を挿入してしまってから(map.put(kx, vx))、map.values (v0 ... vx ... vn)を1つ1つイテレートしてvxと比べ、vx以外にvxと同じvyを発見したら、重複の疑いがあるケースとしてマークし、後で調査して削除するためにどこか(delete_list)に書き残します(次のinsert関数参照)。

これをたくさんの(k,v)ペアに対して行い、最終的にユニーク、つまりどの値(value)も1回しか入っていないマップを得ることがアプリの目的です。

def insert(kx, vx):
    map.put(kx, vx)
    for ky, vy in map.values():
        if vx == vy and ky != kx:
            delete_list.add((kx,ky))



さて、今まさに2つのスレッド(t1, t2)がそれぞれ(k1, v1), (k2, v1)を登録しようとしているとしましょう。同じv1なので、少なくとも1回重複疑いのアラートがあげられなければいけません(2回以上あがってしまうのはOK)。

このHash mapは最低限のAtomicityしか備えていない設定ですので、put, removeはそれぞれアトミックですが、insert自体はアトミックではありません(これは、insert処理の途中の状態を、他のスレッドに見られたり、書き換えられたりする可能性がある、ということ)。なので、考えられる処理の順番としては、次の3つが考えられます(t1とt2を入れ替えたものは同じと考える。t1、t2それぞれの中ではput→readの順番は保たれる)。

    1. t1のput(k1,v1)
    2. t1のread(他のv1無し)
    3. t2のput(k2,v1)
    4. t2のread(他のv1有り)
    1. t1のput(k1,v1)
    2. t2のput(k2,v1)
    3. t1のread(他のv1有り)
    4. t2のread(他のv1有り)
    1. t1のput(k1,v1)
    2. t2のput(k2,v1)
    3. t2のread(他のv1有り)
    4. t1のread(他のv1有り)

これが、「すぐに結果が全員に見える」という保証がなかったらどうなるでしょうか?タイミングによってこういうことがあり得てしまいます。

    1. t1のput(k1,v1)
    2. t1のread(他のv1無し)
    3. t2のput(k2,v1)
    4. t2のread(他のv1無し(まだ見えなかった))
    1. t1のput(k1,v1)
    2. t2のput(k2,v1)
    3. t1のread(他のv1無し(まだ見えなかった))
    4. t2のread(他のv1無し(まだ見えなかった))
    1. t1のput(k1,v1)
    2. t2のput(k2,v1)
    3. t2のread(他のv1無し(まだ見えなかった))
    4. t1のread(他のv1無し(まだ見えなかった))

正確には、先述のvisibilityの仮定から、ReadがWriteの結果を「先取り」してしまうことはあり得る。「アラートがあがらない保証がある」ではなく、あくまで「アラートが必ずあがる保証がない」ということに注意


これで、visibilityがあるのとないのとでは本質な違いがあることが分かっていただけたかと思います。この違いは性能面でも顕著に現れます。visibilityを担保しなくてはいけない処理系は、visibilityを担保しなくても良い処理系に比べて性能が低くなります。CAPの定理を説明する上では、とりあえずこのようなVisibility(と最低限のatomicity)を備えたものを「Cのある分散DB」、備えていないものを「Cのない分散DB」と考えておけば良いです。

Availabilityとは

Availabilityとは、「failしていないノードに発行した(発行できた)リクエストは、必ずレスポンスを返さなければならない」ということです。リクエストが発行できたなら、必ず結果が返ってこなければいけないということですね。

Partition Toleranceとは

Partition Toleranceとは、分散システムにおいて、ノード間で通信ができなくなってもAvailabilityまたはConsistency(のどちらか1個)が保持されることです。「通信分断耐性」とでも訳せるでしょうか。分散システムなので当然複数のノード(サーバ)があるわけですが、これらノード間で通信ができなくなっても、システムが機能を維持できる特性のことです。機能といってもAvailabilityを保証するシステムもあれば、Consistencyを保証するシステムもあるので、「Pを備える」という言葉は、システムによって違う意味を持ちます。Availabilityを保証するシステムでは、ネットワークの分断が起きてもAvailabilityが保証され続けることを意味し、Consistencyを保証するシステムでは、ネットワークの分断が起きてもConsistencyが保証され続けることを意味します。

※正確な定義、CAPの定理の証明についてはLynch & Gilbertの論文を参照

具体例

ちょっと分かりにくくなってきたかもしれないので、具体例で説明しましょう。例えば、DNSは典型的なAP型システムです。DNSでは、DNSサーバ1に問い合わせると「見つからない」というレスポンスが返ってくるが、DNSサーバ2に問い合わせるとちゃんとIPが返ってくる、ということが日頃起きています。そのうちどちらのサーバも最新に更新されていくわけですが、ラグがあったりして、少なくともある時点に着目したときに、問い合わせるサーバによって結果が異なることがあり得る、つまり、「全員が同じ状態を見るという保証がない」ため、Consistencyが破られていることになります。

さて、ある日ルータの故障か何かでDNSサーバ1と2の間の通信が不能になったとします(Partitioningの発生)。DNSでいうPartition Toleranceとは、この状況でAvailabilityを保証し続けること、すなわち、DNSサーバ1へのリクエストも、DNSサーバ2へのリクエストも、必ずレスポンスが返ることを保証することです。DNSサーバ1,2の間で通信ができなくなったところで、更新が遅れるだけで、引き続きどちらのサーバに対してもRead/Writeは実行できるため、Availabilityは達成されていることになります。もし、通信ができないからと言って問い合わせやレコードの追加を拒否する状態になればPartition Toleranceが満たされていないことになります。


逆にCP型のシステムにはどんなものがあるでしょうか?最も分かりやすいのは、2つのノードで同期的にレプリケーションを行っているリレーショナルDBです。どのWriteも、両方のノードのディスクに書き終わらない限り完了しないという設定で組んでいるとしましょう。もし2つのノード間で通信が途絶えてしまったら、両方のディスクに書けないのでシステムは機能を失ってしまいます。それでは不便なので、「通信が途絶えたら、IPの若い(順番が)方が自分のディスクだけをつかってオペレーションを継続する」という約束をすれば、通信が途絶えてもIPの若いほうが生きてさえいればオペレーションを続けることができます。しかし、IPが古い方のノードは「failしていないのに応答できない(正確には『リクエストを実行できない』というエラー応答となるわけですが)」ことになり、「failしていないノードはリクエストに応答しなくてはならない」というAvailabilityの条件を満たさなくなります。もし両方ともオペレーションを続けたら、Consistencyを保てなくなる点に注意してください。例えば、ノード1にWriteした結果が、ノード2からは見えないわけですので、こういう約束をしていなければシステムを止めなければいけなくなります。

ノードが1つだけオペレーションを続けたときは、当然従来通りConsistencyが保たれます。

CAPの定理に従えば、残るはAC型のシステムですが、これがCAP定理を理解しにくくしている原因の1つであるとAbadi氏は主張します。AC型のシステムとは、Partitioningが起きない限りはAvailableかつConsistentなシステムですが、CP型のシステムだって、Partitioningが起きない限りはAvailableなわけです。逆に、AC型のシステムだって、Partitioningが起きてしまったら結局Availabilityを失います。つまり、AC型のシステムと、CP型のシステムは、事実上同一なのです。CAPの定理では「3つのシステム」が作れると説明しますので、AC型のシステムとCP型のシステムは別物と考える人が多く、混乱を招いていると氏は主張します。


と、とりあえず今日はここまでとして、次回はこれを踏まえてAbadi氏が提唱するPACELCについて解説していきたいと思います。

Erlang、求人数の伸びしっかり

近年脚光を浴びているとはいえ、まだまだ超マイナー言語状態のErlangですが、求人の伸び率では、python, PHPなどの最近伸びが大きいWeb系言語を抑えて高い伸びを示しています(以下グラフ)。Web系言語の中でもさらに新興のruby, groovyと並ぶ伸びです

絶対数で見ると圧倒的に少ないので、その影響も多いのかもしれませんが、注目が集まっているのは間違いなさそうです。


フロントエンドでは、まだまだJavaが幅を効かせているものの、Python, Ruby, Groovyなどの動的スクリプト言語が好まれるようになってきています。そうなると、コンパイル言語であるJavaの牙城は、パフォーマンスが要求されるバックエンドとなりますが、Shared Mutable DataをコンカレンシモデルとするJavaでは、マルチスレッドプログラミングの難易度が高く、手がけることのできるプログラマは非常に少ないです。複数のサーバにまたがってアプリを置く場合にも、普通はそれを意識してプログラミングする必要が出てきます。

そこへ行くと、Erlangはコンカレンシのための言語、分散システムのための言語ですから、非常に魅力が出てきますが、関数型言語であるため、Java、C++などの手続き型言語のキャリアがほとんどである産業プログラマにはとっつきにくい言語といえます。複雑な計算や、文字処理などにも向いていない部分があり、様々な言語とミックスして使うのが前提という設計とはいえ、JavaやPythonに比較したときの既存ライブラリの少なさなんかもネックになってしまいそうです。

並行プログラミング・分散システムでの強みがErlangを押し上げるか?それともニッチ言語として特殊な層でのみ普及するか?あるいははたまたとっつきにくさが障害となって、マイナー言語のまま終わってしまうのか?どうなるかこれから注目です。

Erlang開発環境の構築(Erlide) 2011

環境:Windows XP

1. Erlangをインストール(Erlang/OTP 5.7.4 (R13B03)) link
EDIT:R13B03のウィンドウズ版デバッガにはバグがあるようで、VIstaで起動すると落ちてしまいます。なのでR14B01にアップデートしたところ、正常に使えています。

2. erl5.7.4\binをPATHに追加。

3.C++用 eclipseをダウンロード (eclipse-cpp-helios-SR1-win32) link
EDIT:SR1じゃなくてSR2でも正常に動くようです。

4.1.1 Help -> Eclipse Marketplace -> "erlide"を検索窓に入力して、"Go"
4.1.2 2011年2月現在、Erlide 0.9.0.201010010061109がインストールされ、正常に動きます。
4.2 指示に従い、インストール。インストール後再起動。
4.3.1 Eclipse preferencesを開き、Installed Runtimes entryを選択。僕の場合は正常に自動検出できていましたが、できていない場合は多分手動でErlangランタイムを追加する必要があります。
4.3.2 手動でランタイムを追加した場合は、eclipseを再起動。

5 プロジェクトViewで右クリックして、"New Erlang Project”を選択(プロジェクト名は、helloなど)。

6 作成された"src"ディレクトリにhello.erlを次の内容で作成



7.1 Run configurationでErlang applicationを選択し、新規起動コンフィグレーションを作成(左上の「白紙」みたいな形をしているアイコン)
7.1 アプリの名前を入力。(Hello-Concurrent-Worldなど)
7.2 Erlangタブで、Requiredプロジェクトとしてhelloにチェック。
7.3 ランタイムタブで、nodeネームロングを選択して、ノード名として"erlide"と入力。
7.4 適用をクリックして、実行。

8 コンソールビューが表示され、プロンプトが表示されるので、試しにhello:hello().を実行。

これ以降は、ソースをいじって保存(ctrl+s)すれば、自動的にコンパイル・反映され、コンソールから新しいコードをすぐに呼び出せます(改めてコンパイルしたり、コンソールを立ち上げたりすることは不要)。


UPDATE:
Erlide付属のErlangコンソールはやや使いにくいうえに、ソースを変更しても反映されないことがたまにあるみたいなので、今はソースディレクトリでコマンドプロンプトからwerl(Windows版Erlang付属シェル)を別ウィンドウで動かして使っています。そんなにきれいじゃないしいちいちalt+tabでの切り替えが必要になってしまいますですが、tabキーでオートコンプリートできたり、コピーペーストが可能などerlide付属シェルよりも使いやすい感じです(コピペ不可と言うのは厳しいですよね)。


reference

科学的に「流行」を予測し、予防する方法(TED)

僕はTEDが大好きで、podcastをipodに入れていつも移動中に見ているのですが、最近聞いた中で特にへぇ~とおもったのがあったので、紹介します。

講演はこちら->Nicholas Christakis: How social networks predict epidemics



病気や流行、考え方などは、人から人へとつたって集団内に分散していきます。最近では、エジプトでのデモがありましたね。集団内のそれぞれの人は、思い思いに不満を持っていたはずですが、「デモをやろう」、「立ち上がろう」という「考え」が爆発的に広がることがなければ、人々が協調してデモに向かう現象はおこらなかったはずです。エジプトでは、FacebookやTwitterなどのいわゆるsocial netoworkサービスが、重要な媒体となったといわれていますね。



演者のクリスタキス氏はこのような、集団内を、人を介してモノが伝わる現象を研究しています。特に講演では、ある大学のキャンパスでの風邪ウィルス感染の「流行」を従来よりも早く検出した実証実験を紹介しています。ここでは、FacebookやTwitterと違って、人と人とのつながりは物理的ですし、伝わるのは「病原菌」なのですが、対象とする事象が「人を介して伝わっていくもの」であるかぎり、応用が可能なのだそうです。



氏の研究のミソは、「人と人のネットワークにおける「要所」をみつけて、そこでアンテナを立てる」ことです。お互いに情報をやり取りするノード(節、この場合は個人)がつながったネットワークでは、「ネットワークの端」よりも「ネットワークの中心」にいた方が情報が早くもたらされます。



「ネットワークの中心」にいるノードは、要するに「友達がたくさんいる人と友達であるノード」です。どれだけ友達が多くても、その友達がすべて友達の少ない人であれば、そのノードは「端」になります。逆に、友達が普通の数でも、その友達の人たちが、たくさん友達のいる人ばかりであれば、そのノードは「中心」に位置します。



これは、数学的に定量化することができ、こうして求めた「中心に近い」ノードを重点的にモニターしておけば、集団で何か情報なり行動が流行し始めとき、いち早くそれを知ることができます。氏は、「中心に近い」学生を幾人か選んで、彼らに定期的に健康状態を電話で報告してもらうなどしてモニタリングし、風邪の流行をいち早く知ることができることを確認しました。





なんとこの方法は、検出だけでなく、流行の予防にも応用できるそうです。例えば、集団全体の30%にあたる「中心に近い」ノードに予防接種を実施すると、ランダムに集団全体の96%に予防接種を実施するのと同等の予防効果が得られるらしいことがわかりました。



この方法の難しいところは、「中心に近い」ノードを見つけるには、ネットワークの「地図作り」が必要となり、これが非常に大変で難しいところなのですが、クリスタキス氏はこの問題を克服する面白い方法を見つけました。



ランダムに集団内のノードを選び、それぞれのノードに友達を紹介してもらうと、その「友達」集団は、元のランダムに選んだ集団よりも、ネットワークの中心に近い集団となります。これは、ネットワークの中心に近いノードはたくさんのノードからコネクションがきているので、ランダムに紹介してもらうと、中心に近い人の方が名前が挙がりやすいからです。



この方法を使うと、手間のかかるネットワークの「地図作り」をしなくても、流行を効果的に検出したり、予防したり、逆に流行を引き起こすことができるようになります。



クリスタキス氏はマラリア流行国での「蚊帳」の流行を作り出すためなどに使えると話していましたが、政治やビジネスの世界ですごく注目されそうな研究ですね。少し恐ろしい気もしますが、かしこく利用すれば本当に応用範囲の広い、強力な技術だと思います。




ErlideでEunitを使った開発をやってみる

前の記事で作成した開発環境で、テスト駆動開発を試しにやってみます。

といってもすごく単純です。とりあえず、Erlangをインストールしたディレクトリ下\erl5.7.4\lib\eunit-2.1.4\examplesにあるfib.erl をHelloWorldプロジェクトのsrcディレクトリにコピーして、試しにfib:test().を実行してみると、テストが実行されパスします。

自分で書いたソースでも試してみます:


ちょっと単体テストが中途半端ですが(^^;) db:test().を実行するとテストが流れます。とりあえずこれでテスト駆動でErlangを練習していく環境が整いました。

Stackoverflowが教えて!gooよりも何倍もクールな理由

集まるエンジニアのレベルに絶対的な差がある、とりあえずstackoverflowの方がインターフェースがかっこいいなど目に付く明らかな差は当然のことながら、普段はあまり見えないところにも大きな差があります。



※IANAL(I am not a lawyer/僕は弁護士ではないので、間違っていたらすみません)

とりあえず、著作権。StackoverflowのコンテンツはCreative Commons BY-SAです。サイト創始者の一人の考え方としては、著作権は引き続きユーザにあるが、それをstackoverflowに「CC BY-SAとしてライセンスしている」ということらしいです(その割には、Stackoverflowのコンテンツはstackoverflow由来であることを表示することを求めているので、著作権がユーザだけに帰属するかどうかは曖昧ですが)。



CC BY-SAは、オリジナルの著作権者を表示して、著作物をCC BY-SAでライセンスする限りは、商用利用も改変も構わないというライセンスです(商用利用の場合、売ってもいいけど、売った著作物を誰かにCC BY-SAで再配布(もしくは再販売!)されても文句は言えないということ)。



まぁ非常にフェアなライセンスと言えるのではないかと思います。そのおかげでstackoverflowのコンテンツはwebのあちらこちらに転載されており、中にはサイトを丸ごとコピーしているようなサイトもありますが、オープンソースなどへの意識が高いプログラマコミュニティにとっては、こういうライセンスのほうが、愛着というか、コミュニティへの帰属意識が出ますよね。非常にかしこい選択だったのではないかと思います。





一方でこちらは教えて! gooの著作権規定
要約すると、「著作権はgoo側に帰属し、よってgoo側が例えばその内容を使って本を創って設けてもユーザに支払いなどは必要ないばかりか、名前の表示(attribution)なども一切必要ない」という内容です。




��.投稿テキストの著作権等の帰属については以下の各号に定めるとおりとします。
��1)日本国著作権法第18条から第20条までにおいて定義される権利については、会員は、自らまたは第三者をして、当社、オウケイウェイヴ及び当社またはオウケイウェイヴの指定する第三者に対して行使せず、またはさせないものとします。
��2)日本国著作権法21条から第28条までにおいて定義される権利については、会員または第三者から譲渡され当社及びオウケイウェイヴに帰属します。
��3)第1号および第2号の対価として、当社及びオウケイウェイヴは、会員に対し、何らの支払も要しないものとします。



テキスト以外のマルチメディアコンテンツに関する規定は別にあり、こちらは基本的にはgoo側が欲しい権利をもらい、何か問題が発生したらユーザ側の責任となります(多分この点を考慮して、著作権はテキストと違ってユーザに帰属し、gooに無償ライセンスを付与する形にされています)。



これじゃぁあんまり頑張ろうって気にならないですよね。まぁ誰もこんなもの読まないのでいいのかもしれませんが。こういうところ、未来のcollaborationの形に乗り遅れてるんじゃないのって思ってしまいます。



ところで、seesaa blogはどうなっているかというと、こちらが規約および規約付属の説明です。



要約すると、規約によれば著作権はユーザに帰属し、第三者に対する著作権の行使はなんら制限しないが、seesaaにはどう使ってもいい権利を付与してもらうという形態のようです。その理由については規約付属の説明に少しのっています。gooとは違って、seesaaが他の第三者に利用権を付与するようなことはできないみたいですね。



この説明にはさらに、
弊社がユーザー様の著作物を弊社のサービス以外の目的で利用する場合、ユーザー様の許諾を頂く必要があります。
とありますが、「弊社のサービス」という言い方はかなりくくりが大きいので、本などの出版がこれに含まれるのかどうかはよくわかりませんね(本ってサービスなのかなぁ?)。



弊ブログのコンテンツは、テキストはCC BY-NC-SA、ソースコードはApache 2.0ライセンスで公開しています(Apache 2.0は商用可能です)。弊ブログの場合、第三者がもし弊ブログのテキストコンテンツをつかって本を創って売ったら文句が言えますが、seesaaにそれをされた場合は文句は言えないかもしれない、ということのようです。



ちなみに実はブログサービスには商用利用可のものと不可のものがあり、gooブログは商用不可、seesaaはOKです。ここもseesaaを選んだ理由の一つですね。gooはやっぱりNTTなので(?)色々なリスクを恐れて消極的というか、保守的な規約にしているのだと思うのですが、最近でた本、Freeにも書いてあったように、これからは企業がcommunityとうまくcollaborationしていくことが一層重要になってくるように思います。(gooの名誉のために書いておくと、商用利用不可なのはなにもgooだけじゃないですし、gooもblogについては、著作権はユーザに帰属するとしています)



ユーザとしても、頑張ってユーザ・コミュニティの利益・権利を守ろうとしてくれている企業を応援したいですね。








原発事故を予言していた広瀬さんの最新記事

記事


うーん、これを読むと、「事故」というよりは「必然」だったのか。。。

著者は大学時代応用科学を学んだ広瀬さんで、なるほど説得力があります。



水素ガスの爆発限界は、最小値が4.2%であるから、この濃度になれば爆発する。
というのは「おや?」と思いましたが、「爆発し得る」という意味か。



一番恐ろしい記述は、
4号機では建屋内の使用済み核燃料のプールが沸騰を始めたという。ここには、原子炉より多くの放射性物質が入っている。作業者が近づけない場所であるから処理はおそらく不能であろうと、15日の午後5時時点で、私は推測するが、この推測が間違ってくれるよう祈っている。福島第一原発の6基のうち、1基がメルトダウンすれば、そこには職員がいられなくなる。すべてを放棄して逃げ出すだろう。あとは連鎖的に事故が起こる。




たしかにヘリで冷却水を投下するとか検討されてたなぁ。。今は消防車で放水してるみたいですが、まともに近づけないというのはチェルノブイリを連想させます。



敦賀原発・美浜原発も福島と同じく高経年原発だそうで、広瀬さんの指摘が事実ならば、廃炉にすべきなのかも。他に高経年原発がどれくらいあるのか分かりませんが、比較的原発依存度の高い日本は難しい選択を迫られそう。



化石燃料の値段が上がっているなか、日本の経済は弱体化していますからね。日本国内の国債消化力が低下して金利が上がり始め、円安という流れになれば、円建の化石燃料価格はさらに上がり、非常に苦しいことになるかもしれません。かといって原発に依存する道をさらに進んでいっていいものか。。。



技術的なブレイクスルーが起きてクリーンな代替エネルギーが出てきてくれればいいのですが。。



うーん、日本の未来はどうなるのか。。




Tail recursionとNon-tail recursion

Erlangには、C言語やJavaなどの手続き型言語でおなじみのループがありません(!)。その代わりに再帰で問題を解いていかなければいけないのですが、手続き型言語しかやったことがないとむずかしいですね。。



まぁしょうもない問題もパズルみたいで、ある意味面白いのですが。今日は、Erlangプログラミングで最も重要な概念とも言えそうな再帰について勉強していきます。



style="color:#653200;">※この投稿はstackoverflow.comからのマテリアルを使用しており、よってライセンスはいつものhref="http://creativecommons.org/licenses/by-nc-sa/3.0/"
target="_blank">CC BY-NC-SA 3.0ではなくhref="http://creativecommons.org/licenses/by-sa/2.5/"
target="_blank">CC BY-SA 2.5です。






Tail recursionとNon-tail recursionの違いは、ざっくり言うと、



1) Non-Tail recursion:

次の関数呼び出しをした後も、元のスタックフレームが情報を保持していなければならないもの。

2) Tail recursion:

次の関数呼び出しを行ったら、元のスタックフレームが必要なくなるもの。



取りあえず今のところ、例えばJavaではTail recursionだからといって元のスタックフレームを捨てる最適化(tail call
optimization)を行えず、折角必要なくなっているのにスタックフレームを捨てないので、そういう言語ではそれほど重要な違いではないのですが、Tail call
optimizationを行うErlangでは、Tail recursionはconstant memory space (=メモリの使用量のオーダがO(1))で実行できるのに対し、Non-tail
recursionはできないという根本的な違いが出てきます。



Java出身の人間にわかりやすい言い方をすると、Non-tail
recursionではスタックオーバーフローによっていずれプロセスがお亡くなりになってしまいますが、Erlangでは、Tail
recursionだと、無限ループが可能になります。Javaであれば、Tail
recursionであろうがやはりスタックオーバーフローに陥りますが、これは、上で述べたとおり、JVMがErlangと違ってtail call
optimizationを行わないからです(詳しくはhref="http://stackoverflow.com/questions/105834/does-the-jvm-prevent-tail-call-optimizations"
target="_blank">こちら)。



Erlangでは、たくさんのプロセスがあたかもモノというか、会社の部署のようにコミュニケーションしながら働きます。一つ一つのプロセス(アクター)は、それぞれ独立していて、お互いいわばメールでしか干渉せず、基本的には部署ごとで働いているイメージです。このようなプログラミングモデルをアクターモデルというのですが、このアクターを作るとき、実はこのtail recursionによる無限ループを使うのです。なので、これをマスターしないと、Erlangの一番のミソが使えないということになってしまいます。



さて、例をあげて、tail recursionとNon-tail recursionの違いをより直感的に見ていきますhref="http://stackoverflow.com/questions/33923/what-is-tail-recursion"
target="_blank">USCのLorin氏の解説をもとにしています)




あるNを与えられたら、1からNまでを足し合わせる関数を考えます。

sum(5) = 1 + 2 + 3 + 4 + 5 = 15




Non-tail recursionでは、このように書けます。





recsum(5)をコールした場合、計算は次のように実施されます:


recsum(5)

5+recsum(4)

5+(4+recsum(3))

5+(4+(3+recsum(2)))

5+(4+(3+(2+recsum(1))))

5+(4+(3+(2+1)))

15





一番上のスタックフレームは、まだ 5 + recsum(x-1) の「5 + ?」の計算をしないといけないので、スタックフレームにあるものを一旦保存しなくてはいけませんね。



それに対して、tail recursionでは次のように書けます:



※("def tailrecsum(x,running_total=0)" はpythonの書き方で、変数名=数値として関数を定義しておくと、tailrecsum(x)と書くと自動的にtailrecsum(x,0)を呼び出してくれます(デフォルト引数と言います)。




先程は計算の手順なんかを保存して置かなければいけませんでしたが、今回は"小計"を変数として渡していくので、その必要がなくなります。



計算はこのように進んでいきます。





tailrecsum(5,0)

tailrecsum(4,5)

tailrecsum(3,9)

tailrecsum(2,12)

tailrecsum(1,14)

tailrecsum(0,15)

15





計算の手順がたまっていくのではなく、値がアップデートされながらバトンタッチされていくというこころが、tail recursionのミソです。





では、Erlangで書いてみましょう。



なんとなくNon-tail recursionの方がスマートですね。こう考える人は多いみたいで、「必要に迫られなければ、tail recursionは基本使わない」という人もいるようです。

昔はTail recursionの方がずっと早かったり、メモリ消費量がずっと小さかったりしていたらしいのですが、様々な最適化のおかげで、今は一概にどちらがよいとも言えなくなったそうです。

なので、「お好きな方で」やって、必要ならパフォーマンステストして比べなさいというのが最近のErlangのガイドラインのようです。


参考:http://stackoverflow.com/questions/33923/what-is-tail-recursion




Python/Ruby, Java, Erlangの違いと、ファンクションプログラミング

Dynamic Typingで、関数がオブジェクトとして扱われるErlangは、PythonやRubyに似ているところもあります。一方でJavaはStatic Typingで、関数はオブジェクトとして扱われないので、そこは仲間外れと言えます。

同じく関数がオブジェクトとして扱われるといっても、Python/RubyのファンクションプログラミングとErlangのファンクションプログラミングでは色々大きな違いがあるのですが、今日はPython/Ruby, Erlangがサポートしていて、Javaがサポートしていないファンクションプログラミングの1つ、"Higher order functions"について見ていこうと思います。



[1, 9, 3, 5, 8, 4, 2]というリストがあったとして、ここから3以上のものを取り除きたいとしたら、Javaであればこんな感じで書くことが多いと思います。




さらに一般化してやりたいなぁという場合は、次のようなこともできるでしょう。かなり長くなってしまいますが、「必要なもの以外取り除く」という汎用的なfilter関数を定義し、「何が必要で何が必要ではないか」を決めるためのPredicateインターフェースを定義し、最後に、使う際に適切なPredicateの実装クラスを渡しています。まぁ、Comparatorの考え方と一緒ですね。



一番初めのコードではlessThanという名前にせざるを得ず、せいぜい「どの数字より小さいものを残すか」しか「パラメータ化(外だし)」できなかったのですが、無名関数を利用することで、データ型、およびビジネスロジックを外だしすることができ、filter関数をもっと自由に再利用できるようになったりました。

これを使って、例えばこんなことができます。


よく見ると、Predicateクラスは単に関数を入れておくために存在していますね。つまり、これは、「関数がオブジェクトとして扱われない」Javaで、無理やり関数をオブジェクトとして扱う「裏技」です。なので、実はこの裏技を使えばJavaでもHigher order functionを使うことができます。

Erlang, Python, Rubyではそもそも関数自体を最初からオブジェクトとして使ってくれるので、同じことをする場合、クラスで「ラッピング」しなくても済みます。

では、同じことをErlangでやってみます。


fun(E) -> E < 3 endが、無名関数であり、それがオブジェクトとして、Funcに代入され、filter関数の引数として渡されています。

こちらはPython。




とりあえず、Python, Erlangの方が短いですね。まぁ、それはPythonとErlangがDynamic Typingで、JavaがStatic Typingだから、というところも大きいのですが。

Javaでもこういったファンクションプログラミングをしたいという人は多く、Google Guava, Functional Javaといった、Javaでのファンクションプログラミングをやりやすくしてくれるライブラリが人気になっています(特にGuavaは、もはやJavaプログラマ必須ではと言いたくなるほど秀逸)。



クラウドビジネス図鑑

ここ最近クラウドのお勉強をしてたので、今日はそのまとめをお送りしたいと思います。



筆者は、要するにクラウドとはXaaS (X As A Service)のことだと考えています(厳密にはきっと色々違いがあるのでしょうが。。)。なので、クラウドビジネスを俯瞰するために、現在注目されているXaaSを見ていきます(各XaaSの定義は信用できる文献を引いているわけではなく、筆者が独断で決めている部分もあるので、ご注意を。特に、具体例で挙げているサービスには筆者が使ったことのないものも多く、ディスクリプションに間違いが含まれている可能性があります。ご指摘などあれば、コメントなどお願いします!)。リストは、サブカテゴリも含めて、全てできるだけソフトウェア開発技術でいう「下級」から「高級」*の順に並べています。また、サブカテゴリは全て筆者独自の定義なのでご注意を。

*:「下級・高級」の違いについてはこちら(英語)を参照。要するに、よりHW・インフラストラクチャに近い方を下級、より抽象化されてビジネスロジックに近いものを高級としています。

IaaS (Infrastructure As A Service)

基本的には、サーバ、ネットワーク機器、ストレージ機器の代替。土地・建物・ハードウェアなどを持たなくてよくなり、メンテナンス、システムアドミン業務も低減できる。ただし、低減できるとはいっても、実はかなりのメンテナンスタスクが必要になると言われており、引き続きインフラエンジニアリソースが必要である。

  • 非サーバIaaS:ストレージ、ロードバランサなどサーバ以外のインフラストラクチャを借りれるサービス。アマゾンのElastic Load Balancing (同社EC2専用)Elastic Block Storage (EBS)などが代表。ちなみにAmazon EBSでは最近、大手ニュースアグリゲーションサイトRedditを含む複数大手サイトをダウンさせる障害が、数ヶ月間に複数回発生。少し悪評が立ってしまっている。

  • サーバIaaS:仮想サーバを時間課金などで「間貸し」してくれるサービス。OSを自分で入れるものもあるが、大体はメニューからOSを選んでインストール済みの仮想サーバをもらう。セキュリティパッチの適用や、LAMP環境などのプリインストールといった追加的なサービスを実施している事業者も多いよう。リソースは完全にオンデマンドではなく、あらかじめ指定したキャパシティ(ストレージ容量、RAM量、CPUリソースなど)を買っておいて、完全に使いきらなかった分は「残念でした」という料金形態が多い(完全にオンデマンドのサービスとしては、1トランザクションいくらという料金体系のDBサービスなどがある)。料金体系は月単位買いきり、起動時間分課金など様々なものがあるよう。代表例はAmazon EC2Nifty CloudIBMクラウド(IaaS)など。



PaaS (Platform As A Service)

OSと、DB、アプリケーションサーバなどのミドルウェアを借りて、その基盤に自作アプリを展開する方式。OS、アプリケーションサーバ、DBなど用意されるサービスについてはチューニング・セキュリティパッチの適用などを気にしなくてよくなる。そのため、インフラエンジニアリソースのいない組織でも開発が可能になってくる。スコープ(どこまでが利用者が行うことで、どこまでがプロバイダが行うことか)はXaaSの中でもっとも多彩と思われる。

  • オープン型:アプリケーションサーバ、ランタイム環境などが提供され、制限は存在するものの、比較的少なく、割と好きなようにアプリケーションを組める。代表例はvmForce, Heroku, Azureなど。具体的には、バックグラウンドプロセス、スレッド、ソケットなどが利用できたり、任意のミドルウェアを展開して使えたり、2つ以上の開発プラットフォーム(例えばvmForceだとJython, JRuby, Groovy, Scala, Javaなどが使用できるはず)が使えたりする種類のもの。こういったサービスはDBも従来型のリレーショナルDBを用いることができるものが多い。

  • セミオープン型:比較的制限が多いが、その代わりメンテナンスコスト、ランニングコスト、初期コストが少なく、スケールアップが容易といった位置づけで提供されているサービス。バックグラウンドプロセス、スレッド、ソケットが使えなかったり、リクエストの実行時間に制限があったり、サービスに付属のDB以外は使えなかったりする制限がある。特にDBについてはリレーショナルDBでないことが多いよう。2つ以上の開発プラットフォームが使えるものもある。代表例はGoogle App Engineなど。

  • クローズド型:比較的制限が多く、どちらかと言うと特定用途のアプリケーション開発に向いているもの。プラットフォーム独自の言語でしか開発できないものもある。代表例はSalesforce.comのForce.com。Force.comでは同社独自の言語であるApexを用いなければならず、オープンソースのライブラリやソフトウェアを展開するのはほぼ不可能。他にも一回のDBクエリで取得できる行数、一時に使用できるヒープメモリなどに細かい制限(governor limit)があり、自由度が低い傾向があるよう。そのため、多種多様なアプリを開発する総合的なプラットフォームとしては現状適していないという意見が多い。その代わり同社のCRMとの相性が良く、CRMを大幅にカスタマイズするような局面では非常に適していると見なされている。ただし、クラウドSIの先駆で米国のスタートアップ企業であるAppirio社などは、独自のノウハウを駆使して、force.com上でCRMに限らず様々なエンタープライズアプリを開発・展開しているとのこと。

  • MaaS (Middleware as a Service)型:DB、分散コンピューティング、モニタリングサービスなど、従来型のシステム開発では商用ミドルウェア、オープンソースミドルウェアを充てるもの。具体例には、データベースを提供しトランザクション毎課金などの料金体系が使えるSalesforceのdatabase.comや、科学計算などのパラレルコンピューティングが主なユースケースであるPiCloudなどがある。PiCloudはバックエンドにAmazonのAWSを使用しているそうで、IaaSをMaaSにすることで付加価値を付して販売しているということになる。こういった「クラウドミドルウェア」が提供するサービスのコンシューマは、クライアントソフトウェア(PC上で動くデスクトップアプリケーション)、自社ホストの従来型バックエンド、PaaS上のアプリなど様々なパターンが考えられる。人によってはSaaSに含める人もいるのかもしれないが、SaaSにしては下級だと思うので、筆者はPaaSに分類している。

  • モバイルプラットフォーム型:AppleのApp Store、AndroidのAppstoreなどのスマートフォンアプリプラットフォーム、Gree、DeNAのSNSアプリプラットフォームなど。XaaSに含めない人もいるのでしょうが、クラウドと非常に密接に関連しているとは少なくとも言えそう。

  • マーケットプレース・ポータル型:大分毛色は違いますが、B2C型のSaaSを販売する経路(ポータル)だけを提供する形態のこと。ホスティングなどには関与しない。クラウドならではの利点が薄そうなのであまりピンと来ませんが、そういうビジネスをして「クラウドビジネス」と言っている会社もいるみたいなので。

  • デスクトッププラットフォーム型:Chromium/Ubuntu/Windowsなどのネットブック/PCプラットフォーム。Eclipseなどの「プラットフォーム型アプリ」も含めたいと思います。「全然クラウドじゃないじゃん」と言われてしまいそうですが、Ubuntuなんかapt-get installを使えばほとんどSaaS感覚でソフトが使えるようになります。ブラウザのChromeみたいに勝手にアップデートするソフトが増えてきて、かつOSもChromeと同じくらいシームレスにアップデートされるようになってくれば、割とSaaSに近くなってくるのではないでしょうか。以前から存在したJava Web Startといったリッチクライアント技術もあります。XaaSに入れるのは間違いかもしれませんが、これからXaaSと「従来型ソフト」の境目ってあいまいになってくるんじゃないかと思うんです。この辺の示唆などは、次回考えてみたいと思います。関連のある試みとしては、Intelのネットブック向けアプリストアがあります。



SaaS (Software As A Service)

従来ユーザがパッケージソフトを購入したり、カスタムアプリを開発して利用していたサービスを、月額などで課金して提供する形式(説明不要か(^^;))。

  • バックエンドサービス提供型:ビジネスインテリジェンス、コンテンツマネジメント、課題管理などの機能を、他のシステム(そして最終的にはUI)にインテグレーションすることを前提で、開発者向けのAPIとして提供するもの。B2Bだけではなく、以前はクリック証券が、個人投資家が自作のシステムトレードソフトウェア開発に利用出来るAPIを提供して話題になった。クリック証券はこのAPIサービスを停止してしまったようだが、他の証券会社が引き続き似たAPIを提供しているよう。こういったAPIを使って個人の開発者が作成したシステムトレードソフトウェアを、さらに個人投資家に販売するといったビジネスも発生している。その他の具体例としては、科学計算などに使えるWolframAlpha、ビジネスインテリジェンスのSAS-on-Demandなど。

  • 社内システム型:UIまで提供され、それを従業員などが直接利用する形態。APIなども合わせて提供され、これを使ってSIerが他システムと連携させた上で導入する場合も。基本的に零細~小企業は直接利用、中~大企業はSIerを使ってカスタマイズ・連携した上で導入するパターンが多いと思われる。具体例は、開発支援ソフトのFogbugz、電子カルテのMegaOakSR for SaaS, Salesforce CRMGoogle Appsなど。

  • B2C型:一般消費者向けに直接サービスを提供する方式。家計簿、投資管理、タスク管理、コンテンツ管理など。具体例はオンラインストレージのDropbox、投資管理ソフトのmint.comGmail(個人向け)など。変わり種では、オンラインで画像処理ができるpixlrも。



DaaS (Data As A Service)

株式市場のデータ、音楽・写真などのデータをオンデマンドで売るサービス。iTunesやKindleも広義に解釈すれば含まれるんじゃないだろうか。ただし、基本的には他システムへのインテグレーションを前提にAPIを公開しているサービスを言うようだ。

DaaS (Desktop As A Service)

デスクトップをサービスとして提供するビジネスモデル。目的としては、色々なPCからでもいつも同じ環境にアクセスしたいという「利便性」と、デスクトップにデータを持ちたくないのでシンクライアントにしたいという「セキュリティ」の2つに分類できるのではと思う。

  • 部分型:ブックマークの同期や、ファイルの同期を取るソフトウェアが提供され、共有PCなど他のPCを使っていても、あたかもいつも自分の「メインPC」を使っているかのような利便性が得られるもの。完全にメインPCと同じように使えないのならSaaSじゃないかという話もあるが、Ubuntu Oneなどは完全な仮想デスクトップでなくても、SaaSをいくつか組み合わせてより仮想デスクトップに近い形にすることをコンセプトにしているようなので、そういうものは「セミDaaS」とでも言っていいのではと思う。

  • 完全型:デスクトップ環境をリモートログイン感覚で、まるまるサービスで提供する形態。シンクライアントなど。富士通のサービス例



PaaS (Peripherals As A Service) ※筆者の勝手な造語

Desktop As A Serviceでは、「どのHWからアクセスしても同じデスクトップに接続したい」というものだったが、これはあべこべに「同じデスクトップから、いろいろな周辺機器(HW)を使いたい」という要望に応えるサービス。NECが、コンビニの複写機などで「クラウド越しで」プリントアウトできる仕組みを開発しているそうで、そういったものはこれに含まれるのではと思う。他には写真を焼く機械や、CD/DVDなどの媒体を焼く周辺機器、カメラなどが想定できそう。

RaaS (Real-life As A Service) ※筆者の勝手な造語

半分冗談ですが(^^;)個人的には「マネージド農業プラットフォーム」とかやってみたいですね(笑)オンデマンドで土地とか水とか肥料とか買えて。。好きな種をまいて収穫して送ってもらうとか。こないだGreeの人に言ってみたら「もうハコニワあるよ」なんて馬鹿にされてしまいましたが、バーチャルな庭じゃなくて、ガチでビニールハウスを運営してもらって、本物の種をまいて本物の野菜とかを栽培するサービスです。リアル釣りスタは人件費が途方もなくかかりそうなので無理そうですねw。他にも「マネージドお料理プラットフォーム」(レシピを送れば調理して送ってくれる)とか、夢は広がります。もうすでに存在しているものでいえば、オンライン英会話のスカイトークとか、オンライン家庭教師などがあります。そう考えると、このジャンルにも何か分類名を与えてもいいのではと思います。でも家庭教師とかそもそもサービスなんで、As A Serviceだと語呂がいまいちですが。。





。。。後からわかったのですが、米国標準技術局(NIST)がXaaSの定義を詳細にしているのだそうです。ブログAgile Catが非常に詳細に紹介しておられます。



その他クラウドの定義などについて考察している記事:

お前の言っている「クラウドコンピューティング」とはなんですか?





【お薦め洋書】 Unbroken: A World War II Story of Survival, Resilience, and Redemption

第二次世界大戦から生還したアメリカ兵Louis Zamperiniの実体験を、著者のLaura Hillenbrandが、Louis Zamperini本人の全面的な支援を受けて、何年にもわたってありとあらゆる記録、証言を丹念に集め、書き上げた大作です。事実関係には本当に驚くほど細かく脚注がついており、根拠となっている資料・証言が丹念に示されています。

僕が今までに読んだ中で、文句なしで一番心動かされた本です。あまりに凄惨な戦争の現実。何度も何度も折れそうになるたび、立ち上がり戦うLouis。死んでいく仲間たち。残酷な日本人との出会い、やさしい日本人との出会い。アメリカで心を切り裂かれる想いでLouisを待っている家族との家族愛、再会、そして終戦後もLouisを苦しめる戦争の記憶。日本人としては複雑な気持ちになる作品ですが、本当に是非読んで欲しい作品です。

読み始めると先が気になって止まらず、久しぶりに本のせいで寝不足になりました。歩きながら、あるいは電車の中など、何度となく感動して涙してしまいました。読み終えた後は、平和であること、今ある幸せに対する感謝の気持ち、そして勇気と元気がじわじわ湧いてくる、そんな本です。

【あらすじ】
貧しい家庭に生まれ、一旦は不良となったLouis Zamperiniが、家族のおかげで長距離走に出会い、少しづつ人生を立てなおしていきます。ついにはオリンピック選手にまでなり、ベルリンオリンピックに出場しますが、第二次世界大戦が始まり、今度は空軍の兵士として太平洋に送られます。

ある日、乗っていた爆撃機が太平洋に墜落。なんとか墜落を生き延び、漂流しながら救助を待ちますが。。。想像を絶する地獄の日々を経てようやくたどり着いたのは敵国日本の支配下にある島。

壮絶な捕虜生活から生還したLouisですが、戦争の記憶が彼を苦しめます。ある日、日本兵と取っ組み合って首を絞めあう悪夢を見るLouis。目が覚めたLouisは、自分が妊娠中の奥さんの首を締めていたことに気づきます。。。Louisは戦争の亡霊に打ち克つことができるのか。

できるだけ史実に基づいて忠実に描かれており、ドキュメンタリーとしてもすごく優れた本ですし、Louis氏自身が語った心の変化、キリスト教との関係性もすごく興味深いです。

Louie Zamperiniのオフィシャルサイト


【お薦め洋書】(2冊) Free: The Future of a Radical Price と、 What's Mine Is Yours: The Rise of Collaborative Consumption

これからのビジネスがどう変わっていくかを考える上で外せない2冊ではないかと思います。

��冊目は、最近急に世の中に増えてきた「無料」の商品・サービスについて考察したChris Anderson (Wired編集長)の著書、「Free: The Future of a Radical Price」。無料で採算が取れていることに納得できる商品・サービスもありますが、たまに一体どうやってお金を稼いでいるんだろうと不思議になってしまう無料の商品・サービスってありますよね。この本は、そういったビジネスの仕組みや、なぜそのようなビジネスが増えてきたのか、また、これからの「無料ビジネス」時代では、どのような点に注意しなければいけないかといった話題を扱っています。




��冊目は、「これからの消費」に焦点を当てた一冊。弱冠33歳(2011年現在・筆者による推定(^^;))のRachel Botsmanが、オークションサイト、カーシェアリング、P2Pファイナンスなど最近話題になっているサービスについての考察や、様々な経営者・イノベーターとの交流を元に、「世界の消費活動が従来の『ハイパー消費』から、新たな『コラボ消費』へパラダイムシフトしつつある」と主張しています。

少し前にもてはやされた「Web 2.0」と考え方は似ているのですが、新たに「サステイナビリティ」、「コミュニティ」という2つの視点が加えられており、非常に新鮮というか、目からウロコ感があります。ITに深く関わる話ではありますが、ITにとどまらずより大きな視点から論じられています。Web 2.0の進化系というか、あぁ、Web 2.0ってこういう大きな動きの一環だったのか、と感じられるような本です。

著者はさらに、「新たな」潮流であるこの「コラボ消費」が、実は近代以前の消費形態であった物々交換、村社会のいわば復興(「ルネッサンス」の方が適切か)であるとも論じており、非常に興味深いです。

本を読むのはめんどくさいという方は、とりあえず著者がコラボ消費について語っているTEDでの講演を聞いてみてもいいかも(末尾にエンベッドしてます。日本語字幕も出るはずなので試してみてください)。気づいたんですが、Chris Anderson / Rachel Botsmanの両方ともTED演者なんですよね。やっぱTED最高です。



Servlet 3.0の「非同期」サポート -- 何がうれしいのか?



マニアックすぎる話ですが(^^;)


ひとことで言うと、「これまでは、リクエスト処理時間が長めで、同時接続数が非常に多いサービスをJavaで作る場合はマニアックな方法を使うか、我慢して高いHWコストを払わなければいけなかったが、これからはプログラマが親しんだJavaEEを使ってHW効率のいい実装ができるようになった」ということになります。



じゃぁ「リクエスト処理時間が長めで、同時接続数が非常に多い」って具体的にどんな基準よって話なのですが、僕の超独断と偏見に基づく、超ざっくりな基準はコレです:




  • ビジネスロジック(コンテナからリクエストを受け取ってから、レスポンスをコンテナに渡すまで)部の実行時間が、3-5秒以上

  • 実行時間が長くなる原因が、ビジネスロジック内で行うIO(ディスク・ネットワーク)

  • ピーク同時接続数が500-1000以上





一応経験に基づいた値ではありますが、当然こんな画一的な基準を提示するのは無謀と言ってもいいくらいなので、ご了承お願いいたします(^^;) さらに、新しいアプリか既存アプリかによって次のようなことを考える必要があります:




  • 新しいアプリの場合


    • そもそもそういうリクエスト処理時間・同時接続数になるのは適切なのか?

    • 本当に、従来の方式で実装したら問題が出ると予測されるか?

    • そもそも同期のインターフェースにすることは適切?メッセージキューなどの非同期型インターフェースの方が適切だということはないか?

    • 使えなくなってしまうフレームワークなどが出るが、それを補う案はあるか?

    • JavaEEとはいえ、従来のプログラミングモデルとはかなり違ってしまうが、それにうまく適応できそうなチームか?

    • 枯れた技術から新しい技術へ移行する以上、安定性などの面でリスクがあるが、それを凌ぐメリットがあるか?




  • 既存アプリの場合


    • 症状の原因は、本当にこの特定の並行性能問題か?


      1. Connection RefusedやRead timeout、異常に処理時間が長いなどの問題がクライアント側で確かに出ていて、サーバ側の問題に間違いない

        • 負荷バランサのせいだったりすることも。。



      2. 異常ではない

        • 外部のWebサービスなど外部のサービスに異常が生じて、異常にリクエスト処理時間が長くなっていることも


        • インフラの異常ではない?サーバ仮想化を使っている場合、仮想マシンを上げすぎて性能が極端に低下しているなどということはないか?(実話(^^;)ネットワーク・DB・ストレージは?他のプロセスがサーバのリソースを圧迫していないか?


        • バグではない?クライアント側が異常にリクエストを繰り返しているということはないか?サーバ側のバグで余計な処理をしていたり、DB処理が無駄に長く掛かっていることはないか?メモリリークではないか?など



      3. ビジネスロジック部の実行時間が確かに長い

        • コンテナによっては統計を出してくれるかも。プロファイラでスレッドの状況を見るのが一番良いでしょう。

        • 「ビジネスロジック部は短いが同時接続数が非常に多い」というシチュエーションなら、NIOコネクタの使用で解決される可能性も。最近のメジャーなコンテナならまず使えるはず



      4. 単にコンテナの設定が悪いわけではない

        • ドキュメントを参考にチューニングしても症状が持続するかチェックする。実は誰かがデフォルトの設定に余計なことをして問題が起きていることも往々にしてある



      5. スレッドリソースが確かにビジネスロジック部で浪費されている。具体的には、多くのWorkerスレッドがビジネスロジック内で待ち状態か?

        • たくさんのWorkerスレッドが実行可能状態の場合は、コンテキストスイッチスラッシングが起きている可能性があり、むしろmax-threadsを下げると解決する可能性も

        • これもコンテナによっては統計を出してくれるかもしれませんが、僕はスレッドダンプを打ち出して集計してます(^^;)



      6. 設計やデータ量・処理量などから考えて、多くのWorkerスレッドが待ち状態におかれるということが確かにありそうなことか?



    • 以下の選択肢を全て検討したが、ざっくりとした改造コストとテンビンにかけても、なお改造の方が良い可能性がある

      1. もっといいハードウェアを買う

        • 最も容易だが、金がかかる上すぐに限界が訪れやすい



      2. HWを足して、負荷バランスする


        • まともな高可用性を備えたアプリなら簡単にできるはずだが、コストパフォーマンスがかなり悪くなる場合も。サーバは当然のことながら、負荷バランサでもコストがかかることがある


      3. 他のところやビジネスロジックで最適化などを行い、Workerスレッドが待ちになる時間・リクエスト処理時間を減らす
        • どのくらい「贅肉」があるかによる。基本的に、アプリ・外部サービスが新しかったり、今回ほどの性能要件でテストされたことがなかったり、担当したチームの能力が低かった場合などは、「必要なインデックスが張られていない」などの「削ぎやすい贅肉」が見つかる可能性が高い。そうでない場合は効果の予測が困難



    • 「新しいアプリ」編のチェック項目全て







ここまで検討しても、なお「非同期処理」がベストの選択肢であると考えられるなら、真剣に検討してみる価値がありそうです。次回は、実際にServlet 3.0でのWebサービスを作ってみます(あくまで予定ですが(^^;))



Eclipseが遅くて腹たってる人中心に、Intellijのススメ

どうやら日本語化されていないようなので日本で使っている人は少数派かもしれませんが、グーグルやRedHatのOSS開発者の間などで大人気、人気急上昇中のIntellij IDEAというJava IDEがあります。

チェコの数学者が集まって作ったIDEで、有料版しかなかった頃から大変評判が良く、割と出来のよいeclipseが無料で誰でも使えるという市場環境にも関わらず大いに健闘していました。この会社は、.netの分野でもいくつか人気の高い開発ツールを出しています。本当にすごくいい噂を聞くIDEなので気にはなっていたのですが、貧乏の身なので試すこともできず...ご多分に漏れず僕もeclipseをずっと使っていました。

が、2009年にベンダが"Community Edition"型のビジネスモデルに移行。要するに、基本機能を備えた版が無料で使えることになったのです!しかもCommunity EditionはApacheライセンスのオープンソースに。太っ腹です。採算は、より高機能のUltimate Editionを販売することでとろうとしているようです(※ちなみにOSSの開発に使う場合は、Ultimate Editionも無料とのことです)。

てなわけで当時早速使ってみたのですが、結論から言うと、もう絶対離せません(笑) 最初はeclipseとの違いに戸惑うことも少なからずありましたが、取りあえず速い。これホント重要。もうこれだけで頑張って乗り換えようという気になります(笑) 次に、Mavenとの連携がマジいい!今は改善されたのかもしれませんが、eclipseのmavenプラグインは大分不安定だったので、かなり違いを感じました。他のプラグイン・機能の類も概して非常に安定して動作し、性能も良いです。オートコンプリートもeclipseより若干かしこく、本当にサクサクプログラミングができます。

他にはリファクタリングがeclipseよりも高機能、なかなか良いコードの静的解析が標準装備されている、すごく高機能のコード変更履歴機能がついている、あたりが思いつく利点でしょうか。ただ、何よりも速い。これにつきます(少なくともeclipse galileo当時はかなりの差があった)。

eclipseに劣るところといえばプラグインの少なさですが、それでもIDEがオープンソース化される前から、プラグインを開発するためのAPIと、そのプラグインを公開するためのマーケットプレースのようなものが提供されていたので、そこそこの数のプラグインは提供されています。今回オープンソースになったので、さらにプラグイン開発の裾野が広がってくれそうです。

商売道具ですから、長年eclipseを使っていると移行の際のストレスはかなりありますが、それを我慢する価値アリです。


とは言えeclipseほどたくさんの言語をサポートしているIDEはないので、今もpython, erlangの開発にはeclipseベースのIDEを使っています。特に、AptanaというところがWeb開発者向けの多言語対応型eclipseパッケージを提供してまして、これがWeb開発には本当に便利です。やっぱ、悪くはないですよね、eclipse。それでも、もっと速いIDEが欲しい。。。と思っている人は、是非Intellijを試してみてください。




世界は再び小さな村へ・・・ 匿名社会の終焉

少し前に、カナダのバンクーバーで市民の一部などが暴徒化する事件がありました(記事)。バンクーバーでそのような事件が起こったの事自体も驚きでしたが、もう一つ、非常に面白い社会現象が見られました。

reddit.com、facebook、youtubeなどのソーシャルメディアに、現場の写真・映像が次々と投稿され、違法行為に参加していた人々が次々と特定されていったのです。あるカナダのブログは、これらをまとめて、違法行為を働いていた人をいわば晒し者にする"Hall of Shame"キャンペーンを始めました(ブログ)。普通の大学生やスポーツ選手などが、違法行為の瞬間を捉えた写真や映像と共に、実名を掲載されています。誤認もあり得ますし、このようなことをすること自体は批判されるべきでしょう(警察などに情報提供するべき)。しかし、この出来事は、これからは「匿名」であることが、オンラインだけでなくオフラインでも難しくなっていることを示しています。

まだ実用化には至っていないものの、普通のスナップ写真から顔を特定し、顔認証で映っている人物を特定する研究が各地で進んでいます。、画像だけでなく、動画からリアルタイムで人物を探す技術の研究もされています。このような技術が実用化されるのは、時間の問題と言えるでしょう。

このような技術の発達で、世界は再び「ムラ社会」に回帰しようとしているのではないでしょうか。技術は新しいものですが、その技術がもたらす世界は、案外かつての田舎に近いものなのかもしれません。だとすれば、大都会に慣れた人は、新しい世界の秩序の中でどううまく生きて行くべきか、田舎に学ぶ必要があるかもしれませんね。

EDIT:カナダの警察に、100万枚以上の写真と1000時間分以上の映像が寄せられ、警察では顔認証技術も使用してこれらを解析するとのことです。現在の顔認証技術ではどこまで有効かわかませんが、本当に象徴的な事件となりました。


What will happen with Ethereum in 30 years?

tl;dr : We will continue to have a decentralized, global chain powered by ETH, but most of the economic activities using smart contracts ...