C Программа застряла на непрерывном ожидании во время выполнения диска ввода/вывода на Mac OS X Snow Leopard

StackOverflow https://stackoverflow.com/questions/2017283

  •  19-09-2019
  •  | 
  •  

Вопрос

Одна линия фона: я разработчик Redis, база данных NOSQL. Анкет Одной из новых функций, которые я реализую, является виртуальная память, потому что Redis берет все данные в памяти. Благодаря VM Redis может передавать редко используемые объекты из памяти на диск, существует ряд причин, по которым это работает намного лучше, чем позволить ОС выполнять работу для нас. Места, когда они сериализованы на диск Redis, они занимают в 10 раз меньше места по сравнению со страницами памяти, где они живут, и т. Д.).

Теперь у меня альфа -реализация, которая отлично работает на Linux, но не так хорошо на Mac OS X Snow Leopard. Время от времени, в то время как Редис пытается перемещать страницу из памяти на диск, процесс REDIS входит в непрерывное состояние ожидания в течение нескольких минут. Я не смог отладить это, но это происходит либо при вызове fseeko() или же fwrite(). Анкет Через минуту звонок, наконец, возвращается, и Redis продолжает работать без проблем: без сбоев.

Сумма передаваемых данных очень Маленький, что -то вроде 256 байтов. Так что это не должно быть очень большим количеством выполненного ввода/вывода.

Но есть интересная деталь о файле SWAP, который является целью операции записи. Это большой файл (26 гигабайт), созданный открытие файла с fopen() а затем увеличился с помощью ftruncate(). Анкет Наконец файл unlink()Эд, так что Redis продолжает придерживаться этого, но мы уверены, что, когда процесс Redis выйдет, ОС действительно освободит файл SWAP.

Хорошо, это все, но я здесь для дальнейших деталей. И, кстати, вы даже можете найти фактический код в Redis Git, но не тривиально понять за пять минут, учитывая, что это довольно сложная система.

Большое спасибо за любую помощь.

Это было полезно?

Решение

Насколько я понимаю, HFS+ имеет очень плохую поддержку разреженных файлов. Таким образом, может случиться так, что ваша запись запускает расширение файла, которое инициализации/материализации большой части файла.

Например, я знаю, что я знаю новый большой пустой файл, а затем написание в нескольких случайных местах создает очень большой файл на диске с HFS+. Это довольно раздражает, так как файлы MMAP и Sparse являются чрезвычайно удобным способом работы с данными, и практически любая другая платформа/файловая система обрабатывает это изящно.

Записан ли файл SWAP линейно? Это означает, что мы либо заменяем существующий блок, либо пишем новый блок в конце и увеличиваем указатель свободного пространства? Если это так, возможно, выполнение более частых меньших вызовов Ftruncate для расширения файла приведет к более коротким паузам.

Кроме того, мне любопытно, почему Redis VM не использует MMAP, а затем просто перемещайте блоки в попытке сосредоточиться на горячих страницах.

Другие советы

Антирес, я не уверен, что буду очень помогать, так как мой опыт Apple ограничен Apple ][, но я сделаю это.

Первое - это вопрос. Я бы подумал, что для виртуальной памяти скорость работы будет более важной мерой, чем дисковое пространство (особенно для DB NoSQL, где скорость - вся точка зрения, иначе вы будете использовать SQL, нет?). Но, если ваш файл обмена составляет 26 г, может быть, нет :-)

Некоторые вещи, чтобы попробовать (если возможно).

  1. Постарайтесь действительно изолировать проблему для поиска или написать. Мне трудно поверить, что поиск может занять так давно, в худшем случае, это должно быть сменой буферного указателя. Тем не менее, я не писал OSX, поэтому не могу быть уверен.
  2. Попробуйте настроить размер файла свопа, чтобы увидеть, вызывает ли это проблему.
  3. Вы когда-нибудь динамически расширяете файл SWAP (в отличие от предварительного распределения)? Если вы это сделаете, это может быть то, что вызывает проблему.
  4. Вы всегда пишете в файле как можно больше? Может быть, создание файла 26G может на самом деле не заполнить его данными, но, если вы создаете его, запишите на последний байт, ОС может придется обнулить байты до этого (откладывание инициализации, если таковые имеются).
  5. Что произойдет, если вы просто предварительно выделяете весь файл (запишите на каждый байт) и не разбиваете его? Другими словами, оставьте файл между запусками вашей программы (создавая его, если его, конечно, еще не существует). Затем в вашем коде стартапа для Redis просто инициализируйте файл (указатели и тому подобное). Это может избавиться от любых проблем, подобных тем, которые в пункте 4 выше.
  6. Спросите также на различных сайтах BSD. Я не уверен, сколько Apple изменилось под обложками, но OSX просто BSD на самом низком уровне (Pax Ducks для обложки).
  7. Также подумайте о том, чтобы спросить на сайтах Apple (если вы еще этого не сделали).

Ну, это мой небольшой вклад, надеюсь, это поможет. Удачи с вашим проектом.

Вы отключили кэширование файла для вашего файла? т.е. fcntl (fd, f_global_nocache, 1)

Пробовали ли вы отладки с помощью DTRACE и или инструментов (экспериментальный фронт DTRACE)?

Изучение леопарда с DTRACE

Отладка Chrome на OS X

Как сказал Линус однажды в списке рассылки GIT:

«Я понимаю, что OS X людям трудно его принять, но файловые системы OS X, как правило, полные и полные дерьма - даже больше, чем Windows».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top