API bộ nhớ cache đối tượng Java nhẹ [đã đóng]


99

Câu hỏi

Tôi đang tìm API bộ nhớ đệm đối tượng trong bộ nhớ Java. Bất kỳ khuyến nghị? Những giải pháp nào bạn đã sử dụng trong quá khứ?

Hiện hành

Hiện tại, tôi chỉ đang sử dụng Bản đồ:

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

Yêu cầu

Tôi cần mở rộng bộ nhớ cache để bao gồm các tính năng cơ bản như:

  • Kích thước tối đa
  • Thời gian để sống

Tuy nhiên, tôi không cần các tính năng phức tạp hơn như:

  • Truy cập từ nhiều quy trình (máy chủ bộ nhớ đệm)
  • Tính bền bỉ (vào đĩa)

Gợi ý

Bộ nhớ đệm trong bộ nhớ:

  • Guava CacheBuilder - phát triển tích cực. Xem bài thuyết trình này .
  • LRUMap - Cấu hình thông qua API. Không có TTL. Không phải mục đích được xây dựng cho bộ nhớ đệm.
  • whirlycache - cấu hình XML. Danh sách gửi thư. Cập nhật lần cuối năm 2006.
  • cache4j - cấu hình XML. Tài liệu bằng tiếng Nga. Cập nhật lần cuối năm 2006.

Bộ nhớ đệm doanh nghiệp:

  • JCS - Cấu hình thuộc tính. Tài liệu phong phú.
  • Ehcache - Cấu hình XML. Tài liệu phong phú. Cho đến nay, phổ biến nhất theo lượt truy cập của Google.

3
Bạn có thể chỉnh sửa phần Gợi ý Bộ nhớ đệm trong bộ nhớ để bao gồm Bộ nhớ đệm Ổi không? Tôi đang tìm kiếm một cơ chế bộ nhớ đệm nhẹ giống như bạn và đã tìm thấy câu hỏi này, nhưng không tìm thấy Guava vì nó đang bị lỗi. Bây giờ tôi sử dụng gói bộ nhớ cache ổi và nó thật TUYỆT VỜI.
andras

1
Làm xong. :-) Rất vui vì bạn thích nó!
Kevin Bourrillion

Có thể bạn cũng muốn xem xét thêm cache2k tương đối mới . Trên trang điểm chuẩn của họ , người ta nói rằng nó có hiệu suất tốt hơn nhiều so với ehcache và Guava.
user3001

Câu trả lời:


57

EHCache rất tốt. Bạn có thể tạo một bộ nhớ đệm trong bộ nhớ. Kiểm tra các mẫu mã của họ để biết ví dụ về việc tạo bộ nhớ đệm trong bộ nhớ. Bạn có thể chỉ định kích thước tối đa và thời gian tồn tại.

EHCache có cung cấp một số tính năng nâng cao, nhưng nếu bạn không muốn sử dụng chúng - thì không. Nhưng thật vui khi biết họ ở đó nếu yêu cầu của bạn thay đổi.

Đây là một bộ nhớ đệm trong bộ nhớ. Được tạo bằng mã, không có tệp cấu hình.

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

Tạo bộ nhớ cache chứa 200 phần tử và có thời gian lưu trữ là 24 giờ.


2
EHCache chỉ tham chiếu đến đối tượng hay nó tuần tự hóa và sau đó giải mã hóa đối tượng thay thế?
Phương Nguyễn

2
EHCache có phải là một giải pháp nặng ký không? Chúng tôi đang xem xét các giải pháp bộ nhớ đệm hiện có để triển khai bộ nhớ cache API trên Android.
Matthias

2
Nó quá nặng đối với Android. Tôi đang sử dụng bộ nhớ cache Kitty và nó quá hoàn hảo!
Felipe

@Stevet K, tôi đã muộn để biết công nghệ Cache này, nhưng tôi đoán getInstance () đã bị xóa hoặc thay đổi.
Menai Ala Eddine - Aladdin

46

Tôi thực sự thích tính MapMakernăng đi kèm với Google Guava ( API )

JavaDoc có một ví dụ khá gọn gàng thể hiện cả tính dễ sử dụng và sức mạnh của nó:

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);
         }
       });

Hơn nữa, bản phát hành 10.0 của Guava đã giới thiệu com.google.common.cachegói mở rộng hơn nhiều (có một mục wiki rất hay về cách sử dụng chúng ).



@mxttie: cảm ơn, tôi đã thêm liên kết, vui lòng đề xuất chỉnh sửa cho những bổ sung như thế này.
Joachim Sauer

10

Bạn cũng có thể xem thư viện bộ nhớ đệm nhỏ của tôi có tên KittyCache tại:

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

Có một số điểm chuẩn hiệu suất so với ehcache.

Nó được sử dụng trong dự án SimpleJPA như một bộ nhớ cache cấp hai.


1
Đẹp quá, nhưng giá như nó có TTL.
Rosdi Kasim

Cảm ơn ! chỉ mã tôi đã gõ trước khi tôi nghĩ để kiểm tra xem ai đó có đã được mở sourced một cái gì đó :)
jpillora

@RosdiKasim nó có TTL thực sự khi gọi put (), ví dụ: cache.put ("mykey", value, 500); 500 là TTL.
Travis Reeder

1
@TravisR Chà ..., hồi đó nó không có TTL ..: p
Rosdi Kasim

Ahh, không nhận ra bình luận đó cách đây bao lâu rồi.
Travis Reeder

9

Bạn có thể xem LinkedHashMap để triển khai một bộ nhớ cache đơn giản mà không cần các lọ của bên thứ ba:

    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;
        }
    };

thì bạn có thể lấy từ bộ nhớ cache như

    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);
        }
    }

phần còn lại làm bài tập cho người đọc :)


2
Tôi không nghĩ rằng phương pháp này có dung lượng TTL. Tuy nhiên, đó sẽ là một khởi đầu tốt để hướng tới việc tự lăn lộn của riêng bạn.
Chase Seibert 23/10/08

Vâng, tôi sẽ để lại nội dung TTL như một phần của bài tập dành cho người đọc: p - và tất nhiên các lib của bên thứ ba sẽ được thử nghiệm nhiều hơn so với việc cuốn sách của riêng bạn.
JeeBee 23/10/08


5

JCS được thử và đúng. Mặc dù nó rất nhẹ khi các cơ chế lưu vào bộ nhớ đệm, bạn có thể đào sâu vào mã thực tế và bắt chước những gì chúng làm với HashMap dưới vỏ bọc chính xác những gì bạn cần và không hơn thế nữa. Bạn dường như có một ý tưởng khá tốt về những gì bạn đang tìm kiếm.


Tôi giả sử bạn có nghĩa là nó không nhẹ như các cơ chế bộ nhớ đệm đi? Tuy nhiên, nó dường như là một trong những giải pháp doanh nghiệp phổ biến nhất.
Chase Seibert 23/10/08

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.