Я посмотрел на этот вопрос и этот вопрос , но они, кажется, не обращаются к симптомам, которые я вижу.
У меня есть большой файл журнала (около 600 МБ), который я пытаюсь передать по сотовой сети. Потому что это файл журнала он просто добавляется к (хотя это на самом деле в SQLite базе данных только с INSERT выполняется, так что это не совсем так просто, но за исключением последней страницы 4K (или , может быть, несколько) файл каждый раз идентичен. Важно, чтобы только изменения (и любые контрольные суммы, которые необходимо передать) действительно отправлялись, потому что соединение данных измеряется.
Тем не менее, когда я выполняю тестирование по неизмеренному соединению (например, бесплатную точку доступа Wi-Fi), я не вижу ускорения или снижения скорости передачи данных, наблюдаемой или сообщаемой. По медленному WiFi-соединению я вижу порядка 1 МБ / с или меньше, сообщая, что передача займет около 20 минут. По быстрому Wi-Fi-соединению я вижу равномерную более быструю скорость, но нет сообщения об ускорении, и вторая попытка передачи (которая теперь должна быть быстрее, потому что два файла идентичны) теперь показывает какую-то разницу.
Используемая мной (очищенная для удаления конфиденциальной информации) команда:
rsync 'ssh -p 9999' --progress LogFile michael@my.host.zzz:/home/michael/logs/LogFile
Вывод, который я получаю в конце, выглядит так:
LogFile
640,856,064 100% 21.25MB/s 0:00:28 (xfr$1, to-chk=0/1)
Там нет упоминаний о каком-либо ускорении.
Я подозреваю, что проблема может быть одной из следующих:
- Я пропускаю некоторые опции командной строки. Тем не менее, перечитывание справочной страницы говорит о том, что дельта-переносы включены по умолчанию: я вижу только варианты их отключения.
- Я использую rsync через ssh (даже на нестандартном порту), поскольку сервер находится за брандмауэром, который разрешает только ssh. Я не видел ничего явно говорящего, что дельта-передачи не будут работать, если демон rsync не запущен. Я попытался использовать нотацию «::» вместо «:», но на странице руководства не очень ясно, что такое «модуль», и моя команда отклонена для указания недопустимого модуля.
Я исключил следующее:
- Переводы дельты не выполняются в локальной сети. Исключен, потому что я пытаюсь выполнить передачу через Интернет
- накладные расходы из-за вычисления контрольной суммы. Я видел такое поведение как на быстром, так и на медленном Wi-Fi соединении, и скорость передачи данных, похоже, не ограничена вычислительными возможностями.
but with the exception of the last 4k page (or maybe a few) the file is identical each time.
Вы на самом деле это проверялиcmp
? Или лучше, сxdelta
чем-то? Если вы действительно хотите минимизировать размер передачи, сохраняйте старую и новую версии локально, чтобы вы могли локально вычислить минимальный двоичный дифференциал (с чем-то отличным от rsync) и просто отправить его, не отправляя контрольные суммы по измеренному соединению. Делать это на уровне записей базы данных, а не на уровне двоичных файлов, вероятно, еще лучше, как предполагает Дероберт.rsync --stats
, а также-v -v
получить более подробную статистику. Rsync скажет вам, сколько было сопоставленных и несопоставленных данных.Ответы:
Резюме
Базы данных, как правило, содержат много метаданных, организационных данных и т. Д. Вставка, как правило, вряд ли будет простым добавлением, как это было бы с текстовым файлом. Тестирование SQLite показывает, что он ведет себя таким образом, как в WAL, так и в не WAL режимах. Это приводит к тому, что rsync синхронизирует намного больше данных, чем вы ожидаете. Вы можете несколько снизить эти издержки, используя low
--block-size
(за счет увеличения накладных расходов и передачи контрольных сумм).Лучший подход, вероятно, состоит в том, чтобы выгружать новые записи как дамп SQL, сжимать их и передавать. В качестве альтернативы, существует несколько решений для репликации SQLite, вы можете использовать одно из них.
roaima предлагает как минимум, вы могли бы сделать полный дамп SQL, сжать его
gzip --rsyncable
, а затем rsync это. Полагаю, стоит проверить, достаточно ли мала дельта.Детали
То, что вы пытаетесь, должно работать. Я бы лично добавил
--partial
к вашим опциям rsync, на случай, если он каким-то образом обнаружит растущий файл как частичную передачу. Вы также можете получить лучшую статистику передачи с--stats
.Во-вторых, нужно проверить, действительно ли SQLite касается только нескольких страниц - честно говоря, я не удивлюсь, если он будет писать страницы по всему файлу. Одним из быстрых способов проверки будет использование
cmp -l
двух версий - посмотрите, есть ли изменения на страницах, отличных от последних. Помните, чтоrsync
идея «страницы» / блока отличается от идеи SQLite; Вы можете изменить Rsync через--block-size
. Уменьшение может помочь.Изменить: я сделал быстрый тест с SQLite. Даже с 32 тыс. Страниц, добавив кучу записей в журнале на каждой странице. Подробности ниже.
Редактировать 2 : Кажется, лучше в режиме WAL, хотя вы по-прежнему берете огромные накладные расходы, вероятно, с контрольной точки.
Изменить 3 : Это также лучше, чем больше данных, которые вы добавляете за передачу - я думаю, что он, вероятно, размечает определенные блоки снова и снова. Таким образом, вы переносите один и тот же набор блоков независимо от того, записал ли он их один или сто раз.
Кстати: для минимизации передачи вы, вероятно, можете сделать намного лучше, чем rsync. Например, дамп SQL новых записей со времени последней передачи
xz --best
(или дажеgzip
) будет, вероятно, немного меньше.Быстрый тест SQLite
Схема:
Perl программа:
Было гораздо больше примеров сообщений журнала (2076).
Проверка того, какие страницы изменились:
источник