Hatena::Diary

とあるはてな社員の日記 このページをアンテナに追加 RSSフィード

2008-11-09

技術者としての「日本語が亡びるとき」

22:13 | 技術者としての「日本語が亡びるとき」 - とあるはてな社員の日記 を含むブックマーク はてなブックマーク - 技術者としての「日本語が亡びるとき」 - とあるはてな社員の日記 技術者としての「日本語が亡びるとき」 - とあるはてな社員の日記 のブックマークコメント

日本語が亡びるとき を読みました。普段は、あまり書評らしいものは書かないのですが、いろいろ確信が得られたので、熱が逃げない内に記します。

日本語が亡びるとき―英語の世紀の中で

日本語が亡びるとき―英語の世紀の中で

この本で論じられている「日本語はこのままだと亡びる可能性がある」ということは、僕にとっては、若干背を向けたかった現実だったりします。僕は、英語が完璧にはほど遠いエンジニアの常として、なんだかんだ言って日本語をベースとした活動としています。「日本語が亡びる」ということは、それらの活動が将来的に無になってしまうことと、ほぼ同義です。

技術、特に情報科学・技術を専門としている身としては、英語が普遍語である、というのは、この本に教えられるまでもなく常識として実感しています。コンピューター関連の技術の世界では英語のドキュメントが原典で、翻訳されたドキュメントは参考程度です。コンピュータが動作するコードの文法も英語をベースとして構築されています。

とは言え、そのようなコンピューターの世界でも、良くも悪くも日本は恵まれていると思います。主要な情報は翻訳されて日本語になっていますし、日本のオリジナルの情報も、相当の質と量があります。英語が必要とされるのは、最先端を追う場合やよほどマイナーな物を扱う時ぐらいで、日本語+僅かな英語を読む能力でも半周遅れで付いていける、というのが、現在の日本の環境だと思います。

しかし、情報を発信しようとすると、今の日本の恵まれた現状でもだいぶ苦しくなります。この本に書かれているように、いくらいい物を書いても読んでくれる人は日本人+αに限定されますし、コミュニティの広がりも限定されてしまいます。オープンソースの活動でも、いいコードを書く、というのも大事ですが、書いたコードがいいコードであることをちゃんと説明できることも大事です。この説明がうまくできないと、どうしても書いたコードが受け入れられる確率が減ってしまいます。情報科学の一旦の担っている(つもりの)日本人としては、情報を発信する時には英語の圧倒的な壁を感じざるを得ません。英語を母語とする研究者/エンジニアと張り合うには、同等の成果では駄目で、より高い成果を突き付けてようやく認められるのだろう、という感覚があります。

実際、これまでも自分が技術的な文章を書く時には、できるだけ英語で書こう、と努力しています。少なくとも、まず英語で書いてみる努力をしよう、としています。自分の文章は、翻訳されることで失なわれるほど、日本語であることに依存しているとは思っていないし、むしろ、技術的な内容で勝負したいと思っています。さらに言えば、日本語に翻訳されることでなにか失われるほどの英語が書けるようになりたい、と思っています。(そんな日は来なさそうだけれども。)

僕は、日本語という言語は好きだし、日本近代文学も僅かには読んでいるし、できれば「日本語を亡びるとき」は永遠に来ないでほしい、と思っていますし、日本語を維持していこうという活動には積極的に賛同したいと思います。だけれども、1技術者として自分の将来をどちらかの言語に賭けるとしたら、やはり英語にベットせざると得ないと、これまでも思っていましたし、それがこの本を読んだことで確信に変わりました。

石川石川 2008/11/10 09:52 コンプレックスがある場合、そのコンプレックスを克服しない限り、仮に英語が使えるようになっても、コンプレックスは消えないままですよ。

http://msjames.deviantart.com/journal/19005051/

このように、海外から日本語を見ている人たちもいます。彼らは日本語ができないが、日本文化に対して強い関心をもっていて、創造的エネルギーを発信していますよ。彼らは、日本語の本を読んでいません。それとも、彼らに対しても、まずは日本語の本を読んでからという論理は成立ちますか?

プログラマーは、ソースがしっかりしていれば、十分コミュニケーションはできるはずですよ。コミュニケーションが成立しないのは、英語力ではなく、プログラミングに独創性がないからだと思います。英語圏からの関心の対象にならないからですし、欧米人ほど、独創性とパイオニアを求めています。

stanakastanaka 2008/11/10 11:39 URLはありがとうございます。興味深いですね。
ただ、今の僕の立場は、日本の「文化」を海外に広めたい、というよりは、日本の「技術」が日本語の中に閉じるのが残念、というものです。

もちろん、プログラマならコード、それ以外の人なら話したい内容がしっかりしていれば、興味を持って聞いてくれます。ただ、英語に不自由していると、興味を持ってもらうためのハードルが上昇する、という感覚です。

2008-08-11

はてなのインフラ、いまむかし @ サーバ/インフラ Tech Meeting

14:09 |  はてなのインフラ、いまむかし @ サーバ/インフラ Tech Meeting - とあるはてな社員の日記 を含むブックマーク はてなブックマーク -  はてなのインフラ、いまむかし @ サーバ/インフラ Tech Meeting - とあるはてな社員の日記  はてなのインフラ、いまむかし @ サーバ/インフラ Tech Meeting - とあるはてな社員の日記 のブックマークコメント

先週の金曜にサーバ/インフラ Tech Meetingで「はてなインフラ、いまむかし」という発表をさせていただきました。先日発売された「サーバ/インフラを支える技術」の新刊記念のイベントです。

発表内容は、OSC 2008 Kansai in Kyotoid:naoyaが発表したはてなインフラの歴史の抜粋に加えて、今後、発展させようしている方向性について話させていただきました。ちょっと30分では時間が足りず、後半はかけ足気味になってしまいました。また、機会があれば、今後の構想についてじっくり話したいものです。

資料は下にアップロードしました。

発表動画はid:cojiさんにより素早くアップロードされています。そのスピード感は見習わないといけないです。

http://techtalk.jp/2008/08/-tech-meeting.html

id:naoya:20080810:1218328035も書かかれているように、最後はサイン会でした。誰もサインしてほしいと言わなくて寒い雰囲気になるという悪夢を予想していたのですが、いい方向に裏切られて腱鞘炎になるほどのサインをさせていただくことができました。人生のピークを越えてしまった気がします。

(と書いている間にダイアリーで障害がありました。すいません、すいません。)

発表動画

動画を貼ったことがないので、試しに張ってみます。

D

D

D

D

2008-06-30

Perlプログラマのためのgdb入門(at Shibuya.pm #9 LT)

08:02 |  Perlプログラマのためのgdb入門(at Shibuya.pm #9 LT) - とあるはてな社員の日記 を含むブックマーク はてなブックマーク -  Perlプログラマのためのgdb入門(at Shibuya.pm #9 LT) - とあるはてな社員の日記  Perlプログラマのためのgdb入門(at Shibuya.pm #9 LT) - とあるはてな社員の日記 のブックマークコメント

先日のShibuya.pm #9のLightening Talkで「gdbでXS on mod_perlをデバッグ」という話をしてきました。XSを使い出すと、従来のPerl的デバッグだけでは不十分なのでgdbをうまく使って、効率的にデバッグしましょう、という話です。実は、はてな社内では1年近く前に勉強で話したネタだったのですが、ようやく公開することができました。

Shibuya.pmでは5分という枠があったのでショートver.でしたが、ここでは制限はないので、本来のロングバージョンの資料をアップします。ちょっと公開できない情報が混っていたので、xxxで隠していますが、ご了承ください。

ちなみに、Rubyとかでも似た感じでデバッグできると思うので、そちらの人も参考にしてください。長いよ!という人は、最後の「これは設定しておけ的gdb初期化マクロ」だけでもどうぞ。かなり便利です。

(資料公開が遅れて、おまたせしました > id:tokuhirom)

gdbとは

gdb = Gnu DeBugger

  • バイナリアンのたしなみ

CPUやOSのデバッガ向けの機能を使って、任意のタイミングでプロセスを止めたり、再開したり、メモリの中身を読んだり、書き換えたりできます。

Perlレベルでは、手の届かない部分を自由に触れます。

xs on mod_perlの苦労

パターン1
  • たまに動作がおかしいと言われる
  • エラーログには「segmentation fault」
  • 原因はまったく不明
  • はまる
パターン2
  • たまにhttpdが暴走する
  • サービスダウン
  • 原因はまったく不明
  • はまる

バイナリアンのデバッグ

  • 初級者: printf
  • 中級以降: gdb
    • そもそも、gdbがないと、まともにデバッグができない(特にポインタ周り)

Perlプログラマのデバッグ

かなりのベテランでも、

  • print
  • warn
  • use Carp

に留まるようです。Perl界的には、デバッガよりテスト?

perl debugger(perl -d)は、ほとんど使われてない? → あまり使われているところを見たことがありません

これまでの手法の限界

例えば...

  • httpdプロセスが突然暴走する。突然落ちる。ある日httpdプロセスが消えている。
  • 内部の挙動がたまにおかしい。

printデバッグでは追い切るのが難しい。そもそも発生条件を絞れてない -> テストを書くのも困難

限界を突破するには?

  • 発生条件を絞る
    • より深い情報を使いたい
    • いまなにが起きているのかを知りたい
  • 現象をすこしずつ追いたい
    • ステップ実行しながら、変数の変化を追いたい

それを知るための強力なツールが「gdb」

1分で分かるgdbの使い方(httpd暴走編)

  • まずは基本設定
limit core unlimited
define curinfo
  printf "%d:%s\n", my_perl->Tcurcop->cop_line, my_perl->Tcurcop->cop_file
end

define longmess
  set $sv = Perl_eval_pv(my_perl, "Carp::longmess()", 1)
  printf "%s\n", ((XPV*) ($sv)->sv_any )->xpv_pv
end

  • あ、落ちた
  • 頑張って、sshで入る(重いけど根性で)
  • ps aux | grep httpd → プロセスを特定
  • sudo gdb → gdb起動
  • attach xxxx → 問題プロセスにattach
  • gcore → 成否で分岐
gcore成功
  • どこで暴走?
bt
    • up, down, frameでmy_perlの見える位置に
curinfo
longmess
  • どういうリクエストで?
strings core.xxx
  • 出力したコアを解析
gdb httpd core.xxx
gcore失敗

メモリを消費しつくしていると、gcoreを実行するためのメモリすら確保できずに失敗することもあります。その場合でも、bt, curinfo, longmessは使えるので、それを試すことはできます。

やぱりcoreが欲しい場合は..

  • 暴走するのを待つ w/ 'watch ps -C httpd u --sort=-pcpu'
  • 暴走したら、gdbで捕まえる
  • 捕まえたら、gcore
  • うまくすれば、coreが得られる
  • だめだったら、killして始めから

暴走したら即attachするスクリプト

  • catchreckless.sh
#!/bin/bash

TARGET=httpd
while [ 1 ];
do
    psline=`ps -C $TARGET u --sort=-vsz | head -2 | tail -1`
    maxvsz=`echo $psline | awk '{print $4 * 10}'`
    pid=`echo $psline | awk '{print $2}'`
    if [ $maxvsz -gt $1 ] ;
    then
        gdb $TARGET $pid
        exit
    fi
    sleep 1
done
  • %MEMが10%を越えたら、gdbでattach
# ./catchreckless.sh 100

Cレベルのバックトレース

(gdb) bt
#0  0x00000033db08fa64 in Perl_pp_padsv (my_perl=0x92e7f0) at pp_hot.c:228
#1  0x00000033db08a00e in Perl_runops_standard (my_perl=0x92e7f0) at run.c:37
#2  0x00000033db0374d0 in Perl_call_sv (my_perl=0x92e7f0, sv=<value optimized out>, flags=4) at perl.c:2647
#3  0x0000000000444a67 in modperl_callback ()
#4  0x000000000044516e in modperl_callback_run_handlers ()
#5  0x000000000044568f in modperl_callback_per_dir ()
#6  0x000000000043f920 in modperl_response_handler_run ()
#7  0x000000000043fad9 in modperl_response_handler_cgi ()
#8  0x0000000000434b5a in ap_run_handler ()
#9  0x0000000000438012 in ap_invoke_handler ()
#10 0x000000000045e798 in ap_process_request ()
#11 0x000000000045ba20 in ap_process_http_connection ()
#12 0x000000000043bdf2 in ap_run_process_connection ()
#13 0x000000000046c18f in child_main ()
#14 0x000000000046c399 in make_child ()
#15 0x000000000046cea7 in ap_mpm_run ()
#16 0x00000000004220e4 in main ()

Perl_call_svがメソッド呼出しです。

(ちなみに、rpmで入れるとソースはインストールされません。ソースまで入れるなら、debuginfoパッケージを入れる必要があります。)

Perlレベルのバックトレース

define curinfo
printf "%d:%s\n", my_perl->Tcurcop->cop_line, my_perl->Tcurcop->cop_file
end

my_perlがperlインタプリタを示す構造体

define longmess
  set $sv = Perl_eval_pv(my_perl, "Carp::longmess()", 1)
  printf "%s\n", ((XPV*) ($sv)->sv_any )->xpv_pv
end

Perl_eval_pvで、perlのeval相当構文を実行できます。結果を$svから取り出せます。たまに、うまく取れないこともあるので注意。

Perl_eval_pv以外にもperl処理系を制御するメソッドはたくさんあります。ref. perlembed

Perlで変数を変えてみる

直接替えるとうまくいきませんでした。サブルーチンならOKのようです。

my $flag = 1;

sub set_flag {
    if($_[0]){
        $flag = 1;
    } else {
        $flag = 0;
    }
}

sub new {
    my ($class, $r) = @_;
    bless {
        r => $r,
        apr => Apache2::Request->new($r),# _apreq_options()),
    }, $class;
}

sub mode {
    my $self = shift;
    my $r = shift;
    my $apr = Apache2::Request->new($r);

    while($flag){
    }

    #return $_[0]->{apr}->param('mode');
    return $apr->param('mode');
}

無限ループで終らない。

(gdb) set $sv = Perl_eval_pv(my_perl, "set_flag()", 0)

$flagを設定することで、無限ループから抜け出せます。クラス変数なので、以後は問題なし。

ちなみに、

$flag = $_[0];

とすると、なぜか前後でDumperしないと、Segmentation faultします。使いこなすには、まだちょっと研究が必要

Cレベルのブレークポイント

(gdb) break Perl_call_sv
(gdb) clear Perl_call_sv

あたりで、Perlのメソッド呼出しごとにブレークできます。ただ、ちょっと繁雑過ぎるかも。

Perlレベルのブレークポイント

Apache::DBとの連携 w/ gdb
  • httpd.conf
<Perl>
use Apache::DB ( );
Apache::DB->init;
</Perl>

<Location />
   SetHandler perl-script
   PerlResponseHandler xxx::xxx
   PerlFixupHandler Apache::DB
</Location>
gdb /usr/sbin/httpd
(gdb) run -X -f /home/stanaka/libapreq2_test/httpd.conf

リクエストが来ると、perl debuggerが立ち上がるようになります。

  DB<2> x $r
0  Apache2::RequestRec=SCALAR(0x1002000)
   -> 11483864
  DB<3> p $r
Apache2::RequestRec=SCALAR(0x1002000)
  DB<4> $a = 1

  DB<5> p $a
1
  DB<6> b xxx:xxx
  DB<7> c
xxx::xxx(/home/stanaka/lib/xxx/xxx.pm:10):
10:         my ($class, $args) = @_;
  DB<8> s
xxx::xxx(/home/stanaka/lib/xxx/xxx.pm:11):
11:         for (qw/uri namespace/) {
  DB<8> s
xxx::xxx(/home/stanaka/lib/xxx/xxx.pm:12):
12:             croak "argument '$_' must be required" if not defined $args->{$_};
  DB<9> l
12==>           croak "argument '$_' must be required" if not defined $args->{$_};
13          }
...

\C-cでgdbへ。gdb上のcontinueで、perl debuggerへ。というように、gdb←→perl debugger間を、いったり来たりできます。

まとめ

  • 1分で分かるgdbの使い方
    • curinfo, longmess, strings coreで、情報収集
  • gdbとperlデバッガの連携で、詳細なトレース

おまけ

これは設定しておけ的gdb初期化マクロ

$ cat .gdbinit
define curinfo
printf "%d:%s\n", my_perl->Tcurcop->cop_line, my_perl->Tcurcop->cop_file
end

define longmess
  set $sv = Perl_eval_pv(my_perl, "Carp::longmess()", 1)
  printf "%s\n", ((XPV*) ($sv)->sv_any )->xpv_pv
end

define dumperany
set $sv = Perl_eval_pv(my_perl, "use Data::Dumper; Dumper $arg0",0)
printf "$arg0 = `%s'\n", $sv ? ((XPV*) ($sv)->sv_any )->xpv_pv : "cannot dump"
end

sekimurasekimura 2008/07/01 10:36 ”Apache::DBとの連携 w/ gdb”いいですね。私は debugger よく使ってますよ。コントローラとか、モデルのところのデバッグでは重宝してます。

2008-05-14

1日で作る全文検索エンジン - Building a full-text search engine in "ONE" day -

08:37 |  1日で作る全文検索エンジン - Building a full-text search engine in "ONE" day - - とあるはてな社員の日記 を含むブックマーク はてなブックマーク -  1日で作る全文検索エンジン - Building a full-text search engine in "ONE" day - - とあるはてな社員の日記  1日で作る全文検索エンジン - Building a full-text search engine in "ONE" day - - とあるはてな社員の日記 のブックマークコメント

最近、「Introduction to Information Retrieval」というStanfordの大学院向け教科書のドラフトを読んでいます。id:naoyaあたりが勉強会で読んでいる教科書です。この教科書には、効率のいい全文検索システムを作るにはどうすればいいか、という(まさに)教科書的手法が網羅的に書いてあり、そのあたりに興味がある人には、非常に興味深く読めるお勧めの本です。

ただ、面白い面白いと言っているだけでは、エンジニアとしては価値半減ですので、GW中にrubyで一日かけて実装してみました。

さすがに実装は、一日で作ったものですから、非常に素朴です。マルチバイト文字はbi-gramで、シングルバイトはスペースなどの区切り記号で認識しています。インデックスは、rubyの処理系のHashやArrayで保持しており、外部にMarshallで書き出す、というものです。検索エンジン自体はdrubyで外部から検索ができるようになっており、数百ぐらいの文書なら、それなりに動いています。

コードは以下に晒してますので、よかったら見てみてください。

http://github.com/stanaka/one-day-fulltext-search/

全文検索エンジンの肝となる、事前準備のIndexingと検索の二つを軽く解説します。二つの機能ともTokenizeというクラスに実装してみました。まず、Indexingは以下の二つのメソッド(だけ)で実装しています。マルチバイトだったら、bi-gramでtokenをどんどん切り出していき、シングルバイトだったら区切り文字でtokenを切り出しています。切り出したtokenをハッシュに突っ込んでいます。

  def add_token(token, docid, position)
    @tokens[token] ||= Hash.new
    @tokens[token][docid] ||= Array.new
    @tokens[token][docid].push position
  end

  def tokenize(str, docid)
    last_char = nil
    sb_word = nil
    position = 0
    str.each_char do |char|
      position += 1
      if char.mbchar?
        if sb_word
          add_token(sb_word, docid, position);
          sb_word = nil
        end
        add_token(last_char + char, docid, position) if last_char
        last_char = char
      else
        last_char = nil
        if char =~ /[!@\#\$\%^&*\(\)\[\]\s\'\"\;\:\.\,\/\\\|\~\>\<]/ then
          if sb_word
            add_token(sb_word, docid, position)
            sb_word = nil
          end
        else
          sb_word = '' unless sb_word
          sb_word += char
        end
      end
    end
  end

検索は、search, recuresive_search, merge_resultsの三つのメソッドで実装しています。searchで検索を受けつけ、マルチバイトの文字だったら、bi-gramで分割し各tokenをrecursive_searchで再帰的に検索し、merge_resultsで各tokenが連続していることを確認しながら、結果のANDを取得しています。シングルバイトだったら、単純にハッシュで引いた中身をそのまま返しています。

  def merge_results(result_set, new_result, offset)
    new_result_set = Hash.new
    merged_keys = result_set.keys & new_result.keys
    merged_keys.each do |key|
      positions = result_set[key] & new_result[key].map {|v| v - offset}
      if positions.length > 0
        new_result_set[key] = positions
      end
    end
    return new_result_set
  end

  def recursive_search(words, result_set = nil, offset = 0)
    word = words.shift
    if @tokens[word]
      if result_set then
        result_set = merge_results(result_set, @tokens[word], offset)
      else
        result_set = @tokens[word]
      end
      result_set = recursive_search(words, result_set, offset + 1) if words.length > 0
    end
    return result_set
  end

  def search(word)
    results = Array.new
    result_set = nil
    if word.mbchar? && word.jlength > 2 then
      last_char = nil
      words = Array.new
      word.each_char do |char|
        words.push(last_char + char) if last_char
        last_char = char
      end
      result_set = recursive_search(words)
    else
      result_set = @tokens[word]
    end
    if result_set
      #pp result_set
      result_set.each do |docid, positions|
        results.push([docid, positions])
      end
    end
    return results
  end

これだけのシンプルな実装で、ちゃんとそれなりに全文検索が動いています。gitリポジトリには、このクラスを使って、YAMLデータの中身をIndexingするfulltextsearch_indexing.rbと、drubyのサーバとして動作する全文検索エンジンfulltextsearch_server.rb、サーバに検索クエリを投げるfulltextsearch_client.rbがあります。

実際の動きを以下のサンプルデータで紹介してみます。ちなみに、bcount, scountは、それぞれブックマーク数、スター数のイメージです。

-
  url: http://example.com/1
  content: これはFull Text Searchです。
  bcount: 10
  scount: 2
  date: 2006-01-01 00:00:00 +09:00
-
  url: http://example.com/2
  content: これはFull Text Searchかもしれません。
  bcount: 0
  scount: 0
  date: 2007-01-01 00:00:00 +09:00
-
  url: http://example.com/3
  content: Full Versionになるのは、いつのことでしょう
  bcount: 2
  scount: 5
  date: 2008-01-01 00:00:00 +09:00

このサンプルデータに対して検索してみると以下のような結果が得られます。検索順は、ブックマーク数、スター数、時間の経過の三つのパラメータからスコアを付けて、計算しています。

% ruby fulltextsearch_client.rb Full
[{:url=>"http://example.com/1",
  :bcount=>10,
  :scount=>2,
  :content=>"これはFull Text Searchです。",
  :date=>Sun Jan 01 00:00:00 +0900 2006},
 {:url=>"http://example.com/3",
  :bcount=>2,
  :scount=>5,
  :content=>"Full Versionになるのは、いつのことでしょう",
  :date=>Tue Jan 01 00:00:00 +0900 2008},
 {:url=>"http://example.com/2",
  :bcount=>0,
  :scount=>0,
  :content=>"これはFull Text Searchかもしれません。",
  :date=>Mon Jan 01 00:00:00 +0900 2007}]

パラメータの重み付けは自由に変更でき、例えば、スター数を重視すると、以下のような結果が得られます。

stanaka@colinux% ruby fulltextsearch_client.rb Full 0 1 0
[{:url=>"http://example.com/3",
  :bcount=>2,
  :scount=>5,
  :content=>"Full Versionになるのは、いつのことでしょう",
  :date=>Tue Jan 01 00:00:00 +0900 2008},
 {:url=>"http://example.com/1",
  :bcount=>10,
  :scount=>2,
  :content=>"これはFull Text Searchです。",
  :date=>Sun Jan 01 00:00:00 +0900 2006},
 {:url=>"http://example.com/2",
  :bcount=>0,
  :scount=>0,
  :content=>"これはFull Text Searchかもしれません。",
  :date=>Mon Jan 01 00:00:00 +0900 2007}]

ちなみに、日本語文字列でも、ちゃんと結果が得られます。

% ruby fulltextsearch_client.rb これは
[{:url=>"http://example.com/1",
  :bcount=>10,
  :scount=>2,
  :content=>"これはFull Text Searchです。",
  :date=>Sun Jan 01 00:00:00 +0900 2006},
 {:url=>"http://example.com/2",
  :bcount=>0,
  :scount=>0,
  :content=>"これはFull Text Searchかもしれません。",
  :date=>Mon Jan 01 00:00:00 +0900 2007}]

作ってみたところ、(素朴な)全文検索エンジンを作るのは簡単で、教科書を読んだだけで作ることができます。ただ、ここから億単位の文書を読みこませても十分に早いスケールする全文検索エンジンを作るのは、当たり前ですが、相当に大変だと思います。でも、地道にやれば十分手の届くところにある、と感じます。

ともあれ、検索順位のアルゴリズムを考えるのは楽しいです。今回はブックマーク数とスター数と、記事の投稿時間をパラメータとして使ってみました。全文検索でヒットした記事に、それらの三つのパラメータから重み付けをして順位を決め、検索結果を出すというのは、非常に興味深いです。

検索順位については、普段Google「様」がPageRankをベースとしたアルゴリズムで順位を決定しているものを見ているわけですが、はてなのデータを使えば、はてなブックマークやはてなスターによって日々蓄積されている、人為的なデータをベースとして順位を決定できます。実際、はてなダイアリーの記事を対象として、両者の検索結果を比較してみると、なかなか興味深いです。

検索エンジンを自前で持つ意味というのは、Google様の価値観とは異なる自分独自の価値観を持つことができ、かつ、それが有益な場合だと思います。実際、Googleの初期のころ他の検索エンジンを圧倒してきたのは、PageRankという価値観が圧倒的に支持されたからです。それに対抗できる価値観を持つことができたら、まだ新しい検索エンジンの存在価値が出てくると思います。

ちなみに、パラメータの重み付けを少し変える度に、検索結果順がころころ変わって、日々それに一喜一憂しているSEO業者の人は大変だなぁ、と思いました。「見ろ!SEO業者がゴミのようだ!」と思ったのは、ここだけの話です。

2008-04-21

MySQL Conference 2008に行って来た

12:51 |  MySQL Conference 2008に行って来た - とあるはてな社員の日記 を含むブックマーク はてなブックマーク -  MySQL Conference 2008に行って来た - とあるはてな社員の日記  MySQL Conference 2008に行って来た - とあるはてな社員の日記 のブックマークコメント

今年もMySQL Conference 2008に行ってきました。社内向けの報告資料と雑多なメモですが、よろしければ参考にしてください。

f:id:stanaka:20070425143132j:image*1

概要

  • MySQLがSunに買収されて始めてのConference
  • 8セッション並列で、OSCONの規模にだいぶ近い
  • MySQLが扱うトラフィック量・データ量がどんどん大きくなってきており、それにどう追従するか、という観点の話が多い

買収の話とか

  • "MySQL、新機能追加は有償版の「MySQL Enterprise」だけを対象に"というのは、かなりミスリーディングな記事
  • 実体は一部のセキュリティ形の機能やnative storage engine-specific driverをMySQL Enterpriseとして出す、という話
  • Backup機能や、Falcon, Mariaといったストレージエンジンの開発では、Community ServerとEnterpriseのCode baseは統一されたままになると思う

GoogleやFacebookでのMySQL

Google
  • GoogleはInnoDB改善の専門チームがある
    • 8core, 128GBといった大きいサーバでの並列性能を改善
    • 検索システムでは使ってない
  • 思っていたより、GoogleはMySQLのヘビーユーザらしい
Facebook
  • Webサーバ 10,000台、DBサーバ 1,800台だそうな
  • 世界で一番のMySQLのヘビーユーザではなかろうか

次期ストレージエンジン

Maria
  • MyISAMの後継
    • 性能向上
    • トランザクション
    • Crash safe
    • Table lockってのは変わらなさそう
  • けっこう期待できる
Falcon
  • InnoDBの代替ではないと言っているけど、代替としか思えない
    • InnoDBはOracleだし
  • InnoDBより大規模なサーバでの性能を改善
  • Googleが改善しているInnoDBと張り合えるかどうか

memcached

  • MySQLがmemcachedを正式サポート
  • memcached in Facebook
    • マルチスレッド化、新Cクライアント、新バイナリプロトコル
    • memcached proxy
    • 20Mリクエトスト中MySQLサーバまで届くのは500K(2.5%程度)。
    • データセンター間のMySQLのレプリケーションにmemcachedとの同期処理のための追加情報を埋めている

Backup

  • MySQL 6.0でBackup周りが一新される
  • non-blocking Backupに期待

各サービスのスケール感

YouTubeは去年に比べると口が硬くて面白くありません。

How many serversNumber of DBAsHow many web serversNumber of caching servers Version of MySQL Language platform Operating System
MySQL1 Master, 3 Slaves1/10225.1.23Perl,php and bashLinux fedora
Sun2 clustered, 2 individual1.5160+85.0.21Lots of stuff (java mostly)Open Solaris
Flickr166At present 0244145.0.51Php and some JavaLinux
Fotolog140 databases on 37 instances10 instances 1 DBA7040 ( 2 on each, 80 total)?Php -> JavaSolaris 10
Wikipedia20 40 ( 2 on each, 80 total)Php, c++, pythonFedora / Ubuntu
Facebook30000 (1800 db servers)210,0008055.0.44 with relay log corruption patchPhp, python, Java and enlangFedora / RHEL
Youtubecannot say3n/a Corp. policyn/a5.0.24pythonSuSE 9
  • Facebook: 260億枚の写真、毎秒25万リクエスト(写真だけで)

ペタバイトの世界

  • Stanford Linear Accelerator Centerの人によるサイエンス方面で、以下に大量のデータが生成されているか、という話。20PBのデータベースなんて、相当にチャレンジング。
  • Moore's lawをもってしても、当面は解決が困難な問題が目白押しで楽しそう
  • Astronomy
    • Sloan Digital Sky Survey
    • 50+ PB images, 20+ PB database
  • NASA: Earth Observing system
    • 4 PB / year
  • Genomics
    • Multi petabytes

もろもろTips

  • MySQL master on DRBD
  • Backup using LVM snapshot
  • Benchmarking
    • mysqlslap他
  • Monitoring
  • 管理用ツール
    • maatkit, mysqlsla, mysqlreport, mysqldumpslow
  • DBSlayer
    • SQL QueryをJSONで返してくれるDBラッパー

まとめ

  • Sunに買収されたけど、当面は心配はいらない(たぶん)
  • 新しいストレージエンジンはけっこう期待できる。特にMaria
  • memcachedの連携が進むと、より使い勝手が良くなりそう
  • 一年に一度は世の流れを感じるのは価値がある
  • High Performance MySQL, Second Editionがもうすぐ出る → 買うべし

*1:会場も天気も去年と同じなので、写真は去年のを流用してます