write-to-newfile vs overriding: problema de desempenho

2

Eu observei uma enorme diferença entre seguir dois cenários para copiar um arquivo:

  1. Copiando um arquivo para um novo arquivo.
  2. Copiando um arquivo em um arquivo existente e sobrescrevendo-a.

Espero que as duas operações demorem o mesmo tempo para serem concluídas. Mas o primeiro cenário é muito mais rápido na prática. Eu tentei isso em dois sistemas de arquivos diferentes, obtendo o mesmo resultado. Alguma idéia de porque o primeiro cenário é muito mais rápido?

Exemplo no Linux:

$ dd bs=1024 count=1000000 if=/dev/zero of=dummyfile.txt
1000000+0 records in
1000000+0 records out
1024000000 bytes (1.0 GB) copied, 7.45639 s, 137 MB/s
$ while [ "1" == "1" ]; do time cp dummyfile.txt dummyfile2.txt ; rm dummyfile2.txt ; done

real    0m0.850s
user    0m0.003s
sys     0m0.847s

real    0m0.778s
user    0m0.000s
sys     0m0.776s

real    0m0.775s
user    0m0.004s
sys     0m0.772s

real    0m0.775s
user    0m0.003s
sys     0m0.770s

real    0m0.776s
user    0m0.008s
sys     0m0.766s
^C
$ rm dummyfile2.txt -f
$ while [ "1" == "1" ]; do time cp dummyfile.txt dummyfile2.txt ;  done

real    0m0.839s
user    0m0.003s
sys     0m0.834s

real    0m6.056s
user    0m0.005s
sys     0m1.683s

real    0m6.614s
user    0m0.002s
sys     0m1.405s

real    0m6.858s
user    0m0.003s
sys     0m1.436s

O teste EDIT: é realizado em um disco SSD. Eu observei a mesma tendência no HDD, mas a diferença é menor do que no SDD (2-3X). A página a seguir explica por que os SSDs são muito mais lentos que os HDDs em substituição:

Página da Wikipédia (computação)

    
por lashgar 16.01.2015 / 19:44

2 respostas

2

Na verdade, a cópia física leva o mesmo tempo. Mas o driver do sistema de arquivos ext4 close () espera que os dados sejam realmente gravados quando a operação é feita em um nó i existente e não espera pela operação de gravação se for feito em um novo nó. Eu fiz alguns experimentos e percebi que é o recurso ext4. Eu não vi essa diferença com a cópia em btrfs, zfs, ext3, ext.

Como posso dizer que o fechamento é uma operação demorada? strace fornece as informações:

$ strace -tt -T cp bigfile newfile
...
14:36:41.985437 open("bigfile", O_RDONLY)   = 3 <0.000009>
14:36:41.985466 fstat(3, {st_mode=S_IFREG|0664, st_size=647608649, ...}) = 0 <0.000007>
14:36:41.985495 open("newfile", O_WRONLY|O_CREAT|O_EXCL, 0664) = 4 <0.000086>
14:36:41.985602 fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 <0.000007>
14:36:41.985633 fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 <0.000008>
... a lot of reads and writes
14:36:43.584223 close(4)                = 0 <0.000009>
14:36:43.584248 close(3)                = 0 <0.000008>
...
$ strace -tt -T cp bigfile existingfile
...
14:36:52.393034 open("bigfile", O_RDONLY)   = 3 <0.000010>
14:36:52.393071 fstat(3, {st_mode=S_IFREG|0664, st_size=647608649, ...}) = 0 <0.000009>
14:36:52.393104 open("existingfile", O_WRONLY|O_TRUNC) = 4 <0.097058>
14:36:52.490211 fstat(4, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 <0.000007>
14:36:52.490278 fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 <0.000009>
... a lot of reads and writes
14:36:54.047408 close(4)                = 0 <5.346015>
14:36:59.393466 close(3)                = 0 <0.000011>
...

Note que o close (4) leva mais de 5 segundos enquanto no caso de copiar para o arquivo existente e é imediato quando um novo arquivo é criado.

Eu corro iostat para verificar o que o sistema está fazendo. A leitura do bigfile foi executada antes do teste para evitar o efeito de cache do sistema de arquivos.

# iostat sda 1 100
Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.00         0.00         0.00          0          0
sda               0.00         0.00         0.00          0          0
--------------- copy to a new file starts here -----------------------
sda              24.00         0.00      8340.00          0       8340
sda             174.00         8.00     86596.00          8      86596
sda             170.00         0.00     86020.00          0      86020
--------------- copy to a new file finishes here ---------------------
sda             177.00         4.00     90112.00          4      90112
sda             176.00         4.00     89600.00          4      89600
sda             166.00         0.00     84992.00          0      84992
sda             161.00         4.00     81920.00          4      81920
sda             157.00         0.00     78888.00          0      78888
sda              52.00         0.00     26224.00          0      26224
sda               0.00         0.00         0.00          0          0
sda               0.00         0.00         0.00          0          0
sda               0.00         0.00         0.00          0          0
--------------- copy to the existing file starts here ----------------
sda              12.00         0.00      4128.00          0       4128
sda             172.00         4.00     87040.00          4      87040
sda             180.00         4.00     91648.00          4      91648
sda             175.00         0.00     89600.00          0      89600
sda             173.00         4.00     88064.00          4      88064
sda             168.00         4.00     83532.00          4      83532
sda             159.00         0.00     81408.00          0      81408
sda             181.00         4.00     92160.00          4      92160
sda              30.00         0.00     14960.00          0      14960
--------------- copy to the existing file finishes here --------------
sda               0.00         0.00         0.00          0          0
sda               3.00         0.00        28.00          0         28

Observe que a cópia para um novo arquivo é concluída antes que os dados sejam gravados e a operação de gravação continue, embora o cp seja feito do ponto de vista do usuário.

    
por 31.01.2015 / 18:53
0

A substituição é necessária para uma operação de pesquisa ...

As permissões do arquivo devem ser lidas para saber se você pode sobrescrevê-lo (o que pode ou não ser um problema dependendo do seu sistema de arquivos). Além disso, o arquivo deve estar truncado.

Isso requer que a unidade procure a posição em que o arquivo está ..

Copiar para um novo arquivo gera novas permissões e usa os blocos livres disponíveis mais próximos para escrever e não precisa de busca.

Procure em sistemas de arquivos "copy-on-write" (como o ZFS) que não fazem isso ..

    
por 23.01.2015 / 21:15