2 машины монтируют одну и ту же папку NFS (которая находится на одной третьей машине).
Файлы загружаются с любого клиентского сервера на это монтирование, обычно порциями. Сервер A может обрабатывать фрагмент, а затем сервер B, все с определенными начальной и конечной точками, поэтому все они отображаются в конце.
Тем не менее, было несколько случаев, когда, если вы запустите md5sum
от serverA вы получите другой результат, чем с serverB.
Хотя на самом деле файл находится на сервере NFS, и, насколько мне известно, всем клиентам должна быть отправлена только одна версия.
И со временем это не проходит.
В настоящее время я предполагаю, что это состояние гонки, связанное с тем, что фрагменты не добавляются по порядку и кэширование NFS, вы можете заставить один из серверов думать, что файл имеет определенную длину, а это не так, что вызывает много 0000 0000
дополнение, которое нужно добавить.
Итак, как же это происходит? Есть ли параметр монтирования, который мне нужно использовать, чтобы предотвратить это? Есть ли способ указать серверу NFS повторно синхронизировать файл со всеми клиентами?
И вообще как с этим бороться?
РЕДАКТИРОВАТЬ: варианты монтажа на клиентах:
machine1:~$ nfsstat -m
/mnt/dirA from <SERVER_IP>:/dirA
Flags: rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP>
/mnt/dirB from <SERVER_IP>:/dirB
Flags: rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP>
machine1:~$ cat /proc/mounts | grep <SERVER_IP>
<SERVER_IP>:/dirA /mnt/dirA nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP> 0 0
<SERVER_IP>:/dirB /mnt/dirB nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP> 0 0
machine2:~$ nfsstat -m
/mnt/dirA from <SERVER_IP>:/dirA
Flags: rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP>
/mnt/dirB from <SERVER_IP>:/dirB
Flags: rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP>
<SERVER_IP>:/dirA /mnt/dirA nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP> 0 0
<SERVER_IP>:/dirB /mnt/dirB nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255,acregmin=1,acregmax=1,acdirmin=1,acdirmax=1,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=<LOCALHOST_IP>,local_lock=none,addr=<SERVER_IP> 0 0
EDIT2: обе машины - Ubuntu 18.04, свежая установка, инструмент md5sum - версия 8.28 на обеих машинах.
РЕДАКТИРОВАТЬ3:
Я нашел эту записку, которую сохранил в файлах. Я выполнил xxd
чтобы получить шестнадцатеричный дамп с обеих машин с точки монтирования в локальную файловую систему машин. Чтобы быть уверенным, что это было снято с точки зрения отдельных машин. Как видите, согласно machine01, в файле есть пустое заполнение, но не согласно machine02.
Вот результат:
root@machine01:/home/kdguser# grep -C 5 '2ddd5000' output01
2ddd4fb0: 0a78 95ff c53e e2c4 f79a db05 0a59 d7d1 .x...>.......Y..
2ddd4fc0: 85a8 1192 26a6 a25a d741 db3c a61f e72e ....&..Z.A.<....
2ddd4fd0: 4d0b 97b6 93cc 7845 6ef4 0cca f9aa 9390 M.....xEn.......
2ddd4fe0: 9f00 bacd 707f 2398 f419 e49e 8073 67fb ....p.#......sg.
2ddd4ff0: 89f5 9450 99f5 808f 4b21 3154 f97f 1271 ...P....K!1T...q
2ddd5000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2ddd5010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2ddd5020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2ddd5030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2ddd5040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2ddd5050: ba34 fb76 5af3 69d2 9af0 4711 8a0c eae8 .4.vZ.i...G.....
root@machine02:/home/kdguser# grep -C 5 '2ddd5000' output02
2ddd4fb0: 0a78 95ff c53e e2c4 f79a db05 0a59 d7d1 .x...>.......Y..
2ddd4fc0: 85a8 1192 26a6 a25a d741 db3c a61f e72e ....&..Z.A.<....
2ddd4fd0: 4d0b 97b6 93cc 7845 6ef4 0cca f9aa 9390 M.....xEn.......
2ddd4fe0: 9f00 bacd 707f 2398 f419 e49e 8073 67fb ....p.#......sg.
2ddd4ff0: 89f5 9450 99f5 808f 4b21 3154 f97f 1271 ...P....K!1T...q
2ddd5000: c969 a259 431e 2a17 12b4 8365 07cb 5e56 .i.YC.*....e..^V
2ddd5010: fa61 327f eb63 1b13 bc30 eb4b c8f0 af14 .a2..c...0.K....
2ddd5020: 6ebe 3f79 9012 7ece 1662 e104 be19 b249 n.?y..~..b.....I
2ddd5030: 9b9c f61d 180b e92a b93b 9980 aba4 ba41 .......*.;.....A
2ddd5040: 0929 fece fc8a 5309 3883 2562 fe2a 459a .)....S.8.%b.*E.
2ddd5050: ba34 fb76 5af3 69d2 9af0 4711 8a0c eae8 .4.vZ.i...G.....
Хотя фактический файл - это тот, который виден из machine02. Но machine01 показывает кое-что еще.
EDIT4: Чтобы было ясно, длина файлов идентична, md5 отличается для каждого клиента.
Я рекомендую прочитать раздел «Согласованность данных и метаданных» страница руководства nfs.
Протокол NFS версии 3 представил «слабую согласованность кеша» (также известную как WCC), которая обеспечивает способ эффективной проверки атрибутов файла до и после одного запроса. Это позволяет клиенту помочь определить изменения, которые могли быть внесены другими клиентами.
В частности, вам нужно использовать noac
:
Когда действует noac, кэш атрибутов файла клиента отключен, поэтому каждая операция, которая должна проверять атрибуты файла, принудительно возвращается на сервер. Это позволяет клиенту очень быстро видеть изменения в файле за счет множества дополнительных сетевых операций.
Увы,
Параметр монтирования noac не позволяет клиенту кэшировать метаданные файлов, но все еще существуют гонки, которые могут привести к несогласованности кеширования данных между клиентом и сервером.
Таким образом, вам может потребоваться открыть файл с O_DIRECT
отметить если noac
не решает проблему за вас.
Протокол NFS не предназначен для поддержки истинной согласованности кэша файловой системы кластера без какой-либо сериализации приложений. Если требуется абсолютная согласованность кеша между клиентами, приложения должны использовать блокировку файлов. В качестве альтернативы приложения также могут открывать свои файлы с помощью флага O_DIRECT, чтобы полностью отключить кэширование данных.
Отказ от ответственности: Во-первых, я не использую Ubuntu. Во-вторых, я «старая школа». В-третьих, его документация, вероятно, не согласуется со мной (см. Второй отказ от ответственности).
BLUF: Вероятно, это проблема синхронизации, кеширования или буферизации.
Пояснение: в Старые времена, программа не будет сразу записывать на диск. ОС фактически отправила бы данные файла в буфер. Когда буфер был (почти) заполнен, буфер промывать на диск. Т.е. тогда содержимое буфера будет физически записано на сам диск.
Для дисковых массивов иногда контроллер диска также имеет кэш. Данные могут потенциально поступать в контроллер быстрее, чем диск может записать, поэтому они будут кэшироваться в контроллере до тех пор, пока диск не догонит их.
Для сетевого трафика данные обычно передаются пакетами. TCP / IP, нет гарантии, что пакеты будут доставлены в том порядке, в котором они были отправлены. Итак, есть буфер, который хранит пакеты и собирает их заново в правильном порядке.
Сегодня предполагается, что буферы кешируются немедленно. Раньше мы запускали sync
команда для принудительной очистки буфера.
Я вижу здесь следующие проблемы:
У каждого сервера есть «номер следующего блока», по которому он должен начать запись, когда придет очередь. Это значение могло быть не синхронизированным между сервером A и сервером B.
Кэш или буфер, возможно, записываются недостаточно быстро. Например. Сервер A должен отправить свои данные на сервер C. Сервер C должен физически записать их на диск. Сервер B должен перечитать файл с диска, прежде чем он «увидит» его.
Это означает, что на сервере B может быть дыра в данных из предыдущего сброса сервера A. И наоборот.
Сервер C, NFS-сервер, мог быть перегружен запросами на чтение / запись. Есть ли у сервера C (сервера NFS) другая контрольная сумма?
Сервер A и сервер B могут перечитывать недостаточно быстро.
Надеюсь, это даст вам некоторое представление о том, где искать ответы.
Возможные шаги по устранению неполадок: Можно ли совсем в сети запустить несколько sync
команду на каждом сервере и посмотрите, совпадают ли?
Догоняет ли файл в итоге? Вы упомянули дыру в данных.
Как видите, согласно machine01, в файле есть пустое заполнение, но не согласно machine02.
Заполняется ли заполнение недостающими данными через некоторое время (подлежит уточнению)? Если да, то у вас проблема с буферизацией или синхронизацией. В противном случае у вас гораздо более серьезная проблема со всей системой.
Можете ли вы вернуться к проблеме 2 серверов? Можно ли сделать так, чтобы только один сервер взял на себя всю запись и при необходимости переключился на другой сервер?
Есть ли в ваших конфигурациях параметры кэширования или значения времени, которые вы можете настроить?