1.概述
Apache Ignite和Apache Arrow很類似,屬於大資料範疇中的記憶體分散式管理系統。在《Apache Arrow 記憶體資料》中介紹了Arrow的相關內容,它統一了大資料領域各個生態系統的資料格式,避免了序列化和反序列化所帶來的資源開銷(能夠節省80%左右的CPU資源)。今天來給大家剖析下Apache Ignite的相關內容。
2.內容
Apache Ignite是一個以記憶體為中心的資料平臺,具有強一致性、高可用、強大的SQL、K/V以及其所對應的應用介面(API)。結構分佈圖如下所示:
在整個Ignite叢集中的多個節點中,Ignite記憶體中的資料模式有三種,分別是LOCAL、REPLICATED和PARTITIONED。這樣增加了Ignite的擴充套件性,Ignite可以自動化的控制資料如何分割槽,使用者也可以插入自定義的方法,或是為了提供效率將部分資料並存在一起。
Ignite和其他關係型資料庫具有相似的行為,但是在處理約束和索引方面略有不同。Ignite支援一級和二級索引,但是隻有一級索引支援唯一性。在持久化方面,Ignite固化記憶體在記憶體和磁碟中都能良好的工作,但是持久化到磁碟是可以禁用的,一般將Ignite作為一個記憶體資料庫來使用。
由於Ignite是一個全功能的資料網格,它既可以用於純記憶體模式,也可以帶有Ignite的原生持久化。同時,它還可以與任何第三方的資料庫整合,包含RDBMS和NoSQL。比如,在和Hadoop的HDFS、Kafka等,開發基於大資料平臺下的SQL引擎,來操作HDFS、Kafka這類的大資料儲存介質。
2.1 記憶體和磁碟
Apache Ignite是基於固化記憶體架構的,當Ignite持久化儲存特性開啟時,它可以在記憶體和磁碟中儲存和處理資料和索引。在固化記憶體和Ignite持久化儲存同時開啟時,具有以下優勢:
2.1.1 記憶體優勢
- 對外記憶體
- 避免顯著的GC暫停現象
- 自動化碎片清理
- 可預估的記憶體消耗
- 高SQL效能
2.1.2 磁碟優勢
- 可選的持久化
- 支援SSD介質
- 分散式儲存
- 支援事物
- 叢集瞬時啟動
2.2 持久化過程
Ignite的持久化儲存時一個分散式的、支援ACID、相容SQL的磁碟儲存。它作為一個可選的磁碟層,可以將資料和索引儲存到SSD這類磁碟介質,並且可以透明的與Ignite固化記憶體進行整合。Ignite的持久化儲存具有以下優勢:
- 可以在資料中執行SQL操作,不管資料在記憶體還是在磁碟中,這意味著Ignite可以作為一個經過記憶體優化的分散式SQL資料庫
- 可以不用講所有的資料和索引保持在記憶體中,持久化儲存可以在磁碟上儲存資料的大資料集合,然後只在記憶體中保持訪問頻繁的資料子集
- 叢集是瞬時啟動,如果整個叢集當機,不需要通過預載入資料來對記憶體進行資料“預熱”,只需要將所有叢集的節點都連線到一起,整個叢集即可正常工作
- 資料和索引在記憶體和磁碟中以相似的格式進行儲存,避免複雜的格式轉化,資料集只是在記憶體和磁碟之間進行移動
持久化流程如下圖所示:
2.3 分散式SQL記憶體資料庫
在Apache Ignite中提供了分散式SQL資料庫功能,這個記憶體資料庫可以水平擴充套件、容錯且相容標準的SQL語法,它支援所有的SQL及DML命令,包含SELECT、INSERT、DELETE等SQL命令。依賴於固化記憶體架構,資料集和索引可以同時在記憶體和磁碟中進行儲存,這樣可以跨越不同的儲存層執行分散式SQL操作,來獲得可以固化到磁碟的記憶體級效能。可以使用Java、Python、C++等原生的API來操作SQL與Ignite進行資料互動,也可以使用Ignite的JDBC或者ODBC驅動,這樣就具有了真正意義上的跨平臺連線性。具體架構體系,如下圖所示:
3.程式碼實踐
瞭解Apache Ignite的作用後,下面我們可以通過模擬編寫一個大資料SQL引擎,來實現對Kafka的Topic的查詢。首先需要實現一個KafkaSqlFactory的類,具體實現程式碼如下所示:
/** * TODO * * @author smartloli. * * Created by Mar 9, 2018 */ public class KafkaSqlFactory { private static final Logger LOG = LoggerFactory.getLogger(KafkaSqlFactory.class); private static Ignite ignite = null; private static void getInstance() { if (ignite == null) { ignite = Ignition.start(); } } private static IgniteCache<Long, TopicX> processor(List<TopicX> collectors) { getInstance(); CacheConfiguration<Long, TopicX> topicDataCacheCfg = new CacheConfiguration<Long, TopicX>(); topicDataCacheCfg.setName(TopicCache.NAME); topicDataCacheCfg.setCacheMode(CacheMode.PARTITIONED); topicDataCacheCfg.setIndexedTypes(Long.class, TopicX.class); IgniteCache<Long, TopicX> topicDataCache = ignite.getOrCreateCache(topicDataCacheCfg); for (TopicX topic : collectors) { topicDataCache.put(topic.getOffsets(), topic); } return topicDataCache; } public static String sql(String sql, List<TopicX> collectors) { try { IgniteCache<Long, TopicX> topicDataCache = processor(collectors); SqlFieldsQuery qry = new SqlFieldsQuery(sql); QueryCursor<List<?>> cursor = topicDataCache.query(qry); for (List<?> row : cursor) { System.out.println(row.toString()); } } catch (Exception ex) { LOG.error("Query kafka topic has error, msg is " + ex.getMessage()); } finally { close(); } return ""; } private static void close() { try { if (ignite != null) { ignite.close(); } } catch (Exception ex) { LOG.error("Close Ignite has error, msg is " + ex.getMessage()); } finally { if (ignite != null) { ignite.close(); } } } }
然後,模擬編寫一個生產者來生產資料,並查詢資料集,實現程式碼如下所示:
public static void ignite(){ List<TopicX> collectors = new ArrayList<>(); int count = 0; for (int i = 0; i < 10; i++) { TopicX td = new TopicX(); if (count > 3) { count = 0; } td.setPartitionId(count); td.setOffsets(i); td.setMessage("hello_" + i); td.setTopicName("test"); collectors.add(td); count++; } String sql = "select offsets,message from TopicX where offsets>6 and partitionId in (0,1) limit 1"; long stime = System.currentTimeMillis(); KafkaSqlFactory.sql(sql, collectors); System.out.println("Cost time [" + (System.currentTimeMillis() - stime) / 1000.0 + "]ms"); }
執行結果如下所示:
4.總結
Apache Ignite整體來說,它基本把現在分散式的一些概念都整合了,包含分散式儲存、分散式計算、分散式服務、流式計算等等。而且,它對Java語言的支援,與JDK能夠很好的整合,能夠很友好的相容JDK的現有API,當你開啟一個執行緒池,你不需要關係是本地執行緒池還是分散式執行緒池,只管提交任務就行。Apache Ignite在與RDBMS、Hadoop、Spark、Kafka等傳統關係型資料庫和主流大資料套件的整合,提供了非常靈活好用的元件API。
5.結束語
這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉!