لم يعد هذا المشروع يتم الحفاظ عليه !!!
يجب أن توفر OHC أداءً جيدًا على كل من أجهزة السلع والأنظمة الكبيرة باستخدام بنية غير موحدة.
لا توجد نتائج اختبار الأداء متاحة حتى الآن - يمكنك تجربة أداة OHC -BISTMARM. انظر التعليمات أدناه. هناك انطباع أساسي للغاية على السرعة في قسم _nchmarking_.
Java 8 VM التي تدعم 64bit ولديها sun.misc.Unsafe
(Oracle JVMS على X64 Intel CPU).
يستهدف OHC Linux و OSX. يجب أن تعمل على Windows و UNIX OSS الأخرى.
يوفر OHC تطبيقين لخصائص إدخال ذاكرة التخزين المؤقت المختلفة: - يخصص تطبيق _linked_ ذاكرة خارجية لكل إدخال بشكل فردي ويعمل بشكل أفضل للإدخالات المتوسطة والكبيرة. - يخصص تطبيق _chunked_ ذاكرة خارجية لكل جزء من تجزئة ككل وهو مخصص للإدخالات الصغيرة.
يتم تكوين عدد الأجزاء عبر org.caffinitas.ohc.OHCacheBuilder
، الافتراضي إلى # of cpus * 2
ويجب أن تكون قوة 2. تتم مزامنة الوصول إلى كل قطعة.
يتم تخصيص كل إدخال خريطة التجزئة بشكل فردي. الإدخالات مجانية (معروفة) ، عندما لا يتم الإشارة إليها بواسطة خريطة خارج الكعك نفسها أو أي مرجع خارجي مثل 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. تتم مزامنة الوصول إلى كل قطعة.
كل قطعة مقسمة إلى أجزاء متعددة. كل قطعة مسؤولة عن جزء من إجمالي السعة (capacity / segmentCount)
. يتم تخصيص هذه الكمية من الذاكرة بمجرد تقديمها أثناء التهيئة وتقسيمها منطقياً إلى عدد قابل للتكوين من القطع. يتم تكوين حجم كل قطعة باستخدام خيار chunkSize
في org.caffinitas.ohc.OHCacheBuilder
.
مثل التنفيذ المرتبط ، يتم تسلسل إدخالات التجزئة إلى مخزن مؤقت مؤقت أولاً ، قبل حدوث المقطع الفعلي (يتم مزامنة عمليات التحضير).
يتم وضع إدخالات جديدة في قطعة الكتابة الحالية. عندما يكون هذا الجزء ممتلئًا ، سيصبح الجزء التالي الفارغ هو قطعة الكتابة الجديدة. عندما تكون جميع القطع ممتلئة ، يتم إخلاء الجزء الأقل استخدامًا مؤخرًا ، بما في ذلك جميع الإدخالات التي تحتوي عليها.
إن تحديد خصائص fixedKeyLength
و fixedValueLength
Builder يقلل من بصمة الذاكرة بمقدار 8 بايت لكل إدخال.
لا يتم دعم التسلسل والوصول المباشر ووظائف التحميل في هذا التنفيذ.
لتمكين التنفيذ المكثف ، حدد chunkSize
في org.caffinitas.ohc.OHCacheBuilder
.
ملاحظة: لا يزال ينبغي اعتبار التنفيذ المكثف تجريبيًا.
تدعم OHC ثلاث خوارزميات الإخلاء:
استخدم فئة OHCacheBuilder
لتكوين جميع المعلمات اللازمة مثل
بشكل عام ، يجب أن تعمل مع طاولة تجزئة كبيرة. كلما زاد حجم جدول التجزئة ، كلما كان القائمة المرتبطة أقصر في كل قسم التجزئة-وهذا يعني مسارات رابط أقل ارتباطًا وزيادة الأداء.
إجمالي المبلغ المطلوب من ذاكرة الكومة هو إجمالي السعة بالإضافة إلى جدول التجزئة . يتطلب كل دلو تجزئة (حاليًا) 8 بايت - وبالتالي فإن الصيغة هي capacity + segment_count * hash_table_size * 8
.
تخصص OHC الذاكرة خارج الجيفا مباشرة إلى الحد من الحد من الذاكرة خارج جافا. هذا يعني أن جميع الذاكرة المخصصة من قبل OHC لا يتم حسابها نحو -XX:maxDirectMemorySize
.
نظرًا لأن التنفيذ المرتبط بشكل خاص يؤدي عمليات مخصصة/مجانية لكل إدخال فردي ، فكر في أن تجزئة الذاكرة يمكن أن يحدث.
اترك أيضًا بعض غرفة الرأس نظرًا لأن بعض التخصيصات قد لا تزال في رحلة وأيضًا "الأشياء الأخرى" (نظام التشغيل ، JVM ، إلخ) تحتاج إلى ذاكرة. يعتمد ذلك على نمط الاستخدام مقدار الضرورة. لاحظ أن التنفيذ المرتبط يخصص الذاكرة أثناء عمليات الكتابة _before_ يتم حسابه نحو الأجزاء ، مما سيطرد الإدخالات القديمة. هذا يعني: لا تكرس جميع الذاكرة المتاحة لـ 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) . .يبني()؛
يستخدم هذا Quickstart التكوين الافتراضي الأقل:
انظر Javadoc of CacheBuilder
للحصول على قائمة كاملة بالخيارات.
تحتاج المسلسلات الرئيسية والقيمة إلى تنفيذ واجهة CacheSerializer
. تحتوي هذه الواجهة على ثلاث طرق:
int serializedSize(T t)
لإرجاع الحجم التسلسلي للكائن المعطىvoid serialize(Object obj, DataOutput out)
لتسلسل الكائن المحدد إلى إخراج البياناتT deserialize(DataInput in)
لإلغاء تمييز كائن من إدخال البيانات استنساخ repo git إلى جهازك المحلي. إما استخدام الفرع الرئيسي المستقر أو علامة الإصدار.
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
(عند البناء من المصدر) للحصول على بعض معلومات المساعدة.
بشكل عام ، تبدأ الأداة القياسية مجموعة من مؤشرات الترابط وتنفيذ عمليات _get_ و _put_ بشكل متزامن باستخدام توزيعات المفاتيح القابلة للتكوين لعمليات _get_ و _put_. يجب أيضًا تكوين توزيع حجم القيمة.
خيارات سطر الأوامر المتاحة:
-cap <rag> حجم ذاكرة التخزين المؤقت -D <Arg> المدة القياسية في الثواني -هما مساعدة ، طباعة هذا الأمر -LF <Arg> عامل تحميل جدول التجزئة -r <arg> RED-WRITE RATION (كقوة مزدوجة 0..1 تمثل فرصة للقراءة) -RKD <Arg> توزيع مفتاح Hot Key - الافتراضي: موحد (1..10000) -SC <REG> عدد الأجزاء (عدد الخرائط الفردية خارج الوفاة) -t <arg> مؤشرات الترابط للتنفيذ -VS <Arg> أحجام القيمة - الافتراضي: ثابت (512) -WKD <Arg> توزيع المفتاح الساخن - التوزيع الافتراضي: موحد (1..10000) -WU <Arg> الاحماء-<العمل-Secs> ، <seed-secs> -z <arg> حجم جدول التجزئة -CS <REG> حجم قطعة - في حالة تحديد ذلك ، سيستخدم تطبيق "قطعة" -fks <Arg> حجم المفتاح الثابت في البايتات -FVS <Arg> حجم القيمة الثابتة في البايتات -Mes <Arg> Max Entry Size phtes -لا تستخدم القفل -فقط Aversiviate لوضع الخيوط الواحدة -HM <Arg> خوارزمية التجزئة لاستخدام - murmur3 ، xx ، crc32 -BH Show Ducket Historgram في الإحصائيات -كل <arg> تمكين الرسم البياني. الافتراضي: خطأ
يمكن تكوين توزيعات مفاتيح القراءة ومفاتيح الكتابة وأحجام القيمة باستخدام الوظائف التالية:
exp (min..max) توزيع أسي على النطاق [min..max] متطرف (دقيقة .. Max ، الشكل) توزيع القيمة المتطرفة (Weibull) على النطاق [min..max] Qextreme (min..max ، شكل ، Quantas) قيمة متطرفة ، تنقسم إلى Quantas ، حيث تكون فرصة الاختيار موحدة Gaussian (min..max ، stdvrng) توزيع غاوسي/طبيعي ، حيث يعني = (دقيقة+كحد أقصى)/2 ، و stdev (متوسط الظهر)/stdvrng Gaussian (min..max ، mean ، stdev) توزيع gaussian/normal ، مع متوسط محدد بشكل صريح و stdev موحد (دقيقة .. م) توزيع موحد على النطاق [دقيقة ، كحد أقصى] ثابت (VAL) توزيع ثابت ، يعيد دائمًا نفس القيمة سسبق الاسم مع ~ سوف يقلل من التوزيع ، على سبيل المثال ~ exp (1..10) سوف تسفر عن 10 ، بدلاً من الأقل ، في كثير من الأحيان الاسم المستعار: Ext ، Qextr ، Gauss ، Normal ، Norm ، Weibull
(ملاحظة: هذه تشبه أداة الإجهاد Apache Cassandra - إذا كنت تعرف واحدة ، فأنت تعرف كلاهما ؛)
مثال سريع مع نسبة القراءة/الكتابة من .9
، حوالي 1.5 جيجابايت سعة كحد أقصى ، 16 سلسلة رسائل تعمل لمدة 30 ثانية:
Java -jar OHC-BENCHMARM/TARGER/OHC-BENCHMARM-0.5.1-SNAPSHOT.JAR
(لاحظ أن الإصدار في اسم ملف JAR قد يختلف.)
على نظام Core I7 Core (OSX) 2.6 جيجا هرتز (OSX) ، تكون الأرقام التالية نموذجية لتشغيل المعيار المذكور أعلاه (.9 نسبة قراءة/كتابة):
عند استخدام عدد كبير جدًا من الكائنات في كومة كبيرة جدًا ، ستعاني الأجهزة الافتراضية من زيادة ضغط GC لأنه يتعين عليه بشكل أساسي فحص كل كائن سواء كان يمكن جمعه ويتعين عليه الوصول إلى جميع صفحات الذاكرة. يجب أن تحتفظ ذاكرة التخزين المؤقت بمجموعة ساخنة من الكائنات للوصول السريع (على سبيل المثال ، حذف القرص أو الشبكة المستديرة). الحل الوحيد هو استخدام الذاكرة الأصلية - وهناك سينتهي بك الأمر مع الاختيار إما لاستخدام بعض التعليمات البرمجية الأصلية (C/C ++) عبر JNI أو استخدام الوصول المباشر للذاكرة.
يحتوي الكود الأصلي باستخدام C/C ++ عبر JNI على العيب الذي يجب أن تكتب بشكل طبيعي رمز C/C ++ لكل منصة. على الرغم من أن معظم OS OS UNIX (Linux و OSX و BSD و SOLARIS) متشابهان تمامًا عند التعامل مع أشياء مثل مكتبات المقارنة والتبديل أو POSIX ، فإنك تريد أيضًا دعم النظام الأساسي الآخر (Windows).
كل من الكود الأصلي والوصول المباشر من الذاكرة لديهما عيب في "ترك" سياق "JVM" - يريدون أن يقولوا إن الوصول إلى ذاكرة OFF OFF أبطأ من الوصول إلى البيانات في كومة Java وأن كل مكالمة JNI لديها بعض " الهروب من سياق JVM "التكلفة.
لكن ذاكرة الكومة رائعة عندما يتعين عليك التعامل مع كمية هائلة من العديد من/العديد من ذاكرة ذاكرة التخزين المؤقت لأن DOS لا تضع أي ضغط على جامع القمامة Java. دع Java GC تقوم بعملها للتطبيق حيث تقوم هذه المكتبة بعملها للبيانات المخزنة مؤقتًا.
TL ؛ DR تخصيص الذاكرة خارج الجبال مباشرة وتجاوز ByteBuffer.allocateDirect
لطيف للغاية بالنسبة إلى GC ولدينا تحكم صريح في تخصيص الذاكرة ، والأهم من ذلك ، مجانًا. تنفيذ الأسهم في Java يحرر الذاكرة خارج الجبال أثناء مجموعة القمامة-أيضًا: إذا لم يكن هناك المزيد من الذاكرة خارج الربع ، فمن المحتمل أن يؤدي إلى GC كامل ، وهو أمر يمثل مشكلة إذا واجهت خيوط متعددة هذا الموقف بشكل متزامن لأنه يعني الكثير من GCs كاملة بالتتابع. علاوة على ذلك ، يستخدم تنفيذ الأسهم قائمة متزامنة عالمية متزامنة لتتبع تخصيصات الذاكرة خارج الرثة.
هذا هو السبب في أن OHC تخصص الذاكرة خارج الجبال مباشرة وتوصي بتحميل Jemalloc مسبقًا على أنظمة Linux لتحسين أداء إدارة الذاكرة.
تم تطوير OHC في 2014/15 لـ Apache Cassandra 2.2 و 3.0 لاستخدامها كواجهة خلفية لخليط الصف الجديد.
نظرًا لعدم توفر تطبيقات ذاكرة التخزين المؤقت مناسبة تمامًا خارج Heap ، فقد تقرر إنشاء تطبيق جديد تمامًا - وهذا هو OHC. ولكن اتضح أن OHC وحدها قد تكون قابلة للاستخدام أيضًا في المشاريع الأخرى - ولهذا السبب فإن OHC مكتبة منفصلة.
يجب أن يذهب "شكرًا لك" الكبير إلى Benedict Elliott Smith و Ariel Weisberg من Datastax على مدخلاتهما المفيدة جدًا إلى OHC!
بن مانيس ، مؤلف كتاب الكافيين ، ذاكرة التخزين المؤقت على الكثافة القابلة للتكوين باستخدام W-Tiny LFU.
المطور: روبرت ستوب
حقوق الطبع والنشر (C) 2014 Robert Stupp ، Koeln ، ألمانيا ، Robert-Stupp.de
مرخصة بموجب ترخيص Apache ، الإصدار 2.0 ("الترخيص") ؛ لا يجوز لك استخدام هذا الملف إلا في الامتثال للترخيص. يمكنك الحصول على نسخة من الترخيص على
http://www.apache.org/licenses/license-2.0
ما لم يكن مطلوبًا بموجب القانون المعمول به أو الموافقة على الكتابة ، يتم توزيع البرامج الموزعة بموجب الترخيص على أساس "كما هي" ، دون ضمانات أو شروط من أي نوع ، إما صريحة أو ضمنية. راجع ترخيص الأذونات والقيود التي تحكم اللغة المحددة بموجب الترخيص.