開源中國的簡介:html
Hazelcast是一個高度可擴展的數據分發和集羣平臺。特性包括:java
簡介是美好的,現實是坑爹的。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 server集羣所有掛掉後,client竟然不會本身重連(重試3次就放棄了)。如今的各類組件重啓是很正常的事情,而hazelcast client竟然不會自動重連,真心使人無語。更加扯蛋的是,好比map.get,若是沒有鏈接上,會拋出一個RuntimeException,那麼整個線程都退出了。
3.0版本和3.0.2版本之間的配置格式竟然有很大的變化,不少時候,找個配置,得本身去看xml的xsd文件。。
這個我認爲是代碼太多致使的混亂。結點之間數據合併時,原本只要比較下數據的版本,時間等就能夠了,可是在合併時卻把對象反序化出來。若是在Server端沒有對應的jar包,則會拋出ClassNotFoundException。
參考這裏:
https://github.com/hazelcast/hazelcast/issues/1514
從原理上來講,hazelcast是默認有271個partition,這271個parition平均分佈在集羣裏的結點中,所以集羣裏的數據分散在每一個結點中。而後在進行操做時,先計算獲得key所在的partiion,再進行操做。
詳細請參考PartitionServiceImpl這個類的代碼:
hazelcast裏有一個所謂的nearcache的東東,其實這個很簡單,就是一個本地的二級緩存。在get的時候先到本地的nearcache裏查找,若是沒有計算hash,再到對應的結點中取數據,再放到nearcache裏。