Этот проект больше не поддерживается !!!
OHC должен обеспечить хорошую производительность как для товарного оборудования, так и для больших систем, используя неравномерные архитектуры.
Результаты испытаний еще не доступны - вы можете попробовать инструмент OHC -Benchmark. См. Инструкции ниже. Очень основное впечатление на скорости происходит в разделе _benchmarking_.
Java 8 VM, которая поддерживает 64 -битную и имеет sun.misc.Unsafe
(Oracle JVMS на процессорах x64 Intel).
OHC предназначен для Linux и OSX. Это должно работать на Windows и других Unix OSS.
OHC предоставляет две реализации для различных характеристик ввода кэша: - Реализация _linked_ выделяет память вне HEAP для каждой записи индивидуально и работает лучше всего для средних и больших записей. - Реализация _CHUNKED_ выделяет память вне HEAP для каждого хэш-сегмента в целом и предназначена для небольших записей.
Количество сегментов настраивается через org.caffinitas.ohc.OHCacheBuilder
, по умолчанию к # of cpus * 2
и должна быть мощностью 2. Записи распределяются по сегментам, используя наиболее значимые биты 64 -битного кода хеша. Доступ на каждом сегменте синхронизируется.
Каждая запись хеш-карты выделяется индивидуально. Записи свободны (сделка), когда на них больше не ссылаются сама карта вне HEAP или какую-либо внешнюю ссылку, такие как org.caffinitas.ohc.DirectValueAccess
или org.caffinitas.ohc.CacheSerializer
.
Дизайн этой реализации уменьшает заблокированное время сегмента до очень короткого времени. Поместите/заменить операции. Сначала выделите память, вызовите org.caffinitas.ohc.CacheSerializer
, чтобы сериализовать ключ и значение, а затем поместите полностью подготовленный вход в сегмент.
Выселение выполняется с использованием алгоритма LRU. Связанный список через все кэшированные элементы как сегмент используется для отслеживания старших записей.
Распределение памяти с помощью реализации.
Цель этой реализации-уменьшить накладные расходы на относительно небольшие записи кэша по сравнению со связанной реализацией, поскольку память для всего сегмента предварительно выделяется. Эта реализация подходит для небольших записей с быстрой (DE) сериализационной реализацией org.caffinitas.ohc.CacheSerializer
.
Сегментация такая же, как в связанной реализации. Количество сегментов настраивается через org.caffinitas.ohc.OHCacheBuilder
, по умолчанию к # of cpus * 2
и должна быть мощностью 2. Записи распределяются по сегментам, используя наиболее значимые биты 64 -битного кода хеша. Доступ на каждом сегменте синхронизируется.
Каждый сегмент разделен на несколько кусков. Каждый сегмент отвечает за часть общей мощности (capacity / segmentCount)
. Этот объем памяти распределяется после предварительного фронта во время инициализации и логически разделено на настраиваемое количество кусочков. Размер каждого куска настроен с использованием опции chunkSize
в org.caffinitas.ohc.OHCacheBuilder
.
Как и связанная реализация, хеш -записи сначала сериализуются во временный буфер, прежде чем произойдет фактическое помещение в сегмент (операции сегмента синхронизированы).
Новые записи помещаются в текущий кусок записи. Когда этот кусок заполнен, следующий пустой кусок станет новым кусочком записи. Когда все кусочки заполнены, наименее используемый кусок, включая все записи, которые он содержит, выселяется.
Указание свойств fixedKeyLength
и fixedValueLength
застройки.
В этой реализации не поддерживаются сериализация, прямой доступ и get-with-with-загрузок.
Чтобы включить реализацию Chunked, укажите chunkSize
в org.caffinitas.ohc.OHCacheBuilder
.
Примечание. Реализация, проведенная в форме, все еще должна считаться экспериментальной.
OHC поддерживает три алгоритма выселения:
Используйте класс OHCacheBuilder
для настройки всех необходимых параметров, подобных
Как правило, вам следует работать с большим хэш -столом. Чем больше хэш-таблица, тем короче связанный список в каждом хэш-разделе-это означает, что меньше связанных склонов и повышение производительности.
Общее количество требуемой вне памяти с кучей - это общая таблица емкости плюс хэш -таблица . Каждое хеш -ведро (в настоящее время) требует 8 байтов - поэтому формула - capacity + segment_count * hash_table_size * 8
.
OHC выделяет память от Heap напрямую обходной от HAVA OFF HEAP MEMIMETION. Это означает, что вся память, выделенная OHC, не учитывается в отношении -XX:maxDirectMemorySize
.
Поскольку особенно связанная реализация выполняет ALLOC/Free Operations для каждой отдельной записи, учитывайте, что фрагментация памяти может произойти.
Также оставьте немного головной комнаты, так как некоторые ассигнования все еще могут быть в полете, а также «другие вещи» (операционная система, JVM и т. Д.). Это зависит от шаблона использования, сколько для головы необходимо. Обратите внимание, что связанная реализация выделяет память во время операций записи. Это означает: не посвящайте всю доступную память OHC.
Мы рекомендуем использовать Jemalloc для поддержания фрагментации низкой. В операционных системах UNIX, предварительная загрузка Jemalloc.
OSX обычно не требует Jemalloc по соображениям производительности. Также убедитесь, что вы используете недавнюю версию Jemalloc - некоторые распределения Linux по -прежнему предоставляют довольно старые версии.
Для предварительной загрузки Jemalloc на Linux используйте export LD_PRELOAD=<path-to-libjemalloc.so
, чтобы предварительно загружать jemalloc на OSX, используйте export DYLD_INSERT_LIBRARIES=<path-to-libjemalloc.so
. Шаблон сценария для предварительной загрузки можно найти в проекте Apache Cassandra.
QuickStart:
Ohcache ohcache = ohcachebuilder.newbuilder () .keyserializer (yourkeyserializer) .valueSerializer (yourValueSerializer) .строить();
В этом QuickStart используется настройка конфигурации по умолчанию:
См. Javadoc of CacheBuilder
для полного списка параметров.
Ключевые и значения сериализаторы должны реализовать интерфейс CacheSerializer
. Этот интерфейс имеет три метода:
int serializedSize(T t)
чтобы вернуть сериализованный размер данного объектаvoid serialize(Object obj, DataOutput out)
чтобы сериализовать заданный объект на выходные данныеT deserialize(DataInput in)
чтобы десериализировать объект из ввода данных Клонировать git Repo к местной машине. Либо используйте стабильную главную ветвь, либо тег выпуска.
git clone https://github.com/snazy/ohc.git
Вам нужен OpenJDK 11 или новее, чтобы построить из источника. Просто выполнить
mvn clean install
Вам нужно построить OHC из источника, потому что большие эталонные артефакты не загружаются в Maven Central.
Выполните java -jar ohc-benchmark/target/ohc-benchmark-0.7.1-SNAPSHOT.jar -h
(при строительстве из источника), чтобы получить некоторую информацию о помощи.
Как правило, инструмент Cendal запускает кучу потоков и выполняет операции _get_ и _put_ одновременно с использованием настраиваемых распределений ключей для операций _get_ и _put_. Распределение размеров значения также необходимо настроить.
Доступные параметры командной строки:
-cap <gard> размер кэша -Д <gard> Продолжительность эталона за считанные секунды -h Помогите, распечатайте эту команду -lf <gard> Коэффициент загрузки хэш -таблицы -r <gard> read-write ration (как двойной 0..1, представляющий шанс для чтения) -rkd <arg> распределение использования горячих ключей - по умолчанию: унифицировано (1..10000) -SC <GARG> Количество сегментов (количество отдельных карт вне HEAP) -t <arg> потоки для выполнения -vs <arg> Размеры значений - по умолчанию: исправлено (512) -wkd <arg> Распределение использования горячих клавиш - по умолчанию: унифицировано (1..10000) -wu <gard> разогреть -z <Arg> размер хэш -таблицы -cs <arg> размер чанка - если указано, он будет использовать реализацию "Chunked" -fks <gard> фиксированный размер ключей в байтах -FVS <GARG> Размер фиксированного значения в байтах -mes <gard> максимальный размер входа в байтах -unl Не используйте блокировку -только уполномочен для однопоточного режима -hm <gard> Алгоритм хэш для использования - Murmur3, XX, CRC32 -BH показывать ведро Историграм в статистике -Kl <GARD> Включить гистограмму ведра. По умолчанию: ложь
Распределения для клавиш считывания, клавиш записи и размеры значений могут быть настроены с помощью следующих функций:
Exp (min..max) экспоненциальное распределение по диапазону [min..max] Экстремальное (мин..max, форма) распределение экстремального значения (Weibull) по диапазону [min..max] Qextreme (min..max, shape, Quantas) крайнее значение, разделенное на кванты, в рамках которого вероятность выбора является равномерной Гаусса (min..max, stdvrng) Гауссовое/нормальное распределение, где среднее = (min+max)/2, а Stdev-(средняя мимическая)/stdvrng Гаусса (min..max, среднее, stdev) Гауссовое/нормальное распределение с явно определенным средним и stdev Равномерное (мин..max) равномерное распределение по диапазону [мин, макс. Исправлено (Val) фиксированное распределение, всегда возвращая одно и то же значение Предшествующий имену Псевдонимы: extr, qextr, gauss, normal, norm, weibull
(Примечание: это похоже на инструмент стресса Apache Cassandra - если вы знаете его, вы знаете оба;)
Быстрый пример с коэффициентом чтения/записи .9
java -jar ohc-benchmark/target/ohc-benchmark-0.5.1-snapshot.jar
(Обратите внимание, что версия в имени файла JAR может отличаться.)
В системе 2,6 ГГц Core i7 (OSX). Следующие цифры типично используются при вышеуказанном тесте (.9 Коэффициент чтения/записи):
При использовании очень огромного количества объектов в очень большой куче виртуальные машины будут страдать от повышения давления GC, поскольку в основном им необходимо осмотреть каждый объект, независимо от того, можно ли его собирать, и должен получить доступ ко всем страницам памяти. Кэш должен хранить горячий набор объектов, доступных для быстрого доступа (например, опускание диска или обворотки к сети). Единственное решение - использовать собственную память - и там вы получите выбор либо использовать какой -то собственный код (C/C ++) через JNI, либо использовать прямой доступ к памяти.
Настоящий код с использованием C/C ++ через JNI имеет недостаток, который вы должны писать код C/C ++ для каждой платформы. Хотя большинство ОС Unix (Linux, OSX, BSD, Solaris) очень похожи, когда работаете с такими вещами, как Compare-and-Swap или Posix библиотеки, вы обычно также хотите поддерживать другую платформу (Windows).
И нативный код, и прямой доступ к памяти имеют недостаток, который им приходится «оставить» контекст JVM « - хочу сказать, что доступ к памяти вне кучи медленнее, чем доступ к данным в куче Java, и что каждый вызов JNI имеет некоторый Выбег из контекста JVM «Стоимость».
Но от памяти с кучей великолепно, когда вам приходится иметь дело с огромным количеством из нескольких/многих ГБ кэш -памяти, поскольку эта DOS не оказывает никакого давления на коллектор мусора Java. Пусть Java GC выполняет свою работу для приложения, где эта библиотека выполняет свою работу для кэшированных данных.
TL; DR выделяет непосредственную память от HEAP и обход ByteBuffer.allocateDirect
AllocatedIrect очень мягкий для GC, и мы имеем явный контроль над распределением памяти и, что более важно, бесплатно. Реализация акций в Java освобождает память вне Heap во время сбора мусора-также: если больше нет памяти, она, вероятно, запускает полную GC, что проблематично, если несколько потоков сталкиваются с этой ситуацией одновременно, поскольку это означает лоты полных GCS последовательно. Кроме того, реализация акций использует глобальный, синхронизированный связанный список для отслеживания распределения памяти вне HEAP.
Вот почему OHC напрямую выделяет память вне HEAP и рекомендует предварительно загружать Jemalloc в Linux Systems для повышения производительности управления памятью.
OHC был разработан в 2014/15 году для Apache Cassandra 2.2 и 3.0, который будет использоваться в качестве новой бэкэнд с строей.
Поскольку не было подходящих полностью внедренных реализаций кэша, было решено построить совершенно новый - и это OHC. Но оказалось, что один OHC также может быть использован для других проектов - поэтому OHC - отдельная библиотека.
Большое «спасибо», чтобы пойти к Бенедикту Эллиотту Смиту и Ариэлю Вайсбергу из DataStax за их очень полезный вклад в OHC!
Бен Мэнес, автор Caffeine, высоко настраиваемый кэш в HEAP с использованием W-Tiny LFU.
Разработчик: Роберт Ступп
Copyright (c) 2014 Роберт Ступп, Коэльн, Германия, Роберт-Стюпп.Д.
Лицензировано по лицензии Apache, версия 2.0 («Лицензия»); Вы не можете использовать этот файл, кроме как в соответствии с лицензией. Вы можете получить копию лицензии на
http://www.apache.org/licenses/license-2.0
Если не требуется применимый закон или не согласен в письменной форме, программное обеспечение, распространяемое по лицензии, распределяется по основам «как есть», без каких -либо гарантий или условий, явных или подразумеваемых. См. Лицензию для конкретного языка, регулирующих разрешения и ограничения по лицензии.