2012年1月1日日曜日

突然の米国赴任(事前準備編)

最近、全然ブログを書いてませんでした。

どうもGoogleの検索アルゴリズムが変更となった?せいか、アクセス数が急減した為、もういいやーと投げやりになっていました。検索エンジンの独占の弊害というやつかもしれません。

で、、、実は、突然米国赴任という驚愕の話が会社から降りてきた為、また書こうかと思います。まず、私はいわゆる日本では普通の顧客常駐型のSEであり、まず米国赴任なんて話にはならないのです。会社の中でもドブ板営業、兼SEみたいな人材が米国赴任なんて話はまずなく、非常に稀なケースのようです。じゃあなんで?という話なんですが、あまり詳しくは書きません。

さて、今回は米国に赴任する場合の準備に何が必要なのかを書こうと思います。


1.パスポート取得
当然ですが、パスポートを取る必要があります。私は当然のように持っていないので立川まで家族分も含めて3回行きました。戸籍謄本等も必要、かつ、取得の際は本人じゃないとダメだったりして小さい子供がいるとかなり面倒です。


2.ビザの取得
仕事目的でXヶ月以上米国に滞在する場合にはビザが必要です。
基本的には会社がやってくれたのですが、大量の資料に何やかんやと記載が必要です。
その中には
・あなたはマネーロンダリングに関わった事がありますか?
・大量殺戮に関わった事がありますか?
等の変な質問にすべてNoで答える必要があります。
あとは自分の親の生年月日とか、自分の米国渡米歴等、家族分も含めるとかなり時間を食います。

あと、写真が必要なのですが、会社からの指定で行った某カメラ店は米国ビザフォーマットを全く分かっておらず、かなり難儀しました。また、資料をよく読んでなかったのが悪いのですが、実際の写真だけじゃなくてJPG等の電子ファイルも必要・・・であり、カメラ屋と色々やりとりしたんですが、逆に面倒臭くなった為、自分でスキャナーを買って、写真から電子ファイルを作成しました。スキャナーって買ったことなかったんですが、最近のスキャナーはすごい精度で驚きました。結構重宝するんで海外赴任となった際には安いやつを買った方がいいかもしれません。

所定の事務をこなした後、最後に面接という高い壁があります。
朝8時半に米国大使館に行く必要があり、保育園に子供を預けてる身としてはかなり厳しいものがありました。
と言いつつも8時15分には溜池山王の大使館に到着。
間に合ったと思いきや、既に大行列!
・セキュリティーチェックする人が一人しかいない
・何故かセキュリティーチェックで怒られ?たり、ごねたりする人がいたり
して遅々として進みません。
私は中に入ったのが8時45分でかなり焦りました。

その後は以下みたいな流れです。
・またセキュリティチェックを受ける
・窓口に行き資料を渡す(日本語)
番号札を渡され、電光掲示板に自分の番号が表示されれば対象の窓口に行けと言われる。
・別の窓口で指紋を取られる(米人だが何故か日本語。ものすごく軽いノリ)
・別の窓口で500ドル分の日本円を払う
・少し待つ
・別の窓口で面接が始まる(これはさすがに英語)
・終わり!みたいな紙を渡される

というわけで本当に一瞬で終わりました。
面接もかなりビビってたのですが、窓口に三人の係員がおり、一番優しそうなお姉さんにあたったおかげで、かなり気が楽、かつ質問も中学英語。
・どこで働くの?
・いつアメリカに行くの?
・あなた、マネージャ?
・いつからマネージャなの?
・子供は何人いるの?
・子供も米国に行くのよね?

・・・面接の意味あるのかなー?

その後、会社宛にビザが送付された後に、私の元に無事ビザがやってきました。

と簡単に書きましたが、ビザ取得はかなりの時間がかかるので要注意です。
また時期にもよるのでしょうが、大使館の中に入るのに15分じゃ入れなかったので、かなり早めに行くことをお勧めします。


3.健康診断
会社の規定で人間ドック受けたばかりなのにもう一回受診。
また嫁さんも会社所定のフォーマットで受けなくてはダメでかなり面倒。



4.車の売却
約6年乗った車を売却。業者に売ろうかと思ったところ、キズだらけで値段がつかず。。
なので会社の同僚に破格の安値で売却。基本はその同僚がやってくれたのでさして苦労はせず。


5.現地の情報収集
実際の職場の状況を確認の上、住む場所、学校、通勤手段等を調査する。インターネットで調査するのは簡単ですが、はっきり言って調べだしたらきりがないのです。私が行く場所は車が無いと生活は不可能。また、日本人学校がある為、子供は日本人学校に入れる事に決定。ウチの会社の規定では、住む場所は赴任後に速やかに決める必要があるが、大体の目星をつけておくことが重要。


6.持ち家をどうするか
なぜか私はマイホーム所有でした。売る事も考えましたが、今の場所が気に入っているし、どのくらい赴任するのか全く分からない為、結局賃貸に出そうという話で決着しました。ローンがあと30年残っています。。



7.引っ越しの準備
米国に送付するもの、トランクルームに預けるものを検討の上で業者と相談。
船便と航空便がどーのこーのと言われますが、船便だと一か月かかるようです。
しかし、航空便だと会社の規定でかなり物量が制限されるようで大物の家具はトランクルームに預ける事にしました。
それと、引っ越しの準備の中で家の掃除を開始。
我が家がゴミだらけである事に気づきました。
ブックオフを何往復もし、ゴミ引き取り業者にも来てもらいました。


8.銀行口座の開設
米国では銀行口座の開設が一苦労・・・と聞いたので、日本にいながらにして米国の銀行の口座が作れるUnionbankの口座を作成。基本的には東京三菱UFJ銀行が仲介してくれるのですが、資料の間違いで2回突き返されたあげくにやっと口座開設完了。ポイントは嫁さんとのジョイント口座が作れることです。嫁さんは何故か運転免許を持っておらず、作れないかなと思いましたが、健康保険証のコピーとかを送付し無事完了。
作成完了のはがきには、これを使って送金しろと東京三菱UFJ銀行からユニオンバンク宛の送金依頼書がプレ印字された状態で添付されてました。
金額だけを記載して銀行に持って行ったのですが、窓口の方は一体何の依頼書なのか理解してもらえずかなり時間がかかりました。その後UnionbankからPINの紙等が送付されてきて、ネットでログイン確認を行い、ちゃんと入金されている事を確認。


9.子供の予防接種
現地の小学校の規定だと日本よりも予防接種を受けないとダメらしい。
立川にある某クリニックで子供二人分の予防接種を二回に分けて大量接種。
子供2人が泣き叫んだ為、相当疲れました。


10.携帯電話の申し込み
KDDIモバイルで事前に携帯電話を申込み。
http://www.kddimobile.com/
赴任前に日本に携帯が送られてきて、その時点で番号も振られている為、かなり便利である。


11.英語の勉強
会社が特に用意してくれるわけではなかった為、プライベートレッスンの先生を探して特訓。
↓以下で先生を探し出して、週2回ペースでレッスン。
http://www.enjoy-lesson.com/

某英会話学校よりはかなり値段がリーズナブル+時間の融通が利くのでかなりお勧めです。私の先生はなぜかポーランド人だったが、ほぼ英語ネイティブで教えるのがとても上手。大体の場合、赴任が決まってからの時間はあまり無く、英語の勉強はあまり出来ないと思った方が良い。


12.航空券の手配
最後に赴任時の航空券/ホテルの手配。これは会社が全てやってくれた。
赴任時にはなんとビジネスクラス!だそうで。。。乗った事が無いのでちょっとドキドキします。


最後に
赴任準備をやってみて思ったのですが、
・現地の人や赴任経験者の話を聞く
・ネットでの情報収集
をやりだすとキリがない為、どこかで切り上げるべきでしょう。
人によって意見は様々であり、やりすぎると結構混乱します。

2011年4月22日金曜日

PythonからPostgreSQLに大量データのinsert(その2)

以前、PythonのPostgreSQL用のドライバがうまくインストール出来ないと記載しましたが、python-develが入って無かっただけっぽいです。

yum install python-devel

で、
① ocpgdb1.0.3
② psycopg2-2.4
③ PyGreSQL-4.0
④ pg8000-1.08
の全てのドライバがinstall可能でした。
上記はPython2.6及び、2.7で確認しましたが、2.7の場合は④のインストールがいじらないとうまくいきませんでした。(詳細はここに記載されています)

で、今回の趣旨はPythonからのBulkInsertを試してみようというものです。
driverですが、前回は④を使いましたが、今回は②psycopg2を使ってみました。
事前に、
CREATE TABLE hash ( id text PRIMARY KEY , value text );
でhashテーブルというのを作っています。

ソースは以下みたいな感じです。

------ bulk insertする実行例 ------
#!/usr/bin/env python
import csv
import psycopg2
import time

if __name__ == '__main__':
    start = time.time()
    c = psycopg2.connect(host="localhost",user="postgres",password="xxxx",database="testdb")
    i = 0
    l = []
    cur = c.cursor()
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        id = row[0]
        value = row[1]
        t = (id,value)
        l.append(t)
        i += 1
        if i % 10000 == 0:
               cur.executemany("insert into hash values(%s,%s)",l)
               c.commit()
               cur = c.cursor()
               l = []
        c.commit()
    c.close()
    print time.time()-start

上記を実行すると100万件のinsertに大体200sかかりました。

因みに1件ずつinsertするのは以下のような感じです。

------ bulk insertしない実行例 ------
#!/usr/bin/env python
import csv
import psycopg2
import time

if __name__ == '__main__':
    start = time.time()
    c = psycopg2.connect(host="localhost",user="postgres",password="xxxx",database="testdb")
    i = 0
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        id = row[0]
        value = row[1]
        t = (id,value)
        cur = c.cursor()
        cur.execute("insert into hash values(%s,%s)",t)
        i += 1
        if i % 10000 == 0:
              c.commit()
    c.commit()
    c.close()
    print time.time()-start

これを実行すると100万件のinsertに220sかかりました。
executemany()を使用してもパフォーマンス改善にはさしてつながっていません。しかし、言い方を変えると20sも改善しています。これは通信のオーバヘッド以上に処理に時間がかかっている為、改善効果が大きくは見えないという事でしょう。

前回のpg8000で実施したテストよりもだいぶ高速だった為、pg8000でももう一度試してみました。上記のソースで、
・import psycopg2のところをimport pg8000とする
・psycopg2.connect のところを pg8000.dbapi.connectとする
事でつながるようになります。結果として以前やった結果と変わらずにbulkinsertを使おうが使うまいが、1000s以上かかってしまいます。理由は全く不明ですが、バインド変数とかをpg8000だとうまく使えて無いのかな・・・?

<まとめ>
・fedoraにpostgresqlのドライバをinstallする際はpython-develを入れるのを忘れずに
・psycopg2でbulkinsertの効果を確認したが、さしたる改善効果は無かった。
・pg8000とpsycopg2で大量insertのパフォーマンスを比較すると、psycopg2の方が圧倒的に早い。

2011年4月16日土曜日

PythonからSqlite3に大量データをinsertしてみた(その2)

PythonからSqliteに大量データをinsertする際に1件ずつinsertを行うのでは無く、Bulkinsertを行ったら、どの程度高速化されるかを確認しました。Pythonに組み込まれているsqlite3クラスにはexecutemany()というメソッドが実装されていて簡単でした。

事前にsqliteでtestdbというDBを作っておいて、
sqlite> CREATE TABLE hash ( id INTEGER PRIMARY KEY , value TEXT );
でhashというテーブルを作成しておきます。
その後、neta.csvというファイルの中身をhashテーブルにinsertしていきます。

------------------------------------------------------------------------------------------
#!/usr/bin/env python
import csv
import sqlite3
import time

if __name__ == '__main__':
    start = time.time()
    c = sqlite3.connect('./testdb')
    i = 0
    l = []
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        id = row[0]
        value = row[1]
        t = (id,value)
        l.append(t)
        i += 1
        if i % 200000 == 0:
            c.executemany('insert into hash (id,value) values(?,?)',l)
            c.commit()
            l = []
    c.commit()
    c.close()
    print  time.time()-start
------------------------------------------------------------------------------------------

上記を実行したところ、13sで100万件のinsertが完了しました。
以前、1件ずつやった場合だと、27sだったので約2倍の高速化につながりました。

2011年4月9日土曜日

PostgreSQL9.0.3 のpsqlが使えなくてがっかりした

最近PostgreSQLを使ってなかったので、最新版(9.0.3)をFedora13(32bit)にinstallしてみました。尚、PostgreSQLのlinux版はEnterpriseDB社のページからダウンロードするように促される為、そこからファイルを落としてインストーラーを実行します。

インストール自体は何の問題がありませんでしたが、createdbを実行した後にpsqlコマンドにて軽く接続しようとすると以下のエラーが出て、全くつながりません。
--------------------------------------
-bash-4.1$ psql testdb
Password:
psql (9.0.3)
Type "help" for help.

Cannot read termcap database;
using dumb terminal settings.
Aborted (core dumped)
--------------------------------------

はっ?

何か環境設定が悪いのかなと思ったが、特に悪いところは見当たらない。
ので調べると、どうやら既知のバグのようである。

BUG #5807: psql fails to launch with "Cannot read termcap database; using dumb terminal settings. Aborted"

尚、対象のBUGの環境はUbuntuとだけ記載されている。9.0.2から中身が変わっていて出るようになったのだろうとの事。

また、この話題ではPostgreSQLのMLは盛り上がって無かった。
Redhat とか CentOSだと問題の無い話なんでしょうか。

肝心の解決方法はさらっととしか記載が無かったし、9.0.3でも改善していないので少しがっかりですが、

LD_PRELOAD=/lib/libreadline.so.6

を追加したらうまくいく・・・との事。
実際これでうまくいきました。

しかし、PostgreSQLのMLの議論では以下のようにありました。

There was a change in 9.0.2 to use libedit instead of readline for this (readline is GPL, which is not acceptable to some people who wish to use Postgres in other products).

つまり、9.0.2からはreadlineを使わないように修正したんだけど、回避方法はreadlineを無理やり使おう・・・という事のように読み取れます。

全般的に何だかなーというところです。

2011年4月3日日曜日

PythonでMongoDBに大量のデータをinsertしてみた(その2)

以前MongoDBに大量データをinsertしてみましたが、まとめてinsertした場合、どの程度効果があるのか確認してみました。MongoDBは最新版のv1.8.0です。

まず、MongoDBを起動します。

./mongod --dbpath datapath --logpath logpath --fork

PyMongoというPython用ドライバをinstallする際に以下のようなエラーになりましたが、一応インストール自体は終わったので問題無かな・・と思います。
**************************************************************
WARNING: The pymongo._cmessage extension module could not
be compiled. No C extensions are essential for PyMongo to run,
although they do result in significant speed improvements.

Above is the ouput showing how the compilation failed.
**************************************************************

その後、以下のPythonコードを実行します。いつものように100万行のCSVファイルを1件ずつ読み込み、CSVに記載してある2列をそれぞれ、id列、value列として、hashコレクションにinsertしていきます。
-----------------------------------------------------------
#!/usr/bin/env python
import csv
import pymongo
import time

if __name__ == '__main__':
    start = time.time()
    L=[]
    cnt = 0
    c = pymongo.Connection()
    db = c.testdb
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
  D = {}
  D["id"] = row[0]
  D["value"] = row[1]
  L.append(D)
  cnt += 1
  if cnt % 1000 == 0:
   db.hash.insert(L)
   D={}
   L=[]
  print time.time()-start
-----------------------------------------------------------
実行時間は96sでした。

また、今回改めて1件ずつinsertするやり方も確認しました。
-----------------------------------------------------------
#!/usr/bin/env python
import csv
import pymongo
import time

if __name__ == '__main__':
    start = time.time()
    D = {}
    c = pymongo.Connection()
    db = c.testdb
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
  D["id"] = row[0]
  D["value"] = row[1]
  db.hash.insert(D)
  D={}
 print time.time()-start
-----------------------------------------------------------
実行時間は230sでした。

つまり、1000件ずつまとめてinsertする方が2倍以上高速に動作しているようです。

因みにですが、MongoDBv1.8からジャーナルモードをサポートしているようです。RDBのように、変更履歴を先にLogファイルとして書き出し、耐障害性の向上を目指しているようです。そうすると、パフォーマンスは落ちるのだろうなーと思って実験してみました。

ジャーナルモードをONとするには起動の際にオプションで指定します。
./mongod --dbpath datapath --logpath logpath --journal --fork

結果だけ言うと、パフォーマンスは1件ずつinsertした場合でも1000件まとめてinsertした場合でもジャーナルモードで無い場合とほとんど変化ありませんでした。どうもMongoDBでの実装ではinsert毎にDISKに書き出しているようでは無いようです。

---以下、manualの抜粋
MongoDB performs group commits (batch commits) when using the --journal option. This means that a series of operations over many milliseconds are committed all at once. This is done to achieve high performance.

つまり、、journalモードと言ってもinsertしたデータが必ず保護されるという訳では無くて、耐障害性がjournalモードで無い場合よりも、"ある程度"向上するだけ。という事かなと思いました。

2011年3月29日火曜日

PythonからRedisに大量データをsetしてみた

前回memcachedを試しましたが、最近ではredisというKVSがあるようなのでredisで実験してみました。installについて言うと何のダウンロードしてmakeするだけで問題無く完了。Python用ドライバも何の問題も無くinstall出来ましたので割愛します。(OSはFedora13)

redisの起動は以下です。
./redis-server &

Pythonのコードは以下の通りです。いつものようにCSVファイルから大量のネタを読み込み、100万件のsetを行います。
---------------------------------------------------------
#!/usr/bin/env python
import csv
import redis
import time

if __name__ == '__main__':
    cnt=0
    start=time.time()
    r = redis.Redis()
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        r.set(str(row[0]),row[1])
    print time.time()-start
---------------------------------------------------------
実行してみると、100万件のsetに112sかかりました。

尚、mset()を使用した場合の結果は以下です。
---------------------------------------------------------
#!/usr/bin/env python
import csv
import redis
import time

if __name__ == '__main__':
    cnt=0
    d={}
    start=time.time()
    r = redis.Redis()
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        d[str(row[0])] = row[1]
        cnt = cnt+1
        if cnt % 1000 == 0:
            r.mset(d)
            d={}
    print time.time()-start
---------------------------------------------------------
これは約10sで完了しました。今までの自己ベスト!です。

redisはmemcachedと違ってクライアントツールが入っていてsqlplusとかpsqlとかに慣れてる人にはうれしい限りです。また大量のコマンドが用意されていたり、レプリケーションが出来たり、データの保存(=DISKへの同期)が簡単に出来たりと、memcachedに満足出来なかった人には使ってみる価値がありそうな気がしました。

HTTPHeaderの"Server"をいろいろ確認してみた (NYダウ編)

HTTPHeaderのServerをNYダウを構成している銘柄で確認してみました。
前回と同じく、英語の社名でgoogleで検索し、1位に表示されたものを確認してます。

アルコア   Microsoft-IIS/6.0
アメリカン・エキスプレス IBM_HTTP_Server
ボーイング SUN-ONE-Web-Server/6.1
バンク・オブ・アメリカ SUN-ONE-Web-Server/6.1
キャタピラー IBM_HTTP_Server
シスコシステムズ Apache/2.0
シェブロン     Microsoft-IIS/6.0
デュポン     Apache
ウォルト・ディズニー・カンパニー Microsoft-IIS/6.0
ゼネラル・エレクトリック  Apache/2.2.14(Unix) mod_jk/1.2.25 mod_ssl/2.2.14 openssl/0.9.8o
ホームデポ IBM_HTTP_Server/2.0.47.1-PK65782 Apache/2.0.47(Unix)
ヒューレット・パッカード Apache
アイ・ビー・エム IBM_HTTP_Server
インテル IA Web Server
ジョンソン・エンド・ジョンソン IBM_HTTP_Server
JPモルガン・チェース JPMC1.0
クラフト・フーズ Microsoft-IIS/6.0
コカ・コーラ IBM_HTTP_Server
マクドナルド Apache/2.0.54
スリーエム IBM_HTTP_Server
メルク Apache
マイクロソフト Microsoft-IIS/7.5
ファイザー  "-"
P&G Apache
エーティーアンドティー Apache
トラベーズ Microsoft-IIS/6.0
ユナイテッド・テクノロジーズ Microsoft-IIS/6.0
ベライゾン・コミュニケーションズ Microsoft-IIS/6.0
ウォルマート・ストアーズ Apache/2.2.15
エクソンモービル Microsoft-IIS/6.0

Microsoftが9社で、IBM社が7社となりました。
この数字は日本よりも多そうです。まあNYダウが30社という比較的少ない銘柄数で構成されている関係でTOPIXの構成銘柄よりもかなり大きい会社が多く、単純な比較は難しそうですが。しかし、Server名を隠しているのはファイザー社のみであり、その他の会社は全く隠していません。こうなると、私が監査で指摘されたServerは隠した方が良いというのはそもそも日本のセキュリティ監査する人だけが言ってるの?と疑問に思えてしまいます。

気になったのは以下です。
インテル・・・IA Web Server でした。確かに同社はいろんなハードベンダと親密なので特定の企業の商品を使うのはまずそうですが。。。"Apache"とかでいいんじゃないのかな。
マイクロソフト・・・Microsoft-IIS/7.5 でした。 バージョンは最新?っぽいです。同社は自社製品の最新版を自社のHPに使用しており、まるで、他社に最新バージョンにあげるように催促している?ようにさえ感じます。

繰り返しになりますが、Server名を隠している企業は1社のみでした。あまり気にしなくていいって事なんでしょうね。。