Hazelcast入门
7月,我寫了一個(gè)博客向Java開(kāi)發(fā)人員介紹erlang,重點(diǎn)介紹了這兩種語(yǔ)言之間的一些異同。 erlang虛擬機(jī)具有許多令人印象深刻的內(nèi)置功能,其中之一是它們獨(dú)立于位置并且可以互相通信。 這意味著可以通過(guò)編寫很少的代碼行在VM之間同步數(shù)據(jù)。 如果您有一個(gè)網(wǎng)絡(luò)集群的服務(wù)器都在做相同的事情,這真是個(gè)好消息。
您可能會(huì)爭(zhēng)辯說(shuō),即使JVM無(wú)法執(zhí)行最基本的進(jìn)程間通信,也可能缺少某些東西。 但是,Java卻持相反的觀點(diǎn),它具有基本的VM,然后在需要時(shí)在其上分層放置不同的服務(wù)。 這是否正確只是一個(gè)見(jiàn)解,我將其作為未來(lái)博客的主題,因?yàn)镠azelcast Guys似乎已經(jīng)解決了JVM之間相互交談的問(wèn)題; 這是本博客的重點(diǎn)。
那么,什么是Hazelcast?
Hazelcast新聞稿是這樣的:“ Hazelcast( www.hazelcast.com )正在通過(guò)開(kāi)放源代碼重塑內(nèi)存數(shù)據(jù)網(wǎng)格。 Hazelcast提供了一個(gè)嵌入式庫(kù),任何Java開(kāi)發(fā)人員都可以在幾分鐘之內(nèi)包含該庫(kù),從而使他們能夠構(gòu)建優(yōu)雅而簡(jiǎn)單的關(guān)鍵任務(wù),事務(wù)性和萬(wàn)億級(jí)內(nèi)存應(yīng)用程序。”
那么,這到底意味著什么?
好的,那只是營(yíng)銷/公關(guān)障礙。 在現(xiàn)實(shí)生活中,什么是Hazelcast? 可以使用代碼簡(jiǎn)潔地給出答案。 假設(shè)您正在編寫一個(gè)應(yīng)用程序,并且需要一個(gè)Map<String,String>而在生產(chǎn)環(huán)境中,您將在集群中擁有多個(gè)應(yīng)用程序?qū)嵗?然后編寫以下代碼:
HazelcastInstance instance = Hazelcast.newHazelcastInstance(); loggedOnUsers = instance.getMap("Users");…意味著由您的應(yīng)用程序的一個(gè)實(shí)例添加到地圖的數(shù)據(jù)可用于您的應(yīng)用程序的所有其他實(shí)例2
您可以從中得出幾點(diǎn)。 首先,Hazelcast節(jié)點(diǎn)是“無(wú)主節(jié)點(diǎn)”,這意味著它不是客戶端-服務(wù)器系統(tǒng)。 有一個(gè)集群領(lǐng)導(dǎo)者,默認(rèn)情況下是集群中最老的成員,它負(fù)責(zé)管理數(shù)據(jù)在系統(tǒng)中的分布方式。 但是,如果該節(jié)點(diǎn)發(fā)生故障,則下一個(gè)最舊的節(jié)點(diǎn)將接管。
擁有一堆分布式的地圖,列表,隊(duì)列等,意味著一切都保存在內(nèi)存中。 如果集群中的一個(gè)節(jié)點(diǎn)死亡,那么您就可以了,不會(huì)有數(shù)據(jù)丟失; 但是,如果多個(gè)節(jié)點(diǎn)同時(shí)死亡,那么您將遇到麻煩,并且由于系統(tǒng)沒(méi)有時(shí)間重新平衡自身,您將丟失數(shù)據(jù)。 不用說(shuō),如果整個(gè)集群都死了,那么您將遇到大麻煩。
那么,為什么Hazelcast是個(gè)好選擇?
場(chǎng)景
為了演示Hazelcast,請(qǐng)想象您正在編寫一個(gè)應(yīng)用程序,在這種情況下,該應(yīng)用程序由MyApplication類建模,然后有一個(gè)很大的用戶世界,由BigWideWorld類建模。 正如預(yù)期的那樣,來(lái)自BigWideWorld用戶登錄并注銷了您的應(yīng)用程序。 您的應(yīng)用程序非常受歡迎,并且您正在集群中運(yùn)行它的多個(gè)實(shí)例,因此,當(dāng)用戶登錄該應(yīng)用程序的實(shí)例時(shí),它將其詳細(xì)信息(由User類建模)存儲(chǔ)在Map以及Map的內(nèi)容與您的應(yīng)用程序其他實(shí)例保存的地圖同步。
POM配置
首先要做的是設(shè)置POM.xml,只有一個(gè)條目需要考慮:
<dependency><groupId>com.hazelcast</groupId><artifactId>hazelcast</artifactId><version>3.1</version></dependency>編碼
BigWideWorld是代碼的起點(diǎn),對(duì)于這么大的概念而言,這是一個(gè)很小的類。 它有一個(gè)方法nextUser() ,它從應(yīng)用程序所有用戶的集合中隨機(jī)選擇下一個(gè)要登錄或注銷的用戶的名稱。
public class BigWideWorld { private static Random rand = new Random(System.currentTimeMillis()); private final Users users = new Users(); private final int totalNumUsers = users.size(); public String nextUser() { User user = users.get(rand.nextInt(totalNumUsers)); String name = user.getUsername(); return name; } }用戶集合由Users類管理。 這是一個(gè)示例代碼便捷類,其中包含許多硬編碼用戶的詳細(xì)信息。
public class Users { /** The users in the database */ private final User[] users = { new User("fred123", "Fred", "Jones", "fredj@a.com"), new User("jim", "Jim", "Jones", "jimj@a.com"), new User("bill", "Bill", "Jones", "bill@a.com"), new User("ted111", "Edward", "Jones", "tedj@a.com"), new User("annie", "Annette", "Jones", "annj@a.com"), new User("lucy", "Lucy", "Jones", "lucyj@a.com"), new User("jimj", "James", "Jones", "jimj@a.com"), new User("jez", "Jerry", "Jones", "fredj@a.com"), new User("will", "William", "Jones", "willj@a.com"), new User("shaz", "Sharon", "Jones", "shazj@a.com"), new User("paula", "Paula", "Jones", "pauj@a.com"), new User("leo", "Leonardo", "Jones", "leoj@a.com"), }; private final Map<String, User> userMap; public Users() { userMap = new HashMap<String, User>(); for (User user : users) { userMap.put(user.getUsername(), user); } } /** * The number of users in the database */ public int size() { return userMap.size(); } /** * Given a number, return the user */ public User get(int index) { return users[index]; } /** * Given the user's name return the User details */ public User get(String username) { return userMap.get(username); } /** * Return the user names. */ public Set<String> getUserNames() { return userMap.keySet(); } }此類包含一些數(shù)據(jù)庫(kù)類型的調(diào)用,例如get(String username)返回給定名稱的用戶對(duì)象,或者get(int index)返回?cái)?shù)據(jù)庫(kù)中的給定用戶,或者size()返回?cái)?shù)字。數(shù)據(jù)庫(kù)中的用戶數(shù)量。
用戶由User類描述; 一個(gè)簡(jiǎn)單的Java bean:
public class User implements Serializable { private static final long serialVersionUID = 1L; private final String username; private final String firstName; private final String lastName; private final String email; public User(String username, String firstName, String lastName, String email) { super(); this.username = username; this.firstName = firstName; this.lastName = lastName; this.email = email; } public String getUsername() { return username; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String getEmail() { return email; } @Override public String toString() { StringBuilder sb = new StringBuilder("User: "); sb.append(username); sb.append(" "); sb.append(firstName); sb.append(" "); sb.append(lastName); sb.append(" "); sb.append(email); return sb.toString(); } }繼續(xù)討論博客的癥結(jié)所在,這就是MyApplication類。 本博客中的大多數(shù)代碼只是櫥窗裝飾,重要的代碼在MyApplication的構(gòu)造函數(shù)中。 該構(gòu)造包含兩行代碼。 第一個(gè)使用新的Hazelcast實(shí)例,而第二個(gè)使用該實(shí)例創(chuàng)建名稱空間為“ Users”的Map<String, User> 。 這就是所需的所有Hazelcast特定代碼。 其他方法: logon() , logout()和isLoggedOn()僅管理用戶。
使用簡(jiǎn)單的Main類將以上所有內(nèi)容捆綁在一起:
public class Main { public static void main(String[] args) throws InterruptedException { BigWideWorld theWorld = new BigWideWorld(); MyApplication application = new MyApplication(); while (true) { String username = theWorld.nextUser(); if (application.isLoggedOn(username)) { application.logout(username); } else { application.logon(username); } application.displayUsers(); TimeUnit.SECONDS.sleep(2); } } }此代碼創(chuàng)建BigWideWorld和MyApplication的實(shí)例。 然后,它無(wú)限循環(huán)地抓住下一個(gè)隨機(jī)用戶名。 如果用戶已經(jīng)登錄,則該用戶注銷。 如果用戶未登錄,則該用戶登錄。然后將顯示已登錄的用戶,以便您查看正在發(fā)生的情況。
運(yùn)行應(yīng)用
構(gòu)建應(yīng)用程序后,打開(kāi)終端并導(dǎo)航到project target/classes目錄。 然后輸入以下命令:
java -cp /your path to the/hazelcast-3.1/lib/hazelcast-1.jar:. com.captaindebug.hazelcast.gettingstarted.Main運(yùn)行時(shí),您將獲得如下所示的輸出:
Logged on users: User: fred123 Fred Jones fredj@a.com User: jimj James Jones jimj@a.com User: shaz Sharon Jones shazj@a.com User: paula Paula Jones pauj@a.com User: lucy Lucy Jones lucyj@a.com User: jez Jerry Jones fredj@a.com User: jim Jim Jones jimj@a.com 7 -- 14:54:16-17接下來(lái),打開(kāi)更多終端并運(yùn)行您的應(yīng)用程序的更多實(shí)例。
如果您跟蹤輸出,則可以看到用戶登錄和注銷,并且每次更改都顯示用戶Map 。 一個(gè)應(yīng)用程序的地圖更改反映在其他實(shí)例中的線索可能很難發(fā)現(xiàn),但可以從地圖的總大小(輸出最后一行的第一個(gè)數(shù)字)中得出。 每次顯示地圖時(shí),都會(huì)有一個(gè)用戶登錄或注銷。 但是,總大小可能會(huì)改變一個(gè)以上,這意味著其他實(shí)例的更改已影響您正在查看的地圖的大小。
因此,您有一個(gè)簡(jiǎn)單的應(yīng)用程序,當(dāng)四個(gè)實(shí)例正在運(yùn)行時(shí),它們保持同步并知道哪些用戶已登錄。
 它應(yīng)該可以在大型群集中工作,但我從未嘗試過(guò)。 顯然,在大型集群中,您必須對(duì)配置文件進(jìn)行一些改動(dòng),但這超出了本博客的范圍。 
 1好的,足夠的市場(chǎng)營(yíng)銷能力。 總的來(lái)說(shuō),它確實(shí)是“有效的”,但是請(qǐng)記住,它是由像您和我這樣的開(kāi)發(fā)人員編寫的軟件,它確實(shí)具有功能和特質(zhì) 。 舉例來(lái)說(shuō),如果你還在使用2.4版本,然后立即升級(jí)。 這會(huì)有內(nèi)存泄漏,這意味著它在感覺(jué)到時(shí)“只是默默地停止工作”。 最新版本是3.1。 
2我選擇了Map作為示例,但對(duì)于其他集合類型(如List , Set和Queue也是如此,另外,Hazelcast還具有許多其他功能,這些功能超出了本博客的范圍,包括大量并發(fā)實(shí)用程序和發(fā)布/訂閱消息傳遞。
- 該博客的代碼可在github上找到: https : //github.com/roghughe/captaindebug/tree/master/hazelcast
翻譯自: https://www.javacodegeeks.com/2013/11/getting-started-with-hazelcast.html
總結(jié)
以上是生活随笔為你收集整理的Hazelcast入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Mac电脑如何调整桌面图标的大小如何改变
- 下一篇: 手机圈的金九银十来了 苹果、华为、蔚来领
