Ignite的數據網格是圍繞着基於內存的分佈式key/value存儲能力打造的。當初技術選型的時候,決定用Ignite也是由於雖然一樣是key/value存儲,它有着和其餘key/value存儲系統不一樣的特性。根據官網的介紹,Ignite在設計之初,就是爲了能方便的水平擴展而設計的。Ignite將數據分片,每一個節點只存儲數據的一部分,這樣每當有新節點加入時,整個集羣能夠存儲更多的數據。爲了提升可用性,Ignite也支持用不一樣的策略對數據分片進行冗餘備份,這樣保證數據不會由於集羣中一兩個節點失效而丟失。另外,和其餘key/value緩存系統最大的不一樣是,Ignite支持用SQL語句對緩存數據進行查詢。正是因爲有對SQL 99的支持,咱們甚至能夠把Ignite當作一個分佈式內存數據庫來使用。java
從這篇文章開始,咱們先聚焦在Ignite提供的數據網格服務上,看看一樣是基於key/value存儲,Ignite的key/value緩存又提供了哪些能力。node
在介紹Ignite不一樣的緩存冗餘備份模式以前,咱們先用上一篇文章的代碼來模擬一下在默認配置下,若是Ignite集羣中有節點失效,咱們的數據是否還完整有效。咱們在同一臺虛擬機按如下的順序分別啓動server和client實例:git
Montreal is in Quebec Edmonton is in Alberta Markham is in Ontario Toronto is in null
Montreal is in Quebec Edmonton is in Alberta Markham is in null Toronto is in null
由於Ignite將緩存數據分片存儲的,即同一緩存中的不一樣數據存到不一樣的server節點上,Ignite經過一個哈希算法計算出某個數據分片所屬的節點。除了原生的哈希算法,用戶也可實現本身的哈希算法來決定數據分片對應的節點。在上面的步驟1中,緩存數據所有存在僅有的惟一一個server實例中。在步驟2中,當有新的server實例加入集羣,Ignite經過默認的哈希算法決定哪部分的數據分片應該存到新加入的server實例中,而後將數據在兩個實例間從新平衡分佈。因爲咱們採用的是默認的配置,因此每一個數據分片只有一份拷貝,這就是爲何當咱們關了一個server實例後會發生數據丟失的狀況。所以,爲了保證數據的高可用,咱們必須調整數據分片拷貝的數量。接下來,咱們就來看看Ignite提供了哪些對數據分片進行冗餘備份的策略,以便用戶根據實際需求在性能和數據高可用性之間作選擇。算法
咱們先從簡單的模式提及,Local模式,顧名思義就是緩存的全部數據只保存在本地節點,數據不會分佈到其餘節點上,也就沒有數據分片和數據拷貝這麼一說。Local模式的最大好處是它的輕量化,由於沒有了數據分片和冗餘備份的負擔,其很是適合於數據只讀模式和須要按期刷新的場景,也適合於做爲一個read-through的緩存。除了數據分佈不一樣,採用local模式的緩存和分佈式緩存有着相同的功能,好比數據自動清除,過時失效,磁盤交換,數據查詢以及事務等特性。spring
Replicated模式下,緩存數據雖然被均分爲多個數據分片,但每一個節點上都有該緩存的所有數據分片。下面這張官網圖很好的展現了replicated模式的數據分佈:
數據庫
在replicated模式下,緩存數據被平分爲4個數據分片A、B、C、D。在節點1(JVM1)上有分片A的primary拷貝和B、C、D的backup拷貝。在節點2(JVM2)上有分片C的primary拷貝和A、B、D的backup拷貝。節點3(JVM3)和節點4(JVM4)的狀況也相似。關於數據分片的primary和backup拷貝的概念咱們在下一篇介紹,這裏只要記住當primary拷貝失效了,Ignite能夠用backup拷貝恢復數據,保證了數據的高可靠性。因此在replicated模式下,每一個節點其實有緩存的全部數據分片拷貝,即使集羣裏其餘節點都失效,Ignite仍是能夠經過僅存的一個節點提供數據讀寫服務apache
Partition模式下,緩存數據被均分爲多個數據分片,數據分片的拷貝均等的分佈在集羣的某些節點上。換句話說,和replicated模式最大的不一樣就是,一個節點上沒有所有的緩存數據分片拷貝。讓咱們借用官網的圖來解釋一下partitioned模式:
緩存
如上圖所示,在partitioned模式下,緩存數據被平分爲4個數據分片A、B、C、D,每一個數據分片有一份primary拷貝和backup拷貝,因此每一個節點只保存兩個數據分片的拷貝,好比節點1(JVM1)有分片A的primary分片和分片B的backup分片,節點2(JVM2)有分片C的primary分片和分片A的backup分片。Backup拷貝的數量是用戶可配置的,若是配置爲0時,表明着一個數據分片沒有副本,一旦某個節點掛了,數據就會丟失。若是配置爲(集羣節點數量-1),表明着集羣的每一個節點上都有一份該數據分片的拷貝,這就至關於一種特殊的replicated模式。拷貝數量越多,表明數據約可靠,但也會帶來額外的開銷,因此咱們仍是要根據實際的場景和需求來調整拷貝數量。maven
讓咱們簡單的比較下兩種模式的優缺點以及它們適合的場景:tcp
好了,在瞭解完Ignite緩存不一樣的數據分片冗餘策略後,讓咱們經過一個實際的例子看看如何在代碼或是xml配置文件中配置不一樣的數據分片冗餘策略。咱們在上一篇文章的server節點代碼上進行改造,大部分邏輯都保持不變,重點注意一下第26行~34行加入的新代碼:
public class IgniteCacheOpModeExample { public static void main(String[] args) { Ignite ignite; // 建立一個TEST緩存並寫入一些數據, key是城市的名字,value是省的名字 IgniteCache<String, String> cityProvinceCache; if(args.length == 1 && !args[0].isEmpty()) { //若是啓動時指定了配置文件,則用指定的配置文件 System.out.println("Use " + args[0] + " to start."); ignite = Ignition.start(args[0]); //配置文件中,咱們將緩存設置爲partitioned模式,backup數量爲1 cityProvinceCache = ignite.getOrCreateCache("TEST"); } else { //若是啓動時沒指定配置文件,則生成一個配置文件 System.out.println("Create an IgniteConfiguration to start."); TcpDiscoverySpi spi = new TcpDiscoverySpi(); TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder(); ipFinder.setMulticastGroup("224.0.0.251"); spi.setIpFinder(ipFinder); IgniteConfiguration cfg = new IgniteConfiguration(); cfg.setDiscoverySpi(spi); ignite = Ignition.start(cfg); CacheConfiguration<String, String> cacheCfg = new CacheConfiguration("TEST"); // 若是不用配置文件啓動,緩存模式被設置爲replicated cacheCfg.setCacheMode(CacheMode.REPLICATED); /* 下面的配置將"TEST"緩存設爲partitioned模式,而且設置了backup數量爲1,這樣保證即便有一個node出現 故障的狀況下,緩存數據仍是完整可用的 cacheCfg.setCacheMode(CacheMode.PARTITIONED); cacheCfg.setBackups(1); */ cityProvinceCache = ignite.getOrCreateCache(cacheCfg); } cityProvinceCache.put("Edmonton", "Alberta"); cityProvinceCache.put("Markham", "Ontario"); cityProvinceCache.put("Montreal", "Quebec"); } }
在調用ignite.getOrCreateCache()函數以前,咱們爲"TEST"先生成一個CacheConfiguration,而後調用setCacheMode()將其模式設置爲REPLICATED模式(在29~33行被註釋掉的代碼中,是如何設置PARTITIONED模式以及backups數量的代碼),最後再交由Ignite根據configuration生成"TEST"緩存。 固然,和上一篇同樣,也能夠經過XML文件來配置緩存模式:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"> <property name="discoverySpi"> <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi"> <property name="ipFinder"> <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder"> <property name="multicastGroup" value="224.0.0.251"/> </bean> </property> </bean> </property> <property name="cacheConfiguration"> <bean class="org.apache.ignite.configuration.CacheConfiguration"> <!-- 設置緩存名字. --> <property name="name" value="TEST"/> <!-- 設置緩存模式. --> <property name="cacheMode" value="PARTITIONED"/> <property name="backups" value="1"/> <!-- 下面將緩存設置爲replicated模式 --> <!--property name="cacheMode" value="REPLICATED"/--> </bean> </property> </bean> </beans>
在XML文件中,咱們加入了cacheConfiguration的配置,爲了和代碼裏建立的緩存名字保持一致,配置裏也使用了"TEST"做爲緩存名字,"cacheMode"設爲PARTITIONED,"backups"值設爲了1(每一個數據分片除了primay拷貝外,還有額外的一份backup拷貝,即緩存能夠容許有一個節點故障而保證緩存數據的完整性)。
更新了代碼和配置文件後,server節點若是制定了XML配置文件啓動,生成的緩存爲帶一個backup的PARTITIONED模式,若是不用XML配置文件,則生成的緩存爲REPLICATED模式。不管用哪一種方式啓動server節點,咱們再重複這篇文章開頭的那個實驗,就會發現即便在一個節點失效的狀況下,client節點仍是能夠訪問到緩存中的全部數據,不會再出現丟數據的狀況了。在實際使用過程當中,正確的配置緩存的冗餘模式直接影響到Ignite集羣數據的高可用性。
這篇文章咱們介紹了Ignite集羣中數據分片的不一樣冗餘策略,在實際的使用過程當中,不一樣的策略會直接影響集羣中數據的高可用性和讀寫性能,因此理解不一樣的策略的優缺點,是使用好Ignite數據網格集羣的第一步。 這篇文章裏用到的例子的完整代碼和maven工程能夠在這裏找到。 Server對應的xml配置文件在src/main/resources目錄下。
下一篇,咱們將繼續瞭解一下Ignite針對不一樣的冗餘策略提供的功能,好比數據分片因爲節點失效出現丟失時的行爲,primary拷貝和backup拷貝以前的同步等。