1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/victory_always-rocksdb

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
WINDOWS_PORT.md 16 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 05:07 84d19a0

Макросы для констант. Иногда нам приходилось делать членов класса static const и размещать определение в файле .cc.

  • constexpr для функций был заменён на специализацию шаблона (1 место).
  • Члены объединения, имеющие нетривиальные конструкторы, были заменены на char[] в одном месте вместе с исправлениями ошибок (пространственная экспериментальная функция).
  • Нульмерные массивы считаются нестандартным расширением, которое мы преобразовали в массив размером 1, и это должно хорошо работать для целей этих классов.
  • В std::chrono отсутствует поддержка наносекунд (исправлено в предстоящем выпуске STL), и нам пришлось использовать QueryPerfCounter() в env_win.cc.
  • Инициализация статических переменных функции по-прежнему небезопасна. Использовали std::once, чтобы смягчить ситуацию в WinEnv.

Заметки о среде Windows

Мы стремились сделать её функционально наравне с posix_env. Это означает, что мы максимально точно воспроизвели функциональность пула потоков и других вещей, включая:

  • Воспроизведение логики posix с использованием примитивов std:thread.
  • Реализацию всей функциональности дискового доступа posix_env.
  • Установку use_os_buffer=false для отключения буферизации диска ОС для WinWritableFile и WinRandomAccessFile.
  • Замену pread/pwrite на WriteFile/ReadFile со структурой OVERLAPPED.
  • Использование SetFileInformationByHandle для компенсации отсутствия fallocate.

Подробно

Хотя Windows предоставляет собственную эффективную реализацию пула потоков, мы решили воспроизвести логику posix, используя примитивы std::thread. Это позволяет любому быстро обнаруживать любые изменения в исходном коде posix и воспроизводить их в среде Windows. Это оказалось очень эффективным. В то же время любой, кто хочет заменить встроенный пул потоков, может сделать это с помощью стекируемых сред RocksDB.

Для дискового доступа мы реализовали всю функциональность, присутствующую в posix_env, которая включает файлы с отображением памяти, произвольный доступ, поддержку ограничителя скорости и т. д. Флаг use_os_buffer на платформах Posix в настоящее время обозначает отключение опережающего чтения через механизм fadvise. В Windows нет системного вызова fadvise, более того, она реализует кэш диска способом, который сильно отличается от Linux. На Windows нередко выполняют небуферизованный доступ к диску, чтобы контролировать потребление памяти. Мы считаем, что в нашем случае это также может быть хорошим вариантом конфигурации за счёт пропускной способности диска. Вместо этого можно увеличить размер настроенного кэша в памяти. Поэтому мы выбрали use_os_buffer=false, чтобы отключить буферизацию диска ОС для WinWritableFile и WinRandomAccessFile. ОС накладывает ограничения на выравнивание смещений диска, используемых буферов и объёма данных, которые считываются/записываются при доступе к файлам в небуферизованном режиме. Когда опция включена, классы ведут себя стандартным образом. Это позволяет выполнять запись и чтение в случаях, когда небуферированный доступ не имеет смысла, таких как WAL и MANIFEST.

Мы заменили pread/pwrite на WriteFile/ReadFile со структурой OVERLAPPED, чтобы атомарно перейти к позиции операции с диском, но всё ещё выполнять операцию синхронно. Таким образом, мы можем достаточно хорошо имитировать эту функциональность pread/pwrite. Единственное отличие состоит в том, что указатель файла не возвращается в исходное положение, но это вряд ли имеет значение, учитывая случайный характер доступа.

Мы использовали SetFileInformationByHandle, чтобы усекать файлы после записи полной последней страницы на диск и предварительно выделять дисковое пространство для ускорения ввода-вывода, компенсируя отсутствие fallocate, хотя некоторые различия сохраняются. Например, предварительно выделенное пространство не заполняется нулями, как в Linux, однако, с положительной стороны, позиция конца файла также не изменяется после предварительного выделения. RocksDB переименовывает, копирует и удаляет файлы по своему усмотрению, даже если они могут быть открыты другим дескриптором одновременно. Нам пришлось ослабить требования и разрешить почти все возможные разрешения параллельного доступа.

Локальное хранилище потока

Локальное хранилище потока играет значительную роль для производительности RocksDB. Вместо создания отдельной реализации мы решили создать... В тексте запроса используется язык программирования C++.

Перевод текста запроса:

«Встроенные обёртки, которые перенаправляют вызовы pthread_specific в интерфейсы Tls Windows в пространстве имён rocksdb::port. Это оставляет существующую логику нетронутой и неизменной, а также легко поддерживаемой.

Чтобы смягчить отсутствие очистки локального хранилища потока при завершении потока, мы добавили ограниченное количество специфичного для Windows кода в тот же файл thread_local.cc, который внедряет обратный вызов очистки в структуру "__tls" в сегменте данных ".CRT$XLB". Этот подход гарантирует, что обратный вызов вызывается независимо от того, используется ли RocksDB в исполняемом файле, автономной DLL или другой DLL.

Использование Jemalloc

Когда RocksDB используется с Jemalloc, последний должен быть инициализирован до любого из глобальных переменных или статических объектов C++. Для этого мы внедрили процедуру инициализации в ".CRT$XCT", которая автоматически вызывается средой выполнения перед инициализацией статических объектов. je-uninit ставится в очередь на atexit().

Глобальные операторы new/delete, перенаправляющие jemalloc, используются компоновщиком при выполнении определённых условий. См. раздел сборки в этих заметках.

Трассировка стека и обработчик необработанных исключений

Мы решили не реализовывать эти две функции, поскольку хостинговая программа, как правило, уже имеет их. Мы не испытывали неудобств при отладке проблем в отладчике или анализе дампов процессов, если это было необходимо, и поэтому не считали это приоритетом.

Результаты производительности

Настройка

Все тесты проводятся на одном наборе машин. Вот подробности тестовой настройки:

  • 2 Intel(R) Xeon(R) E5 2450 0 @ 2.10 ГГц (всего 16 ядер);
  • 2 XK0480GDQPH SSD Device, всего 894 ГБ свободного места на диске;
  • Машина имеет 128 ГБ оперативной памяти;
  • Операционная система: Windows Server 2012 R2 Datacenter;
  • 100 миллионов ключей, каждый ключ размером 10 байт, каждое значение размером 800 байт;
  • общий размер базы данных составляет ~76 ГБ;
  • результаты производительности основаны на RocksDB 3.11;
  • используемые параметры, если не указано иное, были точно такими же, как опубликованные на странице GitHub Wiki.

RocksDB на флэш-накопителе

Тест 1. Массовая загрузка ключей в случайном порядке

Версия 3.11

  • Общее время выполнения: 17,6 мин;
  • Fillrandom: 5,480 микросекунд/операцию, 182 465 операций/сек, 142,0 МБ/с;
  • Compact: 4 860 565 440,000 микросекунд/операция, 0 операций/сек.

Версия 3.10

  • Общее время выполнения: 16,2 мин;
  • Fillrandom: 5,018 микросекунд/операцию, 199 269 операций/сек, 155,1 МБ/с;
  • Compact: 4 413 131 733,000 микросекунды/операция, 0 операций/сек.

Тест 2. Массовая загрузка ключей в последовательном порядке

Версия 3.11

  • Fillseq: 4,944 микросекунды/операцию, 202 тыс. операций/сек., 157,4 МБ/с.

Версия 3.10

  • Fillseq: 4,105 микросекунды/операцию, 243,6 тыс. операций/сек., 189,6 МБ/с.

Тест 3. Случайная запись

Версия 3.11

  • Небуферизованный ввод-вывод включён;
  • Перезапись: 52,661 микросекунда/операцию, 18,9 тыс. операций/сек., 14,8 МБ/с.

Версия 3.10

  • Небуферизованный ввод-вывод включён;
  • Перезапись: 52,661 микросекунда/операцию, 18,9 тыс. операций/сек., 14,8 МБ/с.

Тест 4. Случайное чтение

Версия 3.11

  • Небуферизованный ввод-вывод включён;
  • Readrandom: 15,716 микросекунд/операцию, 63,6 тыс. операций/сек., 49,5 МБ/с.

Версия 3.10

  • Небуферизованный ввод-вывод включён;
  • Readrandom: 15,548 микросекунд/операцию, 64,3 тыс. операций/сек., 50,1 МБ/с.

Тест 5. Многопоточное чтение и однопоточная запись

Версия 3.11

  • Небуферизованный ввод-вывод включён;
  • Readwhilewriting: 25,128 микросекунд/операцию, 39,7 тыс. операций/сек.

Версия 3.10

  • Небуферизованный ввод-вывод включён;
  • Readwhilewriting: 24,854 микросекунд/операцию, 40,2 тыс. операций/сек.

RocksDB В памяти

Тест 1. Точечная проверка

Версия 3.11

80 тыс. записей/сек.;

  • Достигнутая скорость записи: 40,5 тыс. записей/сек;
  • Readwhilewriting: 0,314 микросекунды/операцию, 3 187 455 операций/сек., 364,8 МБ/с (715 454 999 из 715 454 999 найдено).

Версия 3.10

  • Достигнута скорость записи: 50,6 тыс. записей/сек;
  • Readwhilewriting: 0,316 микросекунды/операцию, 3 162 028 операций/сек., (719 576 999 из 719 576 999 найдено).

10 тыс. записей/сек.

Версия 3.11

  • Скорость записи достигнута: 5,8 тыс./сек. записи/сек;
  • Readwhilewriting: 0,246 микросекунды/операцию, 4 062 669 операций/сек., 464,9 МБ/с (915 481 999 из 915 481 999 найдено).

Версия 3.10

  • Скорость записи достигнута: 5,8 тыс./сек. записи/сек;
  • Readwhilewriting: 0,244 микросекунды/операцию, 4 106 253 операции/сек., (927 986 999 из 927 986 999 найдено).

Тест 2. Префиксный диапазонный запрос

Версия 3.11

80 тыс. записей/сек.;

  • Скорость записи достигнута: 46,3 тыс./сек. записи/сек;
  • Readwhilewriting: 0,362 микросекунды/операцию, 2 765 052 операции/сек., 316,4 МБ/с (611 549 999 из 611 549 999 найдено)». Версия 3.10:
  • Скорость записи: 45,8 тыс. операций записи в секунду.
  • Чтение во время записи: 0,317 микросекунд на операцию, 3 154 941 операций в секунду; (найдено 708 158 999 из 708 158 999).

Версия 3.11:

  • 10 тыс. записей в секунду.
  • Скорость записи: 5,78 тыс. операций записи в секунду.
  • Чтение во время записи: 0,269 микросекунды на операцию, 3 716 692 операций в секунду, 425,3 мегабайт в секунду (найдено 837 401 999 из 837 401 999).

Версия 3.10:

  • Скорость записи: 5,7 тыс. операций записи в секунду.
  • Чтение во время записи: 0,261 микросекунда на операцию, 3 830 152 операций в секунду (найдено 863 482 999 из 863 482 999).

Мы считаем, что есть ещё большой потенциал для улучшения производительности, и это будет нашей постоянной задачей.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/victory_always-rocksdb.git
git@api.gitlife.ru:oschina-mirror/victory_always-rocksdb.git
oschina-mirror
victory_always-rocksdb
victory_always-rocksdb
master