Sử dụng tính năng cache với Guava

Chào mừng các bạn đã quay trở lại với thachleblog. Thứ 7 hôm qua xem phim với ngủ nguyên ngày rồi, hôm nay code tí rồi đi cafe thôi, hehe. Bài viết hôm nay mình sẽ giới thiệu một library hỗ trợ cache khá là “nhẹ” và tiện dụng, đó chính là Guava. Với Guava, các bạn sẽ dễ dàng hiểu được cơ chế làm việc cũng như ưu điểm của cache, đồng thời có thể tìm hiểu thêm để apply cho dự án của mình. Chúng ta cùng bắt đầu nào.

Giới thiệu chung

cache voi guava

Guava là một thư viện mã nguồn mở Java, được phát triển bởi Google (xài hàng của anh Google thì yên tâm rồi 😀 ). Guava cung cấp nhiều methods hỗ trợ cho xử lý String, Collections, Caching, Concurrency… trong project hiện tại của mình cũng xài rất nhiều. Nhưng bài viết hôm nay mình chỉ giới thiệu đến một Guava cache thôi. Các phần khác, nếu có hứng thú các bạn có thể tự tìm hiểu nhé.

Guava cache

Guava hỗ trợ in – memory cache, lưu trữ dữ liệu dưới dạng cặp dữ liệu key – value (xem thêm về memory cache tại đây). Guava chủ yếu hỗ trợ 2 method cache chính đó là LoadingCache và Cache.

  • LoadingCache: tự động load dữ liệu vào cache nếu trong cache chưa có dữ liệu
  • Cache: chúng ta phải thực hiện các thao tác kiểm tra sự tồn tại của key trước khi put value vào cache, hay get cache

Guava hỗ trợ thread – seft trong thao tác dữ liệu với cache. Tuy nhiên, Guava không hỗ trợ distributed cache.

Implement

Phần implement này mình chỉ demo đơn giản thao tác LoadingCache của Guava. Dữ liệu sẽ tự động được thêm vào cache sau khi load nếu trong cache chưa có dữ liệu.

Implement LoadingCache khá đơn giản, chúng ta chỉ việc import thư viện Guava, implement inter face  LoadingCache<K, V>. Guava hỗ trợ các phương thức thiết lập cho cache như maximumSize(int), expireAfterAccess()…

Code demo

Class StudentGuavaCache, chúng ta có thể override method load hoặc loadAll để add dữ liệu vào cache

  1. package thach.le.guava;
  2. import java.util.concurrent.TimeUnit;
  3. import com.google.common.cache.CacheBuilder;
  4. import com.google.common.cache.CacheLoader;
  5. import com.google.common.cache.LoadingCache;
  6. public class StudentGuavaCache {
  7. private static LoadingCache<Integer, Student> cache;
  8. static {
  9. cache = CacheBuilder.newBuilder()
  10. .maximumSize(100) //set size
  11. .expireAfterWrite(10, TimeUnit.MINUTES) //set time expire
  12. .build(
  13. new CacheLoader<Integer, Student>() {
  14. @Override
  15. public Student load(Integer id) throws Exception {
  16. return getEmployeeById(id);
  17. }
  18. }
  19. );
  20. }
  21. public static LoadingCache<Integer, Student> getLoadingCache() {
  22. return cache;
  23. }
  24. // this method demo get data from database or file
  25. public static Student getEmployeeById(int id) {
  26. System.out.println("--Executing getStudent--");
  27. Student student = new Student(1, "Thach Le");
  28. return student;
  29. }
  30. }
  31. class Student {
  32. private int id;
  33. private String name;
  34. public Student(int id, String name) {
  35. this.id = id;
  36. this.name = name;
  37. }
  38. public int getId() {
  39. return id;
  40. }
  41. public void setId(int id) {
  42. this.id = id;
  43. }
  44. public String getName() {
  45. return name;
  46. }
  47. public void setName(String name) {
  48. this.name = name;
  49. }
  50. }

Có các thiết lập cho LoadingCache như set số element tối đa cho cache, time expire (tránh trường hợp lưu cache quá lâu, nhiều dẫn đến thiếu RAM. Các bạn có thể xem thêm ở link bên dưới để biết thêm về các thiết lập.

Class Test

  1. package thach.le.guava;
  2. import java.util.concurrent.ExecutionException;
  3. import com.google.common.cache.LoadingCache;
  4. public class GuavaTest {
  5. public static void main(String[] args) {
  6. GuavaTest guavaTest = new GuavaTest();
  7. try {
  8. // Access student first time with id 1, getStudentUsingGuava() will
  9. // be called.
  10. System.out.println(guavaTest.getStudentUsingGuava(1).getName());
  11. System.out.println("------------------------");
  12.  
  13. // The second time we get student, data will cache
  14. System.out.println(guavaTest.getStudentUsingGuava(1).getName());
  15. } catch (ExecutionException e) {
  16. }
  17. }
  18.  
  19. private Student getStudentUsingGuava(int id) throws ExecutionException {
  20. LoadingCache<Integer, Student> cache = StudentGuavaCache.getLoadingCache();
  21. System.out.println("Cache Size:" + cache.size());
  22. return cache.get(id);
  23. }
  24.  
  25. }

Ở ví dụ trên, mình thực hiện khởi tạo object Student sau đó gọi thông qua cach. Các bạn có thể đọc thêm docs và debug để hiểu thêm về cách sử dụng. Ở trên là demo cách cơ bản nhất là load dữ liệu vào cache bằng cách override mothod load(). Thông thường chúng ta sẽ dùng các phương thức put() để thêm element vào cache và sau đó check và get() để lấy value.

Kết quả: từ lần thứ 2 trở đi, dữ liệu sẽ được load từ cache (sẽ không gọi method getStudent() nữa)

result

Vừa rồi là phần trình bày của mình về Guava. Đối với mình, nếu được đọc bài blog này trước thì chắc chắn mình sẽ tiết kiệm được khối time để tìm hiểu về Guava, do đó mình mới viết bài chia sẻ này, hehe. Hy vọng giúp các bạn hiểu về cache cũng như có thể apply Guava cho dự án của mình. Hẹn gặp lại các bạn ở các bài viết sau.

Còn rất nhiều tính năng khác của Guava, các bạn có thể xem thêm tại: https://github.com/google/guava/wiki

3 thoughts on “Sử dụng tính năng cache với Guava

    • Guava chỉ là cache local cho từng instance, ưu điểm là gọn, nhẹ nên thích hợp cache cho các service mà có ít instance. Nếu em có xài guava cho các tính năng khác thì xài luôn cache cho tiện. Về tính năng cache thì sẽ không hỗ trợ nhiều bằng ehcache.

  1. Pingback: Memcached: giới thiệu và cài đặt » Thach Le

Tham gia bình luận