Googleが世界の電力を食いつぶす日

今日4月22日はアースデー。ということで、このままの勢いでインターネット上にデータがあふれるとしたら、一体いつGoogleは世界の電力を食べつくしてしまうのだろう?、というあり得なさそうで、でもひょっとしたらあるかも、という計算をしてみました。

まずは、世界の総発電量を確認。
電気事業連合会発行の、世界の電気・日本の電気によると、世界の電力消費量は、2003年に15兆kwh(キロワットアワー)だそうです。

さらに今後の予測はこんな感じ。

さて、それでは一体Googleはどれだけの電力を年間に消費しているのでしょうか?これは少し計算をしてみなければならないので、Googleを支える技術からデータと計算を拝借してみます。

2004年の上場時に5万台前後、2007年時点では50万台前後という、う・わ・さ、があるそうです。どちらも梅田氏の情報らしく、公開資料からかいま見えるGoogleのコンピュータシステムと同氏のブログエントリー、Googleの「情報発電所」はいま何台?、から推測できます。

そして、1台のサーバーが消費する電力を120w、24時間稼動、さらに冷房等で約半分の追加電力消費があるとすると、1台のサーバーが年間に消費する電力量は以下のようになります。

120w * 24 * 1.5 * 365 = 約1500kwh

それでは50万台では?

1500kwh * 500,000 = 788,400,000kwh

約8000億kwh!!!

2003年に15兆kwh、2010年の電力消費量予測が20兆kwhだと考えると、2007年は17兆kwhぐらいだと思われる。だとすると、2007年における世界の電力消費量に占めるGoogleのシステム消費量の割合は、

800 / 17,000 * 100 = 4.7%

5%!?

計算間違いなのを祈る・・・。さて、それではデータの増加量から今後のサーバーの増加量を予測し、既存のテクノロジのままではいつGoogleが世界の電力を食いつぶしてしまうのか計算してみる。

So much data, relatively little spaceによると、世界のデータ量は、2003年に5エクサバイト(exaは10億ギガ)、同様の測定法でIDCのデータを修正すると2006年には40エクサバイトだったそうだ。線形(比例して)で増加していないので単純に比較はできないが、サーバーが3年間で10倍に増えたのに対して、データは同じく3年間で8倍。実際には集計に含まれていないデータのことなどを考えると、Googleサーバーの伸びとデータの伸びはほぼ同じようだと言っていいだろう。

IDCによると、これは少し集計法が異なるのだが、2007年の161エクサバイトから、2010年には988エクサバイトになるというので、次の3年間で6倍になる予測だ。となると、Googleのサーバーは300万台、電力消費量は約5兆kwh!!!となる。2010年の世界の電力量見通しは、約20兆kwh。ということで、25%がGoogleに食われることになる。

いつ食いつぶすか?これ以上の予測は根拠が薄いので難しいが、少なくとも既に相当の割合を消費していて、消費量が供給量の伸びより大幅に大きいことを考えると、2015年から2020年には、電力クライシス、またはGoogle電力なるものが登場していても、不思議はない。

*でも普通に考えておかしい。電力会社の総売上の5%をGoogleが払っているとはとても思えない。サーバーは常に最大電力を消費しないし、平均10%ぐらいだとしたら、0.5%とかになるのかも。

ニッポン泥棒

大沢在昌の「ニッポン泥棒」という小説がある。少し前のものだが、文春文庫から単行本で新刊として、先月再発売されている。

この中で出てくる世界を変えるソフト、ヒミコ、を各国の諜報機関などが狙い、それぞれの思惑が渦巻き、物語が展開されていく。

実は、現実の世界でそういうのをやろうとしているベンチャーがある、といったら驚くだろうか。

さらに信じられないことに、そこの海外投資家用資料に、私のプライベートブログが掲載されていた。ちなみにこれは全くの偶然だ。

そして昨日、その会社に参加することになった。

事実は小説より奇なり。

嘘をつくコンピュータ2

明日の掲載に間に合うようにと、「嘘をつくコンピュータ2」を仕上げて提出したところ、「嘘をつくコンピュータ」すごい人気でしたとのこと。私には思いつかなかった過激なタイトルは編集者の方のアイデアです。

謎解きとなるパート2、お楽しみに!

こちらに掲載されました)

fdatasync()でデータベースの性能を向上させる

データベースの更新(追加・更新・削除)性能は、コミットの性能に大きく依存するといって過言ではありません。これはdb4oも例外ではありません。というのも、今日のコンピューターでは、いろんな層でバッファリングされていますが、コミット時にだけ、確実にハードディスクにアクセスしなければならないタイミングがあるからです。(どうしてハードディスクへのアクセスがそんなに問題かはこちらのコラムを参照)

抜本的にデータベースの性能をアップするのは大変な作業ですが、データベースをそのままで、このコミット性能を向上させる方法があります。

POSIX互換のOSでは、fsync()だけでなく、fdatasync()も提供されています。これは、ファイルの更新日時などのメタデータを書き込まないようになっています。通常デフォルトではデータベースからの呼び出しはfsync()になるので、それをこのfdatasync()に変えるだけで、通常10-20%程度の性能向上が得られます。

このテクニックはdb4oにも応用可能です。db4oはIoAdapterというアダプターでI/O操作を抽象化していますので、ここからJNIでPOSIXのfdatasync()を呼び出せばいいのです。

以下は簡単なサンプルです。IoAdapterについてはこちらにチュートリアルがあります。

Code:

#include <jni.h>
#include "LinuxIoAdapter.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
/*
* Class:     LinuxIoAdapter
* Method:    openFile
* Signature: (Ljava/lang/String;ZJ)J
*/
JNIEXPORT jint JNICALL Java_LinuxIoAdapter_openFile
  (JNIEnv *env, jclass jc, jstring path, jboolean lockfile, jlong initiallength)
{
    printf("openFile\n");
    const jbyte *filename = (*env)->GetStringUTFChars(env, path, NULL);
 
    if(filename == NULL){
        return 0; // OutOfMemoryError or NULL value
    }
 
    int fd = open(filename, O_RDWR|O_CREAT, 0644);
 
    if(fd < 0){
        printf("open failed\n");
    }
 
    (*env)->ReleaseStringChars(env, path, NULL);
 
    return fd;
 
}
 
/*
* Class:     LinuxIoAdapter
* Method:    closeFile
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_LinuxIoAdapter_closeFile
  (JNIEnv * env, jclass jc, jint handle)
{
    printf("closeFile\n");
    if(close(handle) < 0){
        printf("close failed\n");
    }
 
}
 
/*
* Class:     LinuxIoAdapter
* Method:    getLength
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_LinuxIoAdapter_getLength
  (JNIEnv *env, jclass jc, jint handle)
{
    struct stat st;
    fstat(handle, &st);
    return st.st_size;
}
 
/*
* Class:     LinuxIoAdapter
* Method:    read
* Signature: (J[BI)I
*/
JNIEXPORT jint JNICALL Java_LinuxIoAdapter_read
  (JNIEnv *env, jclass jc, jint handle, jbyteArray bytes, jint length)
{
    
    jbyte buf[length];
 
    ssize_t n = read(handle, &buf, length);
 
    if(n != length)
        printf("read failed: %i->%i", length, n);
 
    (*env)->SetByteArrayRegion(env, bytes, 0, length, buf);
 
    return n;
}
 
/*
* Class:     LinuxIoAdapter
* Method:    seek
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_LinuxIoAdapter_seek
  (JNIEnv *env, jclass jc, jint handle, jlong pos)
{
 
    lseek(handle, pos, SEEK_SET);
}
 
/*
* Class:     LinuxIoAdapter
* Method:    sync
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_LinuxIoAdapter_sync
  (JNIEnv *env, jclass jc, jint handle)
{
    fdatasync(handle);
    //fsync(handle);
}
 
/*
* Class:     LinuxIoAdapter
* Method:    write
* Signature: (J[BI)V
*/
JNIEXPORT void JNICALL Java_LinuxIoAdapter_write
  (JNIEnv *env, jclass jc, jint handle, jbyteArray bytes, jint length)
{
    jbyte buf[length];
 
    (*env)->GetByteArrayRegion(env, bytes, 0, length, buf);
 
    ssize_t n = write(handle, &buf, length);
 
    if(n != length)
        printf("read failed: %i->%i", length, n);
}
Free Blog Themes and Free Blog Templates