hazelcast的坑爹事

转载自

http://blog.csdn.net/hengyunabc/article/details/18514563


简介

开源中国的简介:html

Hazelcast是一个高度可扩展的数据分发和集群平台。特性包括:java

  • 提供java.util.{Queue, Set, List, Map}分布式实现。
  • 提供java.util.concurrency.locks.Lock分布式实现。
  • 提供java.util.concurrent.ExecutorService分布式实现。
  • 提供用于一对多关系的分布式MultiMap。
  • 提供用于发布/订阅的分布式Topic(主题)。
  • 经过JCA与J2EE容器集成和事务支持。
  • 提供用于安全集群的Socket层加密。
  • 支持同步和异步持久化。
  • 为Hibernate提供二级缓存Provider 。
  • 经过JMX监控和管理集群。
  • 支持动态HTTP Session集群。
  • 利用备份实现动态分割。
  • 支持动态故障恢复。

简介是美好的,现实是坑爹的。node

优势

先说下优势吧:git

有个Manager Center的管理界面,很漂亮,能够看到不少有用的数据。包括每一个Map的请求次数等。这些在Memcached,Redis上只能看个大概。github

简单的配置很方便,能够像JDK里的Map,List同样使用。spring


坑爹事情

配置各类找不到

有不少xml的配置方式没有写在文档上,要到代码里各类找。友情提示,能够到代码里的test目录下找到比较完整的配置:缓存

https://github.com/hazelcast/hazelcast/blob/maintenance-3.x/hazelcast-spring/src/test/resources/com/hazelcast/spring/node-client-applicationContext-hazelcast.xml
安全

有不少参数的配置没有写在文档上,要到代码里各类找。友情提示,在com.hazelcast.instance.GroupProperties 这个类里找到一些在文档上没有的配置参数。网络

默认的超时配置太长

不少超时配置都是上百秒的,试想如今的网站或者应用,有哪一个能够忍受上百秒的超时。从另外一个侧面也能够看出hazelcast的本身的信心不足,要靠超长时间的超时来保证运行的正确性。app

即便配置了较短的超时时间,仍是有可能会有各类出人意料的超时,认真研究过代码后,发现是有不少超时时间是在代码里写死的。。

版本之间不兼容

版本之间不兼容,不能滚动升级。这就意味着,当升级时,整个集群都要一块重启,这对不少网站来讲,是不能忍受的。听说从3.1版本后会保证小版本的兼容性。

https://github.com/hazelcast/hazelcast/issues/14

hazelcast里代码一大问题就是把序列化方案和网络通信混在一块儿了,致使各类升级兼容问题。每一个消息包在解析时,都有可能由于类有改动而不兼容。

并且序列化方案仍是那种要实现一个特定接口的。在Protobuf,Thrift,及各类基于反射的序列化方案这么流行的今天,很难想像会有这样难用的序列化方式。

一个结点出问题,影响整个集群

当集群里某个节点出故障时,好比OOM,CPU100%,没反应以后,集群里发到那个结点的操做就各类超时,各类不正常。这个能够算是hazelcast的一个致命的缺点。

咱们线上的集群有30多个结点,随便一个有问题,都会致使整个集群有问题。另外,当集群里有一个应用下线/上线,都会引发数据的迁移,尽管迁移是自动的,可是也是一个不可控的风险。

咱们开始时用的是hazelcast2.5.1,后来升级到3.1.3版本。升级后发现两个结点间常常会有网络流量超高的状况,最后发现是merge-policy的配置在3.0只能配置类的全名,而在2.5是能够配置一个简称的。而后在集群里有数据要迁移,进行Merge时,就会由于ClassNotFoundException而失败。而Hazelcast坑爹的地方在于它不断地重试,并且是无停顿地重试,从而致使两个结点之间网络流量超高,甚至超过了100Mbps。

hazelcast client很难用

首先,仍是文档太少,不少配置根本没有提到,得本身到代码里去找。

另外,若是hazelcast server集群所有挂掉后,client竟然不会本身重连(重试3次就放弃了)。如今的各类组件重启是很正常的事情,而hazelcast client竟然不会自动重连,真心使人无语。更加扯蛋的是,好比map.get,若是没有链接上,会抛出一个RuntimeException,那么整个线程都退出了。

3.0版本和3.0.2版本之间的配置格式竟然有很大的变化,不少时候,找个配置,得本身去看xml的xsd文件。。

结点之间Merge时,须要反序列化

这个我认为是代码太多致使的混乱。结点之间数据合并时,原本只要比较下数据的版本,时间等就能够了,可是在合并时却把对象反序化出来。若是在Server端没有对应的jar包,则会抛出ClassNotFoundException。

参考这里:

https://github.com/hazelcast/hazelcast/issues/1514


一些原理性的东东

Partition

从原理上来讲,hazelcast是默认有271个partition,这271个parition平均分布在集群里的结点中,所以集群里的数据分散在每一个结点中。而后在进行操做时,先计算获得key所在的partiion,再进行操做。

详细请参考PartitionServiceImpl这个类的代码:

[java]  view plain copy 在CODE上查看代码片 派生到个人代码片
  1. public final int getPartitionId(Data key) {  
  2.     int hash = key.getPartitionHash();  
  3.     return (hash != Integer.MIN_VALUE) ? Math.abs(hash) % partitionCount : 0;  
  4. }  

NearCache的实现原理

hazelcast里有一个所谓的nearcache的东东,其实这个很简单,就是一个本地的二级缓存。在get的时候先到本地的nearcache里查找,若是没有计算hash,再到对应的结点中取数据,再放到nearcache里。

参考:

http://www.oschina.net/p/hazelcast

http://www.hazelcast.org/docs/3.1/manual/html-single/

相关文章
相关标签/搜索