V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
yjsslab
V2EX  ›  Linux

/dev/null 的原理是什么?大量写入会影响系统性能吗?

  •  
  •   yjsslab · 2015-04-13 20:41:56 +08:00 · 9094 次点击
    这是一个创建于 3299 天前的主题,其中的信息可能已经有所发展或是发生改变。
    第 1 条附言  ·  2015-04-14 09:14:02 +08:00
    找到一个解释:https://bbs.archlinux.org/viewtopic.php?id=137861

    It's all implemented via file_operations (drivers/char/mem.c if you're curious to look yourself):

    ```
    static const struct file_operations null_fops = {
    .llseek = null_lseek,
    .read = read_null,
    .write = write_null,
    .splice_write = splice_write_null,
    };
    ```

    write_null is what's called when you write to /dev/null. It always returns the same number of bytes
    that you write to it:

    ```
    static ssize_t write_null(struct file *file, const char __user *buf,
    size_t count, loff_t *ppos)
    {
    return count;
    }
    ```

    That's it. The buffer is just ignored.


    写时竟然还 return 一个 size !
    29 条回复    2015-04-15 10:02:14 +08:00
    bellchu
        1
    bellchu  
       2015-04-13 21:30:44 +08:00   ❤️ 9
    /dev/null类似一个黑洞,写入任何东西都会返回成功,但是实际写入数据随即被丢弃。

    /dev/null的io只是软件层面的,实际没有存储的io动作。但是既然是软件层面的,就会有userspace到kernel的system call,会耗费相当多的CPU和内存。

    因为传入/dev/null的数据几乎是在其被从软件传出的同时被丢弃的,所以传输的速度基本没有延迟,CPU占用率基本会迅速被占满。
    bellchu
        2
    bellchu  
       2015-04-13 21:34:46 +08:00   ❤️ 3
    rming
        3
    rming  
       2015-04-13 21:44:14 +08:00   ❤️ 1
    好像,貌似,记得,有人说过这个问题,在 C 的实现中,是直接使用的 return
    julyclyde
        4
    julyclyde  
       2015-04-13 21:52:33 +08:00   ❤️ 1
    @rming 这个不存在所谓在C的实现中的说法。虽说内核都是C写的,但这事和语言没关系
    tabris17
        5
    tabris17  
       2015-04-13 22:10:09 +08:00
    会有系统调用,所以开销也不算小
    rming
        6
    rming  
       2015-04-13 22:11:26 +08:00
    @bellchu 说的很对
    rrfeng
        7
    rrfeng  
       2015-04-13 22:18:21 +08:00   ❤️ 1
    @bellchu

    这个实验说明了 yes 能使 CPU 使用率增加到 100%。
    ryd994
        8
    ryd994  
       2015-04-13 22:36:46 +08:00
    @bellchu 这只是yes本身的开销而已吧……
    不能认为是/dev/null的
    tianice
        9
    tianice  
       2015-04-13 23:13:05 +08:00
    loading
        10
    loading  
       2015-04-13 23:13:53 +08:00 via Android
    不是你写到哪,写这个动作就耗资源,只是io部分少很多。
    bellchu
        11
    bellchu  
       2015-04-14 06:34:02 +08:00
    @ryd994 对哦,那换一个往null写0的,更贴切点
    cat /dev/zero > /dev/null
    bellchu
        12
    bellchu  
       2015-04-14 06:55:11 +08:00
    @rrfeng 这个实验也说明了频繁写入/dev/null同样会消耗资源影响性能,而不会像很多人想象的输出到null的就不耗费任何资源,但实际上CPU的开销是一样的。

    如果纠结yes命令的话。就换cat /dev/zero > /dev/null,其实效果是一样的,只不过一个是不断输出y,一个是不断输出0.

    我的本意只想表达:把/dev/null当成一个0延迟的IO设备,当IO没有延迟的时候,CPU会成为最大的系统瓶颈,CPU会因为无法及时处理排队的数据而满负载。
    ryd994
        13
    ryd994  
       2015-04-14 07:48:51 +08:00 via Android   ❤️ 1
    @bellchu 那就变成cat的开销了……
    不过到null没开销这个肯定不可能,系统调用是少不了的。不过有多大开销就很难说了,如果只是百分之一/千分之一,认为可以忽略也没什么。
    bellchu
        14
    bellchu  
       2015-04-14 08:44:10 +08:00 via iPhone
    @ryd994 楼主和我说的都是写入null造成的开销,不能单纯说是一个进程的开销或者是null的开销

    这类似于讨论网络 A发送包给B 当A到B的延迟很高时会不会性能下降 当A到B基本无延迟时会不会有性能下降。还有性能下降的程度和速度。当量达到一定程度的时候,例如A有无数个副本同时发送数据给B的时候,一定量时B就瘫痪了,ddos成功。

    就像你所说百分之一千分之一的开销基本可忽略,所以很多人喜欢把null当成焚化炉,把垃圾输出全丢null,不占用存储,不消耗io。现代系统的大多数应用的性能瓶颈都是io。

    歪楼了...
    bellchu
        15
    bellchu  
       2015-04-14 09:06:43 +08:00 via iPhone
    @ryd994 或者换句话说,百分之一千分之一的量不能算是大量。大数据时代要机器所产生的数据很简单就能“大量”。

    可以参照keen.io
    ryd994
        16
    ryd994  
       2015-04-14 09:15:41 +08:00 via Android
    @bellchu 即使是yes这样的程序,生成这么多数据的开销也比null丢弃这么多的大。那么忽略null的开销就是合理的。
    这时候需要检讨的不是为什么输出到null,而是为什么平白无故生成这么多无用的数据。这么多数据,无论输出到哪里都是浪费。
    这就像listen lo和用socket的区别。用loopback固然比用sock开销大,不过实际上可以忽略。倒不如考虑一下怎么减少不必要的进程间数据交换。
    yjsslab
        17
    yjsslab  
    OP
       2015-04-14 09:17:08 +08:00
    所以,没有实际的 IO 发生,只是 return count 的开销。
    yjsslab
        18
    yjsslab  
    OP
       2015-04-14 09:18:21 +08:00
    谢谢楼上各位。
    wizardoz
        19
    wizardoz  
       2015-04-14 09:29:15 +08:00
    要是写的时候不返回size的话,应用程序岂不是认为没有写进去进而重复写同一个内容?
    bellchu
        20
    bellchu  
       2015-04-14 09:32:08 +08:00
    @ryd994 你说的都对,但是你没考虑到垃圾达到一定程度的时候的问题。

    http://devnull-as-a-service.com/
    Admstor
        21
    Admstor  
       2015-04-14 09:37:56 +08:00
    我有时候会把暂时不需要的日志指向null,需要的时候再指向别的地方...
    bellchu
        22
    bellchu  
       2015-04-14 10:03:41 +08:00
    bellchu
        23
    bellchu  
       2015-04-14 10:18:25 +08:00
    @wizardoz 有返回的,输出多少就返回多少
    static ssize_t write_null(struct file *file, const char __user *buf,
    size_t count, loff_t *ppos)
    {
    return count;
    }
    fxxkgw
        24
    fxxkgw  
       2015-04-14 16:15:02 +08:00
    这个一般都是在脚本里面用的吧,特别是一些crontab定时器中执行的脚本,大部分作用是把无用或出错信息不显示。
    如果考虑到使用的情况,将打印显示到界面的资源消耗量应远大于输入到/dev/null 所以个人感觉可以放心使用。
    vonnyfly
        25
    vonnyfly  
       2015-04-14 16:54:47 +08:00   ❤️ 1
    这个return size一定要,不要的话,用户态write会返回失败。以前写驱动的时候这里返回值写0,导致用户态write失败。
    ElmerZhang
        26
    ElmerZhang  
       2015-04-14 18:33:18 +08:00   ❤️ 2
    write系统调用消耗的CPU很少了
    ryd994
        27
    ryd994  
       2015-04-14 23:35:06 +08:00
    @bellchu 26楼
    bellchu
        28
    bellchu  
       2015-04-15 09:48:31 +08:00
    @ryd994 这不是正好证明我的理解是正确的么。无IO或无延迟,大量system call积聚造成CPU占用率飙升。

    BTW,昨天去楼下苹果店用这些命令给新Macbook烤机,开了四个线程的yes,CPU 100%,无风扇的机器居然不是很烫。。。。有点想买了,除了他那个纠结的键盘之外。
    bellchu
        29
    bellchu  
       2015-04-15 10:02:14 +08:00
    @bellchu 再BTW,yes是纯输出的命令,而/dev/null是write only的设备。所以用yes才能演示楼主所说的大量写入的情况。

    cat /dev/zero首先是从/dev/zero读取,然后写入/dev/null。所以system call的数量是read/write各占一半。

    /dev/zero /dev/random /dev/null都是上世纪创造的东西了,现在很多人都在想怎么改良它们。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5471 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 01:25 · PVG 09:25 · LAX 18:25 · JFK 21:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.