lighty的生活

lighty 开发者博客

多线程 Stat()

作为一个概念验证,我实现了一个多线程 stat() 调用。目前这有点像一个“hack”,但当我查看性能数据时,它看起来很有前景。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.00    0.00   26.60   68.40    0.00    0.00

Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          0.00   0.60 66.90  1.60 13019.20   22.40     6.36     0.01   190.39     6.10   88.20  14.49  99.28
sdb          0.00   0.60 66.60  1.60 13061.60   22.40     6.38     0.01   191.85    14.09  208.82  14.67 100.04

blog.lighttpd.net/articles/2007/01/27/accelerating-small-file-transfers 中,我们尝试了同样的方法,但没有使用异步 stat() 并且使用了 fcgi-stat-accel。通过多线程 stat(),我将代码移入了 lighttpd 自身,这减少了外部通信,并使所有内容都在 lighttpd 自身内部进行管理。

name              Throughput  util% iowait%
----------------- ------------ ----- ------------
no stat-accel     12.07MByte/s 81%  
stat-accel (tcp)  13.64MByte/s 99% 45.00%
stat-accel (unix) 13.86MByte/s 99% 53.25%
threaded-stat     14.32MByte/s 99% 68.40%

(越大越好)

实现

在 stat_cache.c 中,我启动了一个单独的线程来处理 stat() 调用,确切地说,是4个线程。

stat_cache_get_entry() 检查其缓存,以确定该文件是否已知。如果未知,它将文件名推入 stat_cache_queue 并返回 HANDLER_WAIT_FOR_EVENT。stat_cache_queue 的另一端是4个 stat() 线程之一,它运行 stat() 并将连接推回 joblist_queue。在主循环中,就在 poll() 调用启动的地方,现在是此队列的处理程序,它会激活此队列中的所有连接。

通过这种方式,我们使 stat() 调用本身异步化,并可以保持代码的其余部分不变。到目前为止,我们只将 inode 放入 fs-buffers 中,就像其他示例一样,我们没有在线程中处理完整的 stat-cache 更新。

gpointer *stat_cache_thread(gpointer *_srv) {
        server *srv = (server *)_srv;
        stat_job *sj = NULL;

        /* take the stat-job-queue */
        GAsyncQueue * inq = g_async_queue_ref(srv->stat_queue);
        GAsyncQueue * outq = g_async_queue_ref(srv->joblist_queue);

        /* get the jobs from the queue */
        while ((sj = g_async_queue_pop(inq))) {
                /* let's see what we have to stat */
                struct stat st;

                /* don't care about the return code for now */
                stat(sj->name->ptr, &st);

                stat_job_free(sj);

                g_async_queue_push(outq, sj->con);
        }

        return NULL;
}

lighttpd

请注意,我们不接受发布超过3个月的帖子的评论! 另外,请使用我们的 bug 追踪器报告 bug,并使用我们的 IRC 频道 #lighttpd@libera 进行交流。

« 加速小文件传输 更多多线程 I/O »