地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【memcached】memcacehdのソケットバッファのサイズ

先日調べたソケットバッファに関する記事でmemcachedはどのくらいの値を設定してるのかと思って調べたのでメモ。

memcacehd.cでsetsockopt(2)を読んでいた

static void maximize_sndbuf(const int sfd) {
    socklen_t intsize = sizeof(int);
    int last_good = 0;
    int min, max, avg;
    int old_size;

    /* Start with the default size. */
#ifdef _WIN32
    if (getsockopt((SOCKET)sfd, SOL_SOCKET, SO_SNDBUF, (char *)&old_size, &intsize) != 0) {
#else
    if (getsockopt(sfd, SOL_SOCKET, SO_SNDBUF, &old_size, &intsize) != 0) {
#endif /* #ifdef _WIN32 */
        if (settings.verbose > 0)
            perror("getsockopt(SO_SNDBUF)");
        return;
    }

    min = old_size;
    max = MAX_SENDBUF_SIZE;

   // setsockoptの戻り値を使ってこの辺で設定値をうまいこと探索してる。
    while (min <= max) {
        avg = ((unsigned int)(min + max)) / 2;
        // 戻りが0以外ならsetsockoptは失敗となる。ハードリミットを超えて設定しようとするとエラーを返すのでそれを契機に探索を行う
        if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void *)&avg, intsize) == 0) {
            last_good = avg;
            min = avg + 1;
        } else {
            max = avg - 1;
        }
    }

    if (settings.verbose > 1)
        fprintf(stderr, "<%d send buffer was %d, now %d\n", sfd, old_size, last_good);
}

予想通りといえば予想通りだがシステム許容の最大値を取得してその値をバッファに設定している。最大値の取得に二分探索を使ってるのはこれって外から取れない値なのだろうか??

SO_RCVBUFの設定してる箇所は無さそうなので送信バッファのみ大きくしてみ模様。memcached側としてはデータを受信した時点でメモリに書き込むので正直小さかろうが関係ないからだろうか。

他にも抜粋だがsocketに関するオプションを色々設定してる模様。ソケットプログラミングは入門程度しか知らないのでこの辺は調べて行きたい。

./memcached.c:        if (setsockopt(sfd, SOL_SOCKET, SO_SNDBUF, (void *)&avg, intsize) == 0) {
./memcached.c:            error = setsockopt(sfd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &flags, sizeof(flags));
./memcached.c:                perror("setsockopt");
./memcached.c:        setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
./memcached.c:            error = setsockopt(sfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&flags, sizeof(flags));
./memcached.c:                perror("setsockopt");
./memcached.c:            error = setsockopt(sfd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
./memcached.c:                perror("setsockopt");
./memcached.c:            error = setsockopt(sfd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
./memcached.c:                perror("setsockopt");

linuxjm.osdn.jp