Hibernate 延迟加载和 Hazelcast
我们现在使用 Hazelcast 作为 Hibernate 二级缓存有一段时间了,但我们认识到,当使用多个节点时,存储和读取数据会出现较长的延迟。
我们大量使用组合对象和 @OneToMany 关系,为了提高性能,我们决定通过 Hibernate 延迟加载来加载这些组合对象或集合。我们还实现了 DataSerialized 来加速 Hazelcast 序列化,正如 Hazelcast 文档中所述。但是记录 writeData/readData 方法的使用情况表明我们实际上并未使用它们!
现在我们还不清楚 Hibernate 代理(通过延迟加载使用)是否会阻止使用 DataSerialized 方法(因为代理本身可能(?)不实现该接口),而且更重要的是 Hazelcast 是否支持延迟加载根本没有——以及如何!
we are using Hazelcast as Hibernate 2nd level cache now for a while but are recognizing long delays in storing and reading data when using more than one node.
We make intensive use of composed objects and @OneToMany relations, and to increase performance we decided to load these composed objects or collections via Hibernate lazy loading. We also implemented DataSerializable to speed up Hazelcast serialization, as it is stated in the Hazelcast documentation. But logging the use of the writeData/readData methods showed us that they were not used actually!
It is unclear for us now, if the Hibernate Proxy (which is used via lazy loading) prevents the use of DataSerializable methods (because the proxy itself might (?) not implement the interface) and - even more important - if Hazelcast supports lazy loading at all - and how!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Hazelcast 的 DataSerialized 与 Hibernate L2 缓存没有任何用途,因为 Hazalcast 集群中存储的对象不是您的实体对象。 Hibernate 在 L2 中使用自己的数据(例如序列化)格式,将实体及其关系和集合转换为自己的格式,并将自己的对象(实现 java.io.Serializable)提供给 Hazelcast。 Hazelcast 使用标准 java 序列化来序列化那些序列并跨集群分发。
如果您的类具有复杂且深层的对象图(密集使用组合对象和 1xn 或类似关系),则此双序列化问题会导致长时间延迟。
Hazelcast 与 Hibernate 的延迟加载无关。 Hibernate 已经单独存储实体及其关系和集合映射。所以所有这些都可以从 Hazelcast 中一一加载。但在您的用例中,如果大多数延迟加载关系始终被加载,那么这将导致多个远程 Hazelcast 调用,而不是一个。所以你应该仔细考虑在哪里使用延迟加载。
如果您的应用程序大部分是只读的,另一个技巧是使用/启用 Hazelcast 近缓存。 (顺便说一句,如果不是,那么使用二级缓存可能不适合您。)这样您将节省大量远程调用,并且经常需要的数据将被缓存在本地。近缓存支持所有 Hazelcast 地图属性,例如 TTL、逐出、最大大小等。
Hazelcast 近缓存文档...
Hazelcast's DataSerializable has no use with Hibernate L2 cache, because stored objects in Hazalcast cluster are not your entity objects. Hibernate uses its own data (say, serialization) format in L2, converts your entities and their relations and collections to its own format and gives its own objects (implementing java.io.Serializable) to Hazelcast. Hazelcast serializes those using standard java serialization and distributes across cluster.
If your classes have complex and deep object graph (intensive use of composed objects and 1xn or similar relations), this dual-serialization issue causes long delays.
Hazelcast has nothing to do with Hibernate's lazy-loading. Hibernate already stores entities and their relations and collection mappings separately. So all those can be loaded from Hazelcast one-by-one. But in your use-case, if most of lazy-loadable relations are always loaded, then that will cause multiple remote Hazelcast calls instead of one. So you should think carefully where to use lazy-loading.
Another trick is to use/enable Hazelcast near-cache, if your app mostly read-only. (Btw if it is not, then using L2 cache maybe not suitable for you.) That way you will save lots of remote calls and frequently needed data will be cached locally. Near cache supports all Hazelcast map properties such as TTL, eviction, max-size etc.
Hazelcast Near-Cache documentation...