Windows系エンジニアのためのElastic Map Reduce 5

Amazon EMRでHiveを使う
EMRに接続して操作するためにSSHに対応したtelnetクライアントが必要です。私自身長年使っていることもあって、TeraTerm(http://ttssh2.sourceforge.jp/)をお勧めします。
Cluster Listから作成したEMRインスタンスの詳細を表示すると、Master public DNS nameにドメイン名が表示されています。このドメインにSSHで接続すると以下のように表示されます。SSHでログインするときのユーザーIDはhadoopです。

Linux (none) 3.2.30-49.59.amzn1.x86_64 #1 SMP Wed Oct 3 19:54:33 UTC 2012 x86_64
——————————————————————————–

Welcome to Amazon Elastic MapReduce running Hadoop and Debian/Squeeze.

Hadoop is installed in /home/hadoop. Log files are in /mnt/var/log/hadoop. Check
/mnt/var/log/hadoop/steps for diagnosing step failures.

The Hadoop UI can be accessed via the following commands:

JobTracker lynx http://localhost:9100/
NameNode lynx http://localhost:9101/

——————————————————————————–
hadoop@ip-10-121-9-185:~$
hadoop@ip-10-121-9-185:~$ hive

プロンプトが表示されたらhiveと入力して、hiveのインスタンスを起動します。
先ほどS3にアップロードしたファイルをテーブルとしてマウントします。

> Create external table reviewsNew
> (MemberID String, ProductID String, ReviewDate TimeStamp,
> HelpFeeedbackNum Int, FeedbackNum Int, Rating Int,
> Title String, Body String )
> row format delimited fields terminated by ‘t’ lines terminated by ‘n’
> stored as textfile location ‘s3://emr-sample/reviewsNew’

これで集計をおこなう準備が完了しました。

> select size(split(Body, ‘ ‘)) as wordscnt, count(*)
> from reviewsNew
> group by size(split(Body, ‘ ‘))
> sort by wordscnt;

上記のようなselect文を実行して集計してみます。bodyに含まれる単語数をカウントして、各単語数のレビューが何件あるかを集計します。この手のインデックスが全く機能しないようなSQLをRDBMSで実行した場合、現実的な時間内には終了しません。hiveなら5ノード程度の小さなクラスタ構成でも7分ほどで集計が終わります。
実際に使用する場合には以下のように結果保存用のテーブルを作成しておきます。

> create external table wordscnt
> (wordcnt Int, recordCnt Int)
> row format delimited fields terminated by ‘t’ lines terminated by ‘n’
> stored as textfile location ‘s3://emr-sample/wordscnt’

そして以下のように保存先テーブルを指定し、結果保存用のテーブルに格納します。その後、S3から作成されたデータファイルをダウンロードします。

> insert into table wordscnt
> select size(split(Body, ‘ ‘)) as wordscnt, count(*)
> from reviewsNew
> group by size(split(Body, ‘ ‘))
> sort by wordscnt;

Windows系エンジニアのためのElastic Map Reduce 3

AmazonでEMRを起動する
まずはEMRで使用するKeyPairを作成します。既に作ってある人は、それを流用してもかまいません。AWSマネジメントコンソールにログインし、EC2のコンソールを開いたら、左側のメニューからKey Pairsを選択します。Create Key Pairをクリックしてダイアログが表示されたら、Key Pair Nameを入力してYesをクリックします。自動的に鍵のダウンロードが始まるので、ダウンロードされたファイルを保管します。
続いてEMRのインスタンスを起動します。AWSマネジメントコンソールのElastic Map Reduceを選択し、Create clusterボタンをクリックして下さい。
Cluster ConfigurationのCluster Nameには適当に識別可能な名称を設定します。Loggingはチェックを外して下さい。
Software Configurationは初期設定のままでかまいません。Hadoop distributionはAmazonにチェックを、AMI Versionは初期設定で2.4.2になっているので、そのままにします。Applications to be installedにも初期設定でHiveとPigが含まれているはずです。
Hardware Configurationには若干のHadoopについての知識が必要です。NetworkとEC2 availability zoneは初期設定のまま、EC2 ClassicとNo preferenceにします。問題となるのはEC2 instance typeでHadoopを構成する仮想マシンノードの数と種類を指定します。
Masterは必ず1台必要になるノードで、Hadoopの分散処理に参加する全てのコンピュータを制御する中心となるノードです。構成する台数が増えた場合、Masterノードのスペックが低いと全体の処理性能が低下する恐れがあります。Masterノードは次に説明するCoreノードとしての機能も兼ねます。
Coreは必ず2台以上必要になるノードです。Hadoopの分散処理においてHDFSと言う分散ストレージを提供しています。EMRではストレージとして主にS3を使用するので、あまり容量を必要としませんが、Hive等のミドルウェアが一時的な記憶領域としてHDFSを使用する場合があります。途中でノードが停止した場合に備えるのと、読み取り負荷分散のため、三重に分散して保存するので、意外に容量を必要とする場合があり、必要に応じて増やします。
Taskは純粋に計算処理を担当するノードです。割り当てない事も出来ます。
Master、Core、TaskともにSpot Instanceを指定して料金を節約することが出来ますが、Masterノードが停止した場合には即座に処理が中断してしまいますし、Coreノードが2/3以上停止するとHDFSに保存したデータが消失してしまい、処理を継続出来なくなる可能性があります。練習中は良いですが、本番ではTaskノード以外をSpot Instanceにすることは避けた方が良いでしょう。
Security and AccessのEC2 key pairを設定して下さい。EMR起動後にSSHでログインするために公開鍵が必要になります。
最後にStepsのAuto TerminateはNoに設定します。

Windows系エンジニアのためのElastic Map Reduce 2

Hive用データを準備する
HiveはCSV形式やTSV形式のファイルに対して処理を行ないます。処理対象とするファイルを事前に変換しておきます。
ファイルは数10MBから数百MB程度のサイズで、複数のファイルに分割しておきます。Hiveは一つのファイルを一つのMapperプロセスに割り当てます。検索対象となるファイルの数が処理を分散できるノード数の上限になるので、必ず適度なサイズに分割しておかないと、Hadoopのメリットを得られません。
Hiveでは一つのフォルダを一つのテーブルとして扱います。ここで作成した分割ファイルをひとつフォルダに保存します。
通常のHadoopではHDSFを使用しますが、Amazon EMRではS3をストレージとして使用します。EMR用にS3のBucketを作成し、フォルダを作り、そこに作成したファイルをアップロードします。ここで作成したフォルダがHive上では一つのテーブルとして扱います。
Bucketを作成するリージョンは、EMRで使用するリージョンと同じ場所にします。同一リージョン内でのネットワーク通信は課金の対象となりませんが、リージョンをまたいだ通信は課金の対象となるので注意しましょう。
同様の理由でCSV形式のファイルへの変換や、CSVファイルをS3にアップロードする作業もAmazon EC2上で行なった方が良い場合もあります。EC2上の仮想マシンからS3へのアップロードは低速のインスタンスでも200~400Mbpsで行えますが、インターネット経由ではシングルスレッド転送だと数百Kbps~数Mbps程度になってしまい、大量のデータをアップロードするには時間がかかりすぎます。
都合、インターネット経由でアップロードする場合には、S3 Browser(http://s3browser.com)のような、マルチスレッド対応した転送ツールが便利です。
ここではサンプルデータとしてインターネット上で公開されているAmazonのレビュー記事のデータを使います。http://liu.cs.uic.edu/download/data/からreviewsNew.rarをダウンロードしてきます。解凍して得られたファイルを適当な行数で分割します。私はCygwinのsplitコマンドを使用しました。これを新たにemr-sampleバケットを作成し、reviewsNewフォルダにアップロードします。

Windows系エンジニアのためのElastic Map Reduce 1

初めに・・・
MapReduceが世に出て早10年、Amazon Elastic Map Reduce(以降EMR)のようにパブリッククラウド上でHadoopを使った分散処理を行えるようになって5年ほどが過ぎました。実際活用しようとするとLinuxを中心とするOpenSource界隈の知識が必要になるため、Windows系のエンジニアからはどうしても遠い存在になりがちです。
ところが最近EMRのWEBインターフェースが刷新されました。以前はコマンドラインでの操作が必須だったのが、WEBからの操作でもずいぶんと使いやすくなりました。この機会にEMRを使いこなしてBigDataの処理など学びたいと思います。
さてBigData処理には大別して二つあります。一つは大量の非構造化データを扱う処理。二つ目は大量の構造化データを扱う処理です。非構造化データの処理は自然言語処理、機械学習といった高度なソフトウェアサイエンスの知識が必要不可欠で、Hadoopで分散処理ができるようになったから一朝一夕に実現できる類のものではありません。二つ目の構造化データなら高度なコンピュータサイエンスの知識がなくとも、手元のデータを解析して何らかの答えを得ることは可能です。だから、ここでは構造化データを扱うことを最初の目標としたいと思います。
構造化データならRDBを使えばHadoopなんか要らないのでは?と考えるかもしれませんが、RAWレベルのログデータなんかを1年分集めると、中小企業でも数十GB~数百GBに達してしまいローレベルのサーバーでは到底解析できないサイズになってしまいます。これを解析できるサーバーを別途用意するというのは、中小企業にとっては大きなハードルなのです。
Hadoopの基本はMap Reduceにあるわけだけど、実際に使うためにはプログラムを開発せざる得ない。そしてプログラムを開発するとなると、テストやら何やらで結構時間がかかるもの。特に私みたいなWindows中心の開発者だと、Linux環境でのプログラミングに不慣れなこともあって、やたらと時間がかかったりします。でも構造化データを扱うならばMap Reduceは必要ありません。HadoopにはHiveやPigといった構造化データを手軽に扱うための仕組みが用意されています。
HiveはHadoop上で動作する簡易RDBです。一般的なRDBと異なりSELECT文は充実していますが、INSERTやUPDATEと言ったデータを更新するための機能が著しく制限されています。カンマ区切りやタブ区切り形式で保存されたテキストファイルや、Hive独自形式のデータベースファイルに対して集計処理を行えます。Hiveに与えたSQL文は数段階の処理に分解されMap Reduceアプリケーションにより集計されます。下手なMap Reduceアプリケーションを作るより余程高速に動作するので、まずはHiveを使った集計処理を学びたいと思います。

Visual Studio Onlineでgitを使用する

Visual Studio OnlineではMicrosoft独自のTeam Foundation Version ControlかOpen Sourceのgitを選択することができますが、gitを使用する場合には追加でパスワードの設定が必要です。
右上に表示されている自分の名前をクリックして、ドロップダウンメニューから「My Profile」を選択します。表示されるダイアログから「CREDENTIALS」を選択して、「Enable alternate credentials」をクリックします。「User name (secondary)」の右側にある「Edit」、「Password」の右側にある「Change」を栗㏍すいて、gitで使用したいユーザーIDとパスワードを設定します。
この時、設定するユーザーIDとパスワードはWindows Live IDで使用しているIDやpasswordとは別のものにしてください。
gitをhttp接続で使用する場合の認証手段はベーシック認証の選択肢がありませんから、Windows Live IDを使ったシングルサインオンに対応できません。また、残念なことに標準的なgitクライアントはベーシンク認証のユーザーIDとパスワードを平文で保存するため、パスワードの漏えいリスクが高いのです。そのためVisual Studio Onlineではgitで使用するユーザーIDとパスワードはWindows Live IDのユーザーIDやパスワードとは別に設定するように作られています。

ASP.NET MVCの標準ユーザー認証のDBを任意の場所に変更する

ASP.NET MVCの標準ユーザー認証機能の保存先データベースはApp_DataASPNETDB.MDFになっている。これを任意のデータベースに変更するためには、Visual Studio 2010のコマンドプロンプトを開いてaspnet_regsqlを実行してDBに必要なテーブルなどを作成した後、Web.configのconnectionStringsに書かれているApplicationServicesの接続文字列を変更すれば良い。
[C#] #27. フォーム認証によるユーザーの認証

VC++ .NET 2003でUACを有効にしたアプリケーションを作成する。

VC .NET 2003以前の開発環境はマニフェストを実行ファイルに埋め込む機能が、設定画面に用意されていません。そこで手動で作成したマニフェストをリソースとして埋め込む必要があります。
まずは以下のようにマニフェストファイルを作成します。赤字の部分がUACに関する部分です。requestedExecutionLevelのlevelにrequireAdministrator(管理者権限が必要)を指定すると、実行時にUACの画面が表示されます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Microsoft.Windows.WinSafeCleaner"
type="win32"
/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel
level="requireAdministrator"
uiAccess="true"/>
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

これをRT_MANIFESTという名称のカスタムリソースの、リソース番号1として実行ファイルに埋め込みます。
参考資料
マニフェスト・ファイルをアプリケーションに組み込むには?

Excelで計算がされない

Excelで複雑な計算式を多数入力していると、自動計算やF9による再計算で、一部の数式が再計算されずに正しい値を表示しない事があります。
CTRL+ALT+SHIFT+F9で再計算する
Excelは値が変更されたセルや、再計算が必要なセルを記憶しており、必要最低限の計算量で再計算をおこなうようになっています。稀にこれが正しく動作せずに再計算が行われなくなる場合があります。この場合はCTRL+ALT+SHIFT+F9を押すことで、変更されているか否かにかかわらず、すべての式を計算します。これによって次回から変更されたセルに関する情報がリセットされ、正しい計算結果を返すようになります。
数式のどこかにエラーがある
数式のどこかで循環参照などのエラーがあると、そこで計算をやめてしまい、その他の式が計算されなくなる場合があります。この場合は循環参照を起こしている数式を正しく修正することで、正しい値を返すようになります。

Windows Vista以降でサービスから画面を表示する

Windows VISTA以降のWindowsではセッション0分離の機能により、サービスから直接UIを表示することができなくなりました。Microsoftの互換性情報では代替手段として「ユーザーログイン時に常駐プロセスを起動しサービスと通信を行う。」「WTSSendMessage関数を使用してメッセージボックス相当の表示を行う。」「CreateProcessAsUserを使用してログインユーザー権限でアプリケーションを起動する。」の三つの方法が提示されています。ここでは最後の「CreateProcessAsUserを使用してログインユーザー権限でアプリケーションを起動する。」サンプルを提示します。
サービスから画面を表示するにはRemote Desktop Services APIを使用します。
WTSGetActiveConsoleSessionId関数で物理コンソールのセッションIDを取得します。
WTSQueryUserToken関数で取得したセッションIDのユーザートークンを取得します。
DuplicateTokenEx関数で取得したユーザートークンを複製し、プライマリトークンを作成します。
CreateEnvironmentBlockを使用してユーザーの環境変数を取得します。
CreateProcessAsUser関数を使用して画面を表示するプロセスを起動します。

BOOL    bRet(FALSE);
HANDLE  hUserToken(INVALID_HANDLE_VALUE);
if (::WTSQueryUserToken(WTSGetActiveConsoleSessionId(), &hUserToken))
{
    SECURITY_ATTRIBUTES sa;
    memset(&sa, 0x00, sizeof(sa));
    sa.nLength	= sizeof(SECURITY_ATTRIBUTES);
    HANDLE	hDupedToken(INVALID_HANDLE_VALUE);
    if (::DuplicateTokenEx(hUserToken, 0, &sa, SecurityIdentification, TokenPrimary, &hDupedToken))
    {
        PVOID	lpEnvironment(NULL);
        if (::CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE))
        {
            STARTUPINFO stStartUpInfo;
            memset(&stStartUpInfo, 0, sizeof(STARTUPINFO));
            stStartUpInfo.cb        = sizeof(STARTUPINFO);
            stStartUpInfo.lpDesktop = _T("winsta0¥¥default");
            PROCESS_INFORMATION ProcessInfo;
            memset(&ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
            ::CreateProcessAsUser(hDupedToken, _T(""), (char*)(const char*)strCmd, NULL, NULL
                    , FALSE, CREATE_UNICODE_ENVIRONMENT, lpEnvironment, NULL, &stStartUpInfo, &ProcessInfo);
        }
    }
}

Hello Android 2:Hello Worldを作ってみる

・・・と言っても、HelloWorldは日本語のページが用意されています。なので、公式のHelloWorldでは書かれていない事を中心に書いていこうと思います。
AVD(仮想Android)の作成
まずはAVD(Android Virtual Device)なるAndroidの仮想OSを設定します。通常はこの仮想OS上でデバッグをおこないます。コマンドプロンプトを起動して、Android SDKのをインストールしたフォルダ配下のToolsに移動します。ここで”android create avd –target 2 –name my_avd”と入力するとAVDが作られます。パラメータ無しでandroidと指定するとGUIが起動するので、私としてはGUIを使うのがお勧めです。
GUIを起動してVirtual Devicesを選択して、Newボタンをクリックします。表示されたダイアログから、AVDの名称、Androidのバージョン、使用メモリ、画面サイズなどを指定してCreate AVDボタンをクリックします。これでAVDが作成されます。作成したAVDを選択してStartボタンをクリックすると、AVDが起動します。
作成したAVDを初めて起動する時には、相当に時間がかかります。何分と言うレベルではなく、何十分も待つ事になるので気長に待ってください。