1. 簡介
Apache Ignite 內存數據組織框架是一個高性能、集成化和分佈式的內存計算和事務平臺,用於大規模的數據集處理,比傳統的基於磁盤或閃存的技術具有更高的性能,同時他還爲應用和不同的數據源之間提供高性能、分佈式內存中數據組織管理的功能。具體介紹可參考官方中文教程。
2. 安裝
從 https://ignite.apache.org/download.cgi#binaries 下載最新的安裝包,這裏我下載的是 apache-ignite-fabric-2.4.0-bin.zip 包。下載後解壓就可以直接使用了。
3. 運行
進入安裝路徑的bin目錄,然後輸入:ignite.sh即可啓動ignite服務,輸入幾次就會啓動幾個集羣節點。如下,我輸入三次即啓動了3個ignite集羣節點。
下面是啓動成功的界面:
其中:
- servers=1 表示當前 Ignite 集羣中只有一個節點。
- clients=0 表示當前沒有客戶端連接到此集羣。
圖中紅線框可以看到 servers=3,說明有2個新節點加入了集羣。
4. 測試
1)用eclipse新建一個動態web項目,並導入相關包。項目結構如下:
2)建一個測試java類,代碼如下:
package com.ignite.test;
import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.lang.IgniteFuture;
public class SimpleCache {
public static void main(String[] args){
// 以client的模式啓動ignite, 數據存儲到前面已經啓動的ignite節點上
Ignition.setClientMode(true);
try(Ignite ignite = Ignition.start()){
// 緩存配置
CacheConfiguration<Integer, String> cacheCfg = new CacheConfiguration<Integer, String>();
cacheCfg.setName("myCache");
// 設置緩存過期時間
cacheCfg.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ONE_MINUTE));
/**
* 緩存系統中的存儲和獲取是同步操作
* 在ignite集羣中創建名稱爲simple的分佈式緩存。第二次啓動時,
* 名稱爲simple的緩存已經存在獲取該緩存,把put語句註釋掉仍然可以獲取到值
*/
// 如果緩存不存在就創建,如果已存在就獲取緩存
/* IgniteCache<Integer,String> cache = ignite.getOrCreateCache("simple");
for(int i = 0; i < 10; i++){
cache.put(i, i+"haha");
}
for(int i=0; i< 10; i++){
System.out.println(cache.get(i));
}*/
/**
* 異步操作
*/
/*IgniteCache<Integer, String> simple =
ignite.getOrCreateCache("simple");
// 啓動異步操作
@SuppressWarnings("deprecation")
IgniteCache<Integer, String> asynCache = simple.withAsync();
// 原子操作 獲取舊值 存入新值
asynCache.getAndPut(33, "3332");
// 獲取上面調用的future
@SuppressWarnings("deprecation")
IgniteFuture<Integer> fut = asynCache.future();
// 監聽結果
fut.listen(f -> System.out.println("Previous cache value: " + f.get()));*/
/**
* 原子操作
*/
IgniteCache<Integer, String> simple =ignite.getOrCreateCache("simple");
// 插入或更新 返回舊值
String oldVal = simple.getAndPut(11, "haha");
// 如果不存在則插入 返回舊值
oldVal = simple.getAndPutIfAbsent(11, "11 getAndPutIfAbsent2");
// 如果存在則替換 返回舊值
oldVal = simple.getAndReplace(11, "11 getAndReplace");
// 刪除鍵值對 返回舊值
oldVal = simple.getAndRemove(11);
// 如果不存在則插入 成功返回true
boolean success = simple.putIfAbsent(12, "12 putIfAbsent");
// 如果存在則替換 成功返回 true
success = simple.replace(12, "12 replace");
// 如果值匹配 則替換 成功返回true
success = simple.replace(12, "12 replace", "12 12 12");
// 如果值匹配則刪除 成功返回true
success = simple.remove(11, "11");
//獲取緩存數據並輸出
for(int i=0; i< 20; i++){
if(simple.get(i)==null) {
continue;
}else {
System.out.println(simple.get(i));
}
}
}
}
}
3)運行結果如下:
OK! 簡單的一個項目就搞定了!
5. 單純的從Ignite內存庫中取數據
import com.alibaba.fastjson.JSON;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by xudasong on 2018/4/23.
* 獲取高速緩存中的數據
*/
public class GetDataTest {
public static void main(String[] args) {
try {
Class.forName("org.apache.ignite.IgniteJdbcThinDriver");
// Open JDBC connection 打開到集羣節點的連接,監聽地址可爲本地(或其它服務器)
Connection conn = DriverManager.getConnection("jdbc:ignite:thin://10.16.5.229/");
// ResultSet rs = conn.createStatement().executeQuery("select * from GPSCACHE.GPSData");
ResultSet rs = conn.createStatement().executeQuery("select * from person");
Map<String, Object> map = new HashMap<>();
//將ResultSet結果集轉換成List
List nameList=convertList(rs);
//將List結果集存入map中
map.put("peopleNames",nameList);
//將map轉換成Json格式
String jsonString= JSON.toJSONString(map);
System.out.println(jsonString);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
//將ResultSet結果集轉換成List方法定義
private static List convertList(ResultSet rs) throws SQLException{
List list = new ArrayList();
ResultSetMetaData md = rs.getMetaData();//獲取鍵名
int columnCount = md.getColumnCount();//獲取行的數量
while (rs.next()) {
Map rowData = new HashMap();//聲明Map
for (int i = 1; i <= columnCount; i++) {
rowData.put(md.getColumnName(i), rs.getObject(i));//獲取鍵名及值
System.out.println(md.getColumnName(i)+' '+rs.getObject(i));
}
list.add(rowData);
}
return list;
}
}
6. Ignite內存數據庫可視化工具
DBeaver作爲一個示例,是一個針對開發者和數據庫管理員的免費開源的統一數據庫工具,它支持包括Ignite在內的所有常見數據庫。 下載地址:https://dbeaver.jkiss.org/download/
Ignite有自己的JDBC驅動實現,DBeaver可以用其處理存儲於分佈式集羣中的數據。
具體配置查看:https://www.zybuluo.com/liyuj/note/1023980
官方文檔:https://www.zybuluo.com/liyuj/note/785629
可以參考的博文:Apache Ignite學習筆記:創建緩存、存儲數據、讀取緩存
7.關於Ignite相關配置需要注意的幾點
1)靜態集羣配置:
服務端配置(如果多個節點集羣可以用逗號分隔如<value>10.16.4.110,10.16.5.111</value>):
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!--
IP Address and optional port range of a remote node.
You can also optionally specify an individual port.
-->
<value>10.16.4.110:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
同時客戶端也要進行相同配置,不能使用默認的組播方式,如果報異常請注意標有《注意此處》部分配置,對端自動傳輸類。
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="cacheConfiguration">
<list>
<!-- Partitioned cache example configuration (Atomic mode). -->
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="default"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="backups" value="1"/>
</bean>
</list>
</property>
<!-- 注意此處 -->
<property name="peerClassLoadingEnabled" value="false"></property>
<!-- Explicitly configure TCP discovery SPI to provide list of initial nodes. -->
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!--
IP Address and optional port range of a remote node.
You can also optionally specify an individual port.
-->
<value>10.16.4.110:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
2)內存配置:
下面配置默認使用4G內存(應該自動使用堆外內存):
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<!-- Redefining the default region's settings -->
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="name" value="Default_Region"/>
<property name="initialSize" value="#{100 * 1024 * 1024}"/>
<!-- Setting the size of the default region to 4GB. -->
<property name="maxSize" value="#{4L * 1024 * 1024 * 1024}"/>
<property name="persistenceEnabled" value="false"/>
<property name="pageEvictionMode" value="RANDOM_2_LRU"/>
</bean>
</property>
</bean>
</property>
配置堆堆外內存要將持久化置爲false,另外在java運行參數中增加最大堆外內存分配大小(ignite.bat中),否則java默認的堆外內存太小(應該是64M):
if %ERRORLEVEL% equ 0 (
if "%JVM_OPTS%" == "" set JVM_OPTS=-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxPermSize=256m -XX:MaxDirectMemorySize=3g
) else (
if "%JVM_OPTS%" == "" set JVM_OPTS=-Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxMetaspaceSize=256m -XX:MaxDirectMemorySize=3g
)
3)2.6版本開始支持java瘦客戶端模式,但還不支持異步。