กำลังมองหา Java ในหน่วยความจำแคชแบบง่าย [ปิด]


102

ฉันกำลังมองหาแคชในหน่วยความจำ Java แบบธรรมดาที่มีการทำงานพร้อมกันที่ดี (ดังนั้น LinkedHashMap จึงไม่ดีพอ) และสามารถต่ออนุกรมกับดิสก์ได้เป็นระยะ

คุณลักษณะหนึ่งที่ฉันต้องการ แต่ซึ่งพิสูจน์แล้วว่าหาได้ยากคือวิธี "มอง" วัตถุ ด้วยเหตุนี้ฉันหมายถึงดึงวัตถุจากแคชโดยไม่ทำให้แคชค้างอยู่กับวัตถุนานกว่าที่มันจะมี

อัปเดต:ข้อกำหนดเพิ่มเติมที่ฉันละเลยที่จะพูดถึงคือฉันต้องสามารถปรับเปลี่ยนอ็อบเจ็กต์ที่แคช (ซึ่งมีอาร์เรย์ลอยอยู่) ในตำแหน่ง

ใครสามารถให้คำแนะนำ?


1
ฉันกำลังมองหาสิ่งที่คล้ายกันซึ่ง "อยู่ในกระบวนการ" และน้ำหนักที่เบากว่า ฉันต้องการใช้เพื่อเก็บข้อมูลบางส่วนภายในปลั๊กอิน Eclipse ในฮีป Ehcache และ JCS ดูเหมือนจะมีน้ำหนักมากเกินไป / แจกจ่าย / J2EE สำหรับรสนิยมของฉัน
Uri

1
อาจซ้ำกันได้ของLightweight Java Object cache API
Raedwald

ฉันจะแนะนำ Apache Ignite ( ignite.apache.org )
Bhagat S.

1
คำถามนี้ถูกปิด (6 ปีหลังจากความจริง) และยังคงเป็นสิ่งที่ผู้คนสงสัยในปัจจุบันแสดงให้เห็นว่าระบบโมเดอเรเตอร์ของ SO ล้มเหลวอย่างไร
dustinevan

คำตอบ:


62

เนื่องจากคำถามนี้ถูกถามในตอนแรกห้องสมุด Guava ของ Google จึงมีแคชที่มีประสิทธิภาพและยืดหยุ่น ฉันอยากจะแนะนำให้ใช้สิ่งนี้


3
โปรดทราบว่า Spring ไม่รองรับ Guava cache อีกต่อไป: stackoverflow.com/questions/44175085/…
sinner

@sanity ใช้ Jcache หรือไม่?
Gaurav

Caffineยังเป็นไลบรารีแคชที่ดีและมีประสิทธิภาพ คาเฟอีนเป็นไลบรารีแคชที่มีประสิทธิภาพสูงใกล้เคียงกับ Java 8 คาเฟอีนให้แคชในหน่วยความจำโดยใช้ API ที่ได้รับแรงบันดาลใจจาก Google Guava
Slavus

38

Ehcacheเป็นทางออกที่ดีสำหรับสิ่งนี้และมีวิธีการแอบดู ( getQuiet ()เป็นวิธีการ) เพื่อที่จะไม่อัปเดตการประทับเวลาที่ไม่ได้ใช้งาน ภายใน Ehcache ถูกนำไปใช้กับชุดของแผนที่ซึ่งคล้ายกับ ConcurrentHashMap ดังนั้นจึงมีประโยชน์หลายอย่างพร้อมกัน


2
ขอบคุณคำถามเพิ่มเติม: ถ้าฉันดึงวัตถุจาก EHcache (พูดคืออาร์เรย์) และแก้ไขวัตถุนั้นจะถูกอัปเดตในแคชหรือไม่ กล่าวคือ. EHCache รักษาการอ้างอิงไปยังวัตถุหรือไม่
สติ

1
ฉันเชื่ออย่างนั้น แต่การจะทำได้อย่างปลอดภัยคุณต้องล็อควัตถุอย่างเหมาะสมแน่นอน
Alex Miller

ฉันชอบ ehcache แต่มันเป็นขวดขนาด 10mb ใหญ่เกินไป
markthegrea

24

หากคุณต้องการอะไรง่ายๆสิ่งนี้จะเหมาะกับใบเสร็จหรือไม่

Map<K, V> myCache = Collections.synchronizedMap(new WeakHashMap<K, V>());

มันจะไม่บันทึกลงดิสก์ แต่คุณบอกว่าคุณต้องการง่ายๆ ...

ลิงค์:

(ตามที่อดัมแสดงความคิดเห็นการซิงโครไนซ์แผนที่มีผลการดำเนินงานไม่ได้บอกว่าไอเดียนี้ไม่มีขนบนแผนที่ แต่ก็เพียงพอแล้วสำหรับวิธีแก้ปัญหาที่รวดเร็วและสกปรก)


4
การซิงโครไนซ์แผนที่ขนาดมหึมาทั้งหมดถือเป็นบทลงโทษที่หนักหน่วง คุณสามารถจัดเก็บประเภทที่อ่อนแอในแผนที่แฮชพร้อมกันและลบออกเป็นระยะ ๆ
Adam Gent

7
ConcurrentHashMap ดีกว่า Collections.synchronizedMap stackoverflow.com/questions/6692008/…
Pablo Moretti

8
ประสิทธิภาพที่ชาญฉลาด ConcurrentHashMap ทำงานได้ดีกว่าอย่างแน่นอน แต่จะไม่แบ่งปันคุณสมบัติของ WeakHashMap เกี่ยวกับการอนุญาตให้ตัวรวบรวมขยะเรียกคืนหน่วยความจำ สิ่งนี้อาจสำคัญสำหรับคุณหรือไม่ก็ได้
Evan

4
ConcurrentHashMap<WeakReference<T>>การใช้งานแล้ว docs.oracle.com/javase/7/docs/api/java/lang/ref/…
jdmichal

19

ตัวเลือกสำหรับการแคชในหน่วยความจำ Java ก็คือcache2k ผลการดำเนินงานในหน่วยความจำจะดีกว่า EHCache และ google ฝรั่งดูหน้า cache2k มาตรฐาน

รูปแบบการใช้งานจะคล้ายกับแคชอื่น ๆ นี่คือตัวอย่าง:

Cache<String,String> cache = new Cache2kBuilder<String, String>() {}
  .expireAfterWrite(5, TimeUnit.MINUTES)    // expire/refresh after 5 minutes
  .resilienceDuration(30, TimeUnit.SECONDS) // cope with at most 30 seconds
                                          // outage before propagating 
                                          // exceptions
  .refreshAhead(true)                       // keep fresh when expiring
  .loader(new CacheLoader<String, String>() {
    @Override
    public String load(final String key) throws Exception {
      return ....;
    }
  })
  .build();
String val = cache.peek("something");
cache.put("something", "hello");
val = cache.get("something");

หากคุณมี google guava เป็นที่พึ่งแล้วลองใช้ guava cache อาจเป็นทางเลือกที่ดี


cruftex ถ้าฉันปิดแอปพลิเคชันแคชจะทำลายข้อมูลที่ลงทะเบียนทั้งหมดหรือไม่?
Menai Ala Eddine - Aladdin

10

คุณสามารถใช้imcache โค้ดตัวอย่างอยู่ด้านล่าง

void example(){
    Cache<Integer,Integer> cache = CacheBuilder.heapCache().
    cacheLoader(new CacheLoader<Integer, Integer>() {
        public Integer load(Integer key) {
            return null;
        }
    }).capacity(10000).build(); 
}

9

ลองสิ่งนี้:

import java.util.*;

public class SimpleCacheManager {

    private static SimpleCacheManager instance;
    private static Object monitor = new Object();
    private Map<String, Object> cache = Collections.synchronizedMap(new HashMap<String, Object>());

    private SimpleCacheManager() {
    }

    public void put(String cacheKey, Object value) {
        cache.put(cacheKey, value);
    }

    public Object get(String cacheKey) {
        return cache.get(cacheKey);
    }

    public void clear(String cacheKey) {
        cache.put(cacheKey, null);
    }

    public void clear() {
        cache.clear();
    }

    public static SimpleCacheManager getInstance() {
        if (instance == null) {
            synchronized (monitor) {
                if (instance == null) {
                    instance = new SimpleCacheManager();
                }
            }
        }
        return instance;
    }

}

ปัญหาเกี่ยวกับการใช้แผนที่ที่ซิงโครไนซ์ได้รับการกล่าวถึงแล้วในคำตอบอื่น ๆ
สติ

@sergeyB: ฉันกำลังมองหาโซลูชันที่คล้ายกันซึ่งง่ายสำหรับการใช้แคช ... ขอบคุณ
Prakruti Pathik

1
public static SimpleCacheManager getInstance() {ควรเป็นpublic synchronized static SimpleCacheManager getInstance() {อย่างอื่นif (instance == null) {ไม่ด้ายปลอดภัย ในกรณีนี้คุณสามารถลบอ็อบเจ็กต์มอนิเตอร์ทั้งหมดออกจากกันได้เนื่องจากการซิงโครไนซ์เกิดขึ้นสำหรับการเรียก getInstance () ทั้งหมดโปรดดูที่javaworld.com/article/2073352/core-java/…
Can Kavaklıoğlu

ฉันขอแนะนำให้ใช้ enum สำหรับซิงเกิลตันได้ไหม dzone.com/articles/java-singletons-using-enum
Erk

9

ลอง@Cacheableจากjcabi-ด้าน ด้วยคำอธิบายประกอบเดียวคุณทำให้ผลลัพธ์ของวิธีการทั้งหมดสามารถแคชได้ในหน่วยความจำ:

public class Resource {
  @Cacheable(lifetime = 5, unit = TimeUnit.SECONDS)
  public String load(URL url) {
    return url.openConnection().getContent();
  }
}

อ่านบทความนี้ด้วย: http://www.yegor256.com/2014/08/03/cacheable-java-annotation.html



0

ลองEhcacheไหม ช่วยให้คุณสามารถเสียบอัลกอริธึมการหมดอายุการแคชของคุณเองเพื่อให้คุณสามารถควบคุมฟังก์ชันการทำงานของคุณได้

คุณสามารถทำให้เป็นอนุกรมกับดิสก์ฐานข้อมูลข้ามคลัสเตอร์ ฯลฯ ...

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