Java Object cache API น้ำหนักเบา [ปิด]


99

คำถาม

ฉันกำลังมองหา API การแคชอ็อบเจ็กต์ Java ในหน่วยความจำ ข้อเสนอแนะใด ๆ ที่ผ่านมาคุณเคยใช้วิธีแก้ไขอะไรบ้าง?

ปัจจุบัน

ตอนนี้ฉันแค่ใช้แผนที่:

Map cache = new HashMap<String, Object>();
cache.put("key", value);

ข้อกำหนด

ฉันต้องการขยายแคชเพื่อรวมคุณสมบัติพื้นฐานเช่น:

  • ขนาดสูงสุด
  • ถึงเวลาที่จะมีชีวิตอยู่

อย่างไรก็ตามฉันไม่ต้องการคุณสมบัติที่ซับซ้อนมากขึ้นเช่น:

  • เข้าถึงได้จากหลายกระบวนการ (เซิร์ฟเวอร์แคช)
  • ความคงอยู่ (ไปยังดิสก์)

ข้อเสนอแนะ

แคชในหน่วยความจำ:

  • Guava CacheBuilder - การพัฒนาที่ใช้งานอยู่ ดูงานนำเสนอนี้
  • LRUMap - กำหนดค่าผ่าน API ไม่มี TTL ไม่ได้สร้างขึ้นเพื่อการแคช
  • whirlycache - การกำหนดค่า XML รายชื่อผู้รับจดหมาย. อัปเดตล่าสุดเมื่อปี 2549
  • cache4j - การกำหนดค่า XML เอกสารเป็นภาษารัสเซีย อัปเดตล่าสุดเมื่อปี 2549

การแคชขององค์กร:

  • JCS - การกำหนดค่าคุณสมบัติ เอกสารมากมาย
  • Ehcache - การกำหนดค่า XML เอกสารมากมาย เป็นที่นิยมมากที่สุดตามความนิยมของ Google

3
คุณสามารถแก้ไขส่วนแคชคำแนะนำในหน่วยความจำเพื่อรวม Guava Cache ได้หรือไม่ ฉันกำลังมองหากลไกการแคชที่มีน้ำหนักเบาเช่นเดียวกับคุณและพบคำถามนี้ แต่ไม่พบ Guava เนื่องจากเป็นวิธีการลง ตอนนี้ฉันใช้แพ็กเกจฝรั่งแคชและมันน่าทึ่งมาก
andras

1
เสร็จแล้ว :-) ดีใจมากที่คุณชอบ!
Kevin Bourrillion

บางทีคุณอาจจะยังต้องการที่จะต้องพิจารณาที่จะเพิ่มค่อนข้างใหม่cache2k ในหน้าเกณฑ์มาตรฐานมีการกล่าวว่ามีประสิทธิภาพดีกว่า ehcache และ Guava มาก
user3001

คำตอบ:


57

EHCacheดีมาก คุณสามารถสร้างแคชในหน่วยความจำ ดูตัวอย่างโค้ดของพวกเขาสำหรับตัวอย่างการสร้างแคชในหน่วยความจำ คุณสามารถระบุขนาดสูงสุดและเวลาที่จะอยู่ได้

EHCache มีคุณสมบัติขั้นสูงบางอย่าง แต่ถ้าคุณไม่สนใจที่จะใช้งาน - อย่าทำ แต่เป็นเรื่องดีที่ทราบว่าพวกเขาอยู่ที่นั่นหากความต้องการของคุณเปลี่ยนไป

นี่คือแคชในหน่วยความจำ สร้างในรหัสโดยไม่มีไฟล์การกำหนดค่า

CacheManager cacheManager = CacheManager.getInstance();
int oneDay = 24 * 60 * 60;
Cache memoryOnlyCache = new Cache("name", 200, false, false, oneDay, oneDay);
cacheManager.addCache(memoryOnlyCache);

สร้างแคชที่จะเก็บองค์ประกอบ 200 รายการและมีค่า ttl 24 ชั่วโมง


2
EHCache แค่อ้างถึงวัตถุหรือทำให้เป็นอนุกรมแล้ว deserialize วัตถุแทน?
PhươngNguyễที่

2
EHCache เป็นโซลูชันที่มีน้ำหนักมากหรือไม่? เรากำลังมองหาโซลูชันการแคชที่มีอยู่เพื่อใช้แคช API บน Android
Matthias

2
มันหนักเกินไปสำหรับ Android ฉันใช้คิตตี้แคชและมันสมบูรณ์แบบมาก!
Felipe

@Stevet K ฉันสายที่จะรู้เทคโนโลยีแคชนี้ แต่ฉันเดาว่า getInstance () ถูกลบหรือเปลี่ยนแปลง
Menai Ala Eddine - Aladdin

46

ฉันชอบMapMakerที่มาพร้อมกับGoogle Guava ( API ) มาก

JavaDoc มีตัวอย่างที่ค่อนข้างเรียบร้อยซึ่งแสดงให้เห็นทั้งความสะดวกในการใช้งานและพลังของมัน:

ConcurrentMap<Key, Graph> graphs = new MapMaker()
   .concurrencyLevel(32)
   .softKeys()
   .weakValues()
   .expiration(30, TimeUnit.MINUTES)
   .makeComputingMap(
       new Function<Key, Graph>() {
         public Graph apply(Key key) {
           return createExpensiveGraph(key);
         }
       });

นอกจากนี้การเปิดตัว 10.0 ของ Guava ยังนำเสนอcom.google.common.cacheแพ็คเกจที่ครอบคลุมมากขึ้น(มีรายการวิกิที่ดีเกี่ยวกับวิธีใช้ )



@mxttie: ขอบคุณฉันได้เพิ่มลิงก์แล้วอย่าลังเลที่จะแนะนำการแก้ไขสำหรับส่วนเพิ่มเติมเช่นนี้
Joachim Sauer

10

คุณยังสามารถตรวจสอบคลังแคชเล็ก ๆ ของฉันชื่อ KittyCache ได้ที่:

https://github.com/treeder/kitty-cache

มีเกณฑ์มาตรฐานประสิทธิภาพเทียบกับ ehcache

ใช้ในโครงการSimpleJPAเป็นแคชระดับที่สอง


1
ดี แต่ถ้ามี TTL
Rosdi Kasim

ขอบคุณ! แค่รหัสที่ฉันพิมพ์ก่อนที่ฉันจะคิดว่าจะตรวจสอบว่ามีใครเปิดแหล่งที่มาแล้วหรือไม่ :)
jpillora

@RosdiKasim มี TTL จริงในการโทร () เช่น: cache.put ("mykey", ค่า, 500); 500 คือ TTL
Travis Reeder

1
@TravisR อืม ... มันไม่มี TTL ย้อนกลับไป .. : p
Rosdi Kasim

อ่าไม่รู้ว่าความคิดเห็นนั้นนานแค่ไหนแล้ว
Travis Reeder

9

คุณสามารถตรวจสอบ LinkedHashMap เพื่อใช้แคชอย่างง่ายโดยไม่ต้องใช้ขวดของบุคคลที่สาม:

    Map <String, Foo> cache = new LinkedHashMap<String, Foo>(MAX_ENTRIES + 1, .75F, true) {

        public boolean removeEldestEntry(Map.Entry<String, Foo> eldest) {
            return size() > MAX_ENTRIES;
        }
    };

จากนั้นคุณจะได้รับจากแคชเช่น

    Foo foo = cache.get(key);
    if (foo == null && !cache.containsKey(key)) {
        try {
            FooDAO fooDAO = DAOFactory.getFooDAO(conn);
            foo = fooDAO.getFooByKey(key);
            cache.put(key, foo);
        } catch (SQLException sqle) {
            logger.error("[getFoo] SQL Exception when accessing Foo", sqle);
        }
    }

พักผ่อนให้เต็มที่เพื่อผู้อ่าน :)


2
ฉันไม่คิดว่าวิธีนี้มีความจุ TTL แม้ว่ามันจะเป็นการเริ่มต้นที่ดีในการหมุนตัวของคุณเอง
Chase Seibert

ใช่ฉันจะปล่อยให้เนื้อหา TTL เป็นส่วนหนึ่งของแบบฝึกหัดของผู้อ่าน: p - และแน่นอนว่า libs ของบุคคลที่สามจะได้รับการทดสอบมากกว่าการหมุนของคุณเอง
JeeBee


5

JCSพยายามและเป็นจริง แม้ว่ากลไกการแคชจะมีน้ำหนักเบา แต่คุณอาจขุดคุ้ยโค้ดจริงและเลียนแบบสิ่งที่พวกเขาทำกับ HashMap ภายใต้ฝาครอบเพื่อให้ตรงกับสิ่งที่คุณต้องการและไม่มีอีกต่อไป ดูเหมือนคุณจะมีความคิดที่ดีในสิ่งที่คุณกำลังมองหา


ฉันคิดว่าคุณหมายความว่ามันไม่เบาเท่าที่กลไกการแคชทำงาน? ดูเหมือนว่าจะเป็นหนึ่งในโซลูชันระดับองค์กรที่ได้รับความนิยมมากที่สุด
Chase Seibert

3

memcached มีไคลเอนต์สำหรับ Java http://www.danga.com/memcached/ต้องการกระบวนการแยกต่างหากเพื่อเป็นเซิร์ฟเวอร์แคช แต่เป็นสิ่งที่ทรงพลัง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.