Khi nào và làm thế nào để sử dụng bộ nhớ đệm cấp hai ngủ đông?


90

Tôi không hiểu khi nào chế độ ngủ đông chạm vào bộ nhớ cache cấp thứ hai và khi nào nó làm mất hiệu lực bộ nhớ cache.

Đây là những gì tôi hiện đang hiểu:

  • Bộ nhớ cache cấp hai lưu trữ các thực thể giữa các phiên, phạm vi là SessionFactory
  • Bạn phải cho biết thực thể nào cần lưu vào bộ nhớ cache, không thực thể nào sẽ được lưu vào bộ nhớ cache theo mặc định
  • Bộ nhớ cache truy vấn lưu trữ kết quả của các truy vấn trong bộ nhớ cache.

Điều tôi không hiểu là

  • Khi nào thì hibernate nhấn bộ nhớ cache này?
  • Giả sử tôi đã thiết lập bộ đệm ẩn cấp hai nhưng không phải bộ đệm truy vấn. Tôi muốn lưu vào bộ nhớ cache khách hàng của mình, có 50000 người trong số họ. Tôi có thể truy xuất khách hàng từ bộ nhớ cache bằng những cách nào?
  • Tôi cho rằng tôi có thể lấy chúng bằng id từ bộ nhớ cache. Điều đó sẽ dễ dàng nhưng cũng không đáng để lưu vào bộ nhớ đệm. Nhưng nếu tôi muốn thực hiện một phép tính nào đó với tất cả khách hàng của mình. Giả sử tôi muốn hiển thị danh sách khách hàng thì tôi sẽ tiếp cận họ bằng cách nào?
  • Làm cách nào để có được tất cả khách hàng nếu bộ nhớ đệm truy vấn bị tắt?
  • Điều gì sẽ xảy ra nếu ai đó cập nhật một trong các khách hàng?
    • Khách hàng đó sẽ bị vô hiệu trong bộ nhớ cache hay tất cả khách hàng sẽ bị vô hiệu?

Hay tôi đang nghĩ bộ nhớ đệm hoàn toàn sai? Điều gì sẽ là cách sử dụng thích hợp hơn của bộ đệm cấp hai trong trường hợp đó? Tài liệu về chế độ ngủ đông hoàn toàn không rõ ràng cách bộ nhớ đệm hoạt động trong thực tế. Chỉ có hướng dẫn về cách thiết lập nó.

Cập nhật: Vì vậy, tôi đã hiểu rằng bộ đệm cấp hai (không có bộ đệm truy vấn) sẽ tốt cho việc tải dữ liệu bằng id. Ví dụ: tôi có đối tượng người dùng mà tôi muốn kiểm tra quyền trong mọi yêu cầu trong ứng dụng web. Đây có phải là một trường hợp tốt để giảm quyền truy cập cơ sở dữ liệu bằng cách lưu vào bộ nhớ đệm người dùng trong bộ đệm ẩn cấp hai không? Giống như tôi sẽ lưu trữ id người dùng trong phiên hoặc bất cứ nơi nào và khi tôi cần kiểm tra quyền, tôi sẽ tải người dùng bằng id đó và kiểm tra quyền.


Câu trả lời:


100

Trước hết, chúng ta hãy nói về bộ nhớ cache cấp quá trình (hoặc bộ nhớ cache cấp 2 như họ gọi nó trong Hibernate). Để làm cho nó hoạt động, bạn nên

  1. định cấu hình nhà cung cấp bộ nhớ cache
  2. cho hibernate biết những thực thể nào cần lưu vào bộ nhớ cache (ngay trong tệp hbm.xml nếu bạn sử dụng loại ánh xạ này).

Bạn cho nhà cung cấp bộ nhớ đệm biết số lượng đối tượng mà nó nên lưu trữ và khi nào / tại sao chúng nên bị vô hiệu. Vì vậy, giả sử bạn có các thực thể Sách và Tác giả, mỗi khi bạn nhận chúng từ DB, chỉ những thực thể không có trong bộ nhớ cache mới được chọn từ DB thực sự. Điều này làm tăng hiệu suất đáng kể. Nó hữu ích khi:

  • Bạn chỉ ghi vào cơ sở dữ liệu thông qua Hibernate (vì nó cần một cách để biết khi nào cần thay đổi hoặc làm mất hiệu lực các thực thể trong bộ nhớ cache)
  • Bạn thường xuyên đọc các đồ vật
  • Bạn có một nút duy nhất và bạn không có bản sao. Nếu không, bạn sẽ cần phải sao chép chính bộ nhớ đệm (sử dụng bộ đệm phân tán như JGroups), điều này làm phức tạp hơn và nó không mở rộng quy mô tốt như các ứng dụng không chia sẻ.

Vậy cache hoạt động khi nào?

  • Khi bạn session.get()hoặc session.load()đối tượng đã được chọn trước đó và nằm trong bộ nhớ cache. Cache là nơi lưu trữ ID là khóa và các thuộc tính là giá trị. Vì vậy, chỉ khi có khả năng tìm kiếm theo ID, bạn có thể loại bỏ việc đánh vào DB.
  • Khi các liên kết của bạn được tải chậm (hoặc được tải với các lựa chọn thay vì liên kết)

Nhưng nó không hoạt động khi:

  • Nếu bạn không chọn theo ID. Một lần nữa - bộ nhớ cache cấp 2 lưu trữ một bản đồ ID của các thực thể đến các thuộc tính khác (nó không thực sự lưu trữ các đối tượng, mà là chính dữ liệu), vì vậy nếu tra cứu của bạn trông giống như from Authors where name = :namesau:, thì bạn không nhấn vào bộ nhớ cache.
  • Khi bạn sử dụng HQL (ngay cả khi bạn sử dụng where id = ?).
  • Nếu trong ánh xạ của bạn mà bạn đặt fetch="join", điều này có nghĩa là để tải các phép nối liên kết sẽ được sử dụng ở mọi nơi thay vì các câu lệnh chọn riêng biệt. Bộ đệm ở mức quy trình chỉ hoạt động trên các đối tượng con nếu fetch="select"được sử dụng.
  • Ngay cả khi bạn có fetch="select"nhưng sau đó trong HQL bạn sử dụng các phép nối để chọn các liên kết - các phép nối đó sẽ được cấp ngay lập tức và chúng sẽ ghi đè lên bất cứ thứ gì bạn đã chỉ định trong hbm.xml hoặc các chú thích.

Bây giờ, về bộ nhớ cache truy vấn. Bạn nên lưu ý rằng nó không phải là một bộ nhớ cache riêng biệt, nó là một phần bổ sung cho bộ nhớ cache cấp quy trình. Giả sử bạn có thực thể Quốc gia. Nó tĩnh, vì vậy bạn biết rằng mỗi lần sẽ có cùng một tập hợp kết quả khi bạn nói from Country. Đây là một ứng cử viên hoàn hảo cho bộ đệm truy vấn, nó sẽ lưu trữ danh sách các ID trong chính nó và khi bạn chọn tất cả các quốc gia vào lần tiếp theo, nó sẽ đưa danh sách này trở lại bộ nhớ cache cấp quy trình và lần lượt, sẽ trả về các đối tượng cho mỗi ID. vì các đối tượng này đã được lưu trữ trong bộ đệm ẩn cấp 2. Bộ nhớ cache truy vấn bị vô hiệu mỗi khi bất kỳ điều gì liên quan đến thực thể thay đổi. Vì vậy, giả sử bạn đã định cấu hình from Authorsđể được đặt vào Bộ nhớ cache truy vấn. Nó sẽ không hiệu quả vì Tác giả thay đổi thường xuyên.


Truy vấn "từ Tác giả tìm nạp tham gia a.books" có yêu cầu bộ nhớ cache Truy vấn để tìm nạp tác giả từ bộ nhớ cache không?
palto

1
Không, bộ đệm truy vấn chỉ dành cho dữ liệu tĩnh và nó chỉ lưu trữ các ID. Tác giả sẽ được lấy từ bộ nhớ cache cấp 2.
Stanislav Bashkyrtsev

@ctapobep: không đúng những gì bạn nói! "from Author a fetch join a.books" hoạt động tốt nếu sách trường của thực thể Tác giả được chú thích (tìm nạp EAGER) ... tôi nghĩ đã quá muộn
Bilal BBB

Như một câu trả lời tuyệt vời! Tôi sẽ nhớ nó mọi lúc! : d
Mohammadreza Khatami

sau khi bật 'bộ nhớ cache truy vấn', nó có tìm nạp dữ liệu từ bộ nhớ cache nếu bạn chọn theo thuộc tính khác với id không?
Arun Raaj

41
  • bộ đệm ẩn cấp 2 là nơi lưu trữ khóa-giá trị. Nó chỉ hoạt động nếu bạn lấy các thực thể của mình theo id
  • bộ đệm ẩn cấp 2 bị vô hiệu hóa / cập nhật cho mỗi thực thể khi một thực thể được cập nhật / xóa qua chế độ ngủ đông. Nó không bị vô hiệu nếu cơ sở dữ liệu được cập nhật theo một cách khác.
  • cho các truy vấn (ví dụ: danh sách khách hàng) sử dụng bộ đệm truy vấn.

Trên thực tế, rất hữu ích khi có một bộ nhớ đệm phân tán khóa-giá trị - đó chính là memcached, và nó cung cấp năng lượng cho facebook, twitter và nhiều hơn nữa. Nhưng nếu bạn không có tra cứu theo id, thì nó sẽ không hữu ích lắm.


12

Đến muộn nhưng muốn trả lời một cách có hệ thống câu hỏi mà nhiều nhà phát triển đặt ra.

Lấy từng câu hỏi của bạn ở đây là câu trả lời của tôi.

Q. Khi nào thì hibernate đánh vào bộ nhớ cache này?

A. Bộ nhớ cache cấp độ đầu tiên được liên kết với đối tượng Session . Bộ đệm ẩn mức thứ hai được liên kết với đối tượng Session Factory . Nếu đối tượng không được tìm thấy trong đầu tiên, thì mức thứ hai được kiểm tra.

Q. Giả sử tôi đã thiết lập bộ đệm ẩn cấp hai nhưng không phải bộ đệm truy vấn. Tôi muốn lưu vào bộ nhớ cache khách hàng của mình, có 50000 người trong số họ. Tôi có thể truy xuất khách hàng từ bộ nhớ cache bằng những cách nào?

A. Bạn đã có câu trả lời trong bản cập nhật của mình. Ngoài ra, bộ đệm truy vấn chỉ lưu trữ danh sách các ID của đối tượng và các Đối tượng đó có ID của chúng được lưu trữ trong cùng bộ đệm cấp hai. Vì vậy, nếu bạn bật bộ nhớ cache truy vấn, bạn sẽ sử dụng cùng một tài nguyên. Gọn gàng đúng không?

Q. Tôi cho rằng tôi có thể lấy chúng bằng id từ bộ nhớ cache. Điều đó sẽ dễ dàng nhưng cũng không đáng để lưu vào bộ nhớ đệm. Nhưng nếu tôi muốn thực hiện một phép tính nào đó với tất cả khách hàng của mình. Giả sử tôi muốn hiển thị danh sách khách hàng thì tôi sẽ tiếp cận họ như thế nào?

A. Đã trả lời ở trên.

Q. Làm cách nào để tiếp cận tất cả khách hàng của tôi nếu bộ nhớ đệm truy vấn bị tắt?

A. Đã trả lời ở trên.

Q. Điều gì sẽ xảy ra nếu ai đó cập nhật một trong các khách hàng? Khách hàng đó sẽ bị vô hiệu trong bộ nhớ cache hay tất cả khách hàng sẽ bị vô hiệu?

Đ. Hibernate không có ý kiến ​​gì nhưng bạn có thể sử dụng IMDG / bộ đệm phân tán của bên thứ ba khác để được triển khai dưới dạng bộ đệm ẩn cấp hai ở chế độ ngủ đông và khiến chúng vô hiệu. Ví dụ: TayzGrid là một trong những sản phẩm như vậy và tôi đoán có nhiều sản phẩm khác.


0

Bộ đệm ẩn cấp hai Hibernate hơi khó hiểu và khó triển khai. Đây là những gì chúng tôi có thể nói dựa trên câu hỏi của bạn:

Khi nào thì Hibernate nhấn bộ nhớ cache này?

Như bạn đề xuất, bộ đệm Hibernate L2 (nếu được bật; nó không được bật theo mặc định) chỉ được truy vấn sau bộ đệm L1. Đây là bộ đệm khóa-giá trị có dữ liệu được lưu giữ trong nhiều phiên.

Giả sử tôi đã thiết lập bộ đệm ẩn cấp hai nhưng không phải bộ đệm truy vấn. Tôi muốn lưu vào bộ nhớ cache khách hàng của mình, có 50000 người trong số họ. Tôi có thể truy xuất khách hàng từ bộ nhớ cache bằng những cách nào?

Bộ nhớ đệm truy vấn sẽ là tốt nhất cho trường hợp sử dụng này, vì dữ liệu khách hàng là tĩnh và được truy xuất từ ​​cơ sở dữ liệu quan hệ.

Điều gì sẽ xảy ra nếu ai đó cập nhật một trong các khách hàng? Khách hàng đó sẽ bị vô hiệu trong bộ nhớ cache hay tất cả khách hàng sẽ bị vô hiệu?

Nó phụ thuộc vào chiến lược bộ nhớ cache Hibernate cụ thể mà bạn đang sử dụng. Hibernate thực sự có bốn chiến lược bộ nhớ cache khác nhau:

READ_ONLY : Các đối tượng không thay đổi khi bên trong bộ đệm.

NONSTRICT_READ_WRITE : Các đối tượng thay đổi (cuối cùng) sau khi mục nhập cơ sở dữ liệu tương ứng được cập nhật; điều này đảm bảo tính nhất quán cuối cùng.

READ_WRITE : Các đối tượng thay đổi (ngay lập tức) sau khi mục nhập cơ sở dữ liệu tương ứng được cập nhật; điều này đảm bảo tính nhất quán mạnh mẽ bằng cách sử dụng khóa "mềm".

GIAO DỊCH : Đối tượng thay đổi bằng cách sử dụng các giao dịch XA phân tán, đảm bảo tính toàn vẹn của dữ liệu; điều này đảm bảo thành công hoàn toàn hoặc quay lại tất cả các thay đổi. Tuy nhiên, trong cả bốn trường hợp này, việc cập nhật một mục nhập cơ sở dữ liệu sẽ không làm mất hiệu lực của toàn bộ danh sách khách hàng trong bộ nhớ cache. Hibernate thông minh hơn một chút :)

Để tìm hiểu thêm về cách hoạt động của bộ nhớ đệm L2 trong Hibernate, bạn có thể xem bài viết “Bộ nhớ đệm Hibernate L2 là gì” hoặc bài viết chuyên sâu Bộ nhớ đệm trong Hibernate với Redis

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.