Apache Cassandra和Apache Ignite:關系并置和分布式SQL

為什么80%的碼農都做不了架構師?>>> ??hot3.png

在上一篇文章中,回顧和總結了Cassandra中使用的查詢驅動數據模型(或者說非常規數據模型)方法論的缺陷。事實證明,如果不對查詢有深入的了解,通過該方法論將無法開發高效的應用。實際上,這種場景的應用架構上會變得更加的復雜,難于維護,并且會造成很大的數據冗余。

此外,這個問題通常會被這樣的觀點掩蓋:“如果想要擴展性、速度以及高可用性,那么就得準備存儲多份數據,并且犧牲SQL和強一致性。”,這個論調十年前可能是正確的,但是現在完全錯誤!

沒那么夸張,我們選擇了另一個ASF成員,Apache Ignite。在本文中,會講解基于Ignite的應用架構,然后衡量它的維護成本。

我們選擇的應用仍然是跟蹤所有廠商生產的車輛,然后了解每個單一廠商的產能,如果看過第一篇文章,那么應該知道關系模型如下:

下一步,可以使用Ignite的CREATE TABLE命令創建這三個表,然后運行由SQL驅動的應用了么?不一定,如果不需要對存儲于不同表中的數據進行關聯操作,那么是可以的。但是根據前文,前提是應用需要支持兩種關聯的查詢:

  1. Q1:獲取一個廠商在特定的時間段內生產的車型。
  2. Q2:獲取一個廠商特定車型的產量。

在Cassandra的案例中,我們為每個查詢創建了一張表規避了關聯的問題,那么用Ignite,是不是還要經歷同樣的過程?完全不用。事實上,Ignite的非并置的關聯已經完全可用,如果三個表已經建好了,那么不需要什么額外的工作。但是,這沒有比并置的高效和快速。因此,首先要多學習一下關系并置,然后了解這個概念在Ignite中是如何使用的。

基于并置關聯的數據模型

關系并置在Ignite(還有其他的分布式數據庫,比如Google Spanner以及MemSQL)中是一個強大的概念,它可以在以一個集群節點上存儲相關的數據。那么哪些數據是相關的呢?尤其是在關系數據庫的背景下,這非常簡單,只需要在業務對象之間標示一個父子關系,在CREATE TABLE語句中指定一個關系鍵就可以了,剩下的就交給Ignite了!

還是拿車輛和廠商的應用舉例,使用廠商作為父實體,車輛作為子實體是合理的。比如,按照這樣配置好之后,某個廠商生產的所有車輛數據都會存儲于同一個節點上,如下圖所示:

如圖所示,豐田生產的車輛都存儲于節點1,而福特生產的車輛都存儲于節點2,這就是關系并置,車輛都會存儲于對應的廠商所在的節點上。

要做到這樣的數據分布,Vendor表的SQL定義如下:

CREATE TABLE Vendor (id INT PRIMARY KEY,name VARCHAR,address VARCHAR
);

廠商數據會在整個集群中隨機地分布,Ignite會使用主鍵列計算廠商數據所在的節點。 下一個是Car表:

CREATE TABLE Car (id INT,vendor_id INT,model VARCHAR,year INT,price float,PRIMARY KEY(id, vendor_id)
) WITH "affinityKey=vendor_id";

車輛表有一個affinityKey參數,配置為vendor_id列,它告訴Ignite,車輛存儲于vendor_id對應的集群節點。

Production表上重復同樣的過程,它的數據也是存儲于vendor_id對應的集群節點上,如下:

CREATE TABLE Production (id INT,car_id INT,vendor_id INT,country VARCHAR,total INT,year INT,PRIMARY KEY(id, car_id, vendor_id)
) WITH "affinityKey=vendor_id";

這樣數據模型就建完了,下一步就進入應用的代碼,然后開發必要的查詢。

帶關聯的SQL查詢

Ignite集群可以使用我們熟悉的SQL進行查詢,它支持分布式的SQL關聯以及二級索引。 Ignite支持兩種類型的關聯:并置和非并置。假定要關聯的表已經并置,并且本地數據全部可用,那么并置的關聯會避免數據(關聯所需的)的移動,這是在分布式數據庫中效率最高、性能最好的。如果部分表無法實現關系并置,但是還需要進行關聯,那么非并置的關聯就是一個備份計劃。這種類型的關聯速度較慢,因為在關聯時它需要在集群節點間進行數據的移動。

之前,已經配置好了VendorCarProduction表,下一步就是利用并置關聯的優勢,為Q1寫一個SQL:

SELECT c.model, p.country, p.total, p.year FROM Vendor as v
JOIN Production as p ON v.id = p.vendor_id
JOIN Car as c ON c.id = p.car_id
WHERE v.name = 'Ford Motor' and p.year >= 2017
ORDER BY p.year;

還能更快么?當然能。下面為Vendor.nameProduction.year列定義二級索引:

CREATE INDEX vendor_name_id ON Vendor (name);
CREATE INDEX prod_year_id ON Production (year);

針對Q2的查詢也不需要額外的工作:

SELECT p.country, p.total, p.year FROM Vendor as v
JOIN Production as p ON v.id = p.vendor_id
JOIN Car as c ON c.id = p.car_id
WHERE v.name = 'Ford Motor' and c.model = 'Explorer';

現在,如果老板要求增加一個新特性時,很快就能構造出一套新的SQL滿足他。 完成!作為比較,如果要支持Q2,可以看看基于Cassandra的架構是怎么搞的。

架構簡化:任務完成!

Ignite的基于關系并置的數據模型,針對Cassandra的基于查詢驅動的模型有如下的優點:

  • 應用的數據層基于熟悉的關系模型進行建模,易于維護;
  • 數據使用標準的SQL語法進行訪問;
  • 關系并置提供了現代分布式數據庫的更多好處:
    • 高效和高性能的分布式關聯;
    • 并置計算;

使用Ignite替代Cassandra,簡化的軟件架構并不是唯一的好處,過段時間,還會有關于強一致性和內存極性能方面的想法。

本文譯自Denis Magda的博客。

轉載于:https://my.oschina.net/liyuj/blog/1615008

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255579.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255579.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255579.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android高級開發專題晉升班

Android高級開發專題晉升班 適用人群:1-3年以上經驗的開發者丨學員平均薪酬20K/月轉載于:https://www.cnblogs.com/lythonliu/p/6285531.html

使用opencv簡單的播放AVI程序(40行)

學習OPENCV的第一個例子 #include <highgui.h> #include <cassert> #include <iostream> #include <Windows.h> using namespace std; void OnTrackbarSlide(int pos);int g_slider_position 0; CvCapture *g_capture NULL; int main(int argc , cha…

【糾錯】——mysql Authentication plugin ‘caching_sha2_password‘ is not supported問題處理

mysql Authentication plugin ‘caching_sha2_password’ is not supported問題處理 使用mysql8.0版本&#xff0c;登錄失敗&#xff0c;提示 Authentication plugin ‘caching_sha2_password’ is not supported。 原因是在MySQL 8.0以后&#xff0c;默認的密碼加密方式是cac…

關于EL表達式取值的問題

EL表達式取值時,如果沒有指定作用域,EL表達式會自動按照作用域的大小,從小到大依次去找;比如${s},會自動按照"pageContext,request,session,application"的順序去找屬性名為s的屬性.如果找到,則顯示.否則,什么都不顯示. 當Map中存整數時,如果想采用EL表達式取值,Map的…

統計信息自動收集任務失效原因排查

環境&#xff1a;Oracle 11.2.0.3 RAC問題&#xff1a;統計信息自動收集任務失效原因排查 1.查看自動任務的狀態2.進一步查看其它信息3.解決問題1.查看自動任務的狀態 查看自動任務的狀態&#xff0c;確認是enabled狀態&#xff1a; SQL> select client_name,status from db…

Markdown使用

#一級標題 ##二級標題 ###三級標題 斜體 粗體 斜體粗體 代碼段> 刪除內容效果是&#xff1a; 這是一級標題 這是二級標題 這是三級標題 這是斜體這是粗體這是斜體粗體 代碼段 FileInputStream is new FileInputStream("text"); byte[] iput new byte[1024]; is.…

灰度圖的width和widthstep的區別

灰度圖的width是表示圖像的每行像素數&#xff0c;widthstep指表示存儲一行像素需要的字節數。 在OpenCV里邊&#xff0c;widthStep必須是4的倍數&#xff0c;從而實現字節對齊&#xff0c;有利于提高運算速度。 如果8U單通道圖像寬度為3&#xff0c;那么widthStep是4&#xff…

【pyradiomics學習】——安裝pyradiomics以及簡單示例

目錄 數據集下載&#xff1a; 示例代碼 參考文獻&#xff1a; bug修復 運行結果&#xff1a; 數據集下載&#xff1a; https://www.jianguoyun.com/p/DcEwQq0Q45bOBxj09JYC (訪問密碼: gd8dmv) 示例代碼 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 20…

最新Django2.0.1在線教育零基礎到上線教程(九)

演示地址&#xff1a; http://mxonline.mtianyan.cn 教程倉庫地址1: https://github.com/mtianyan/DjangoGetStarted 教程倉庫地址2: https://github.com/mtianyan/Mxonline2 教程倉庫地址3: https://github.com/mtianyan/Mxonline3 9-1 講師列表頁 teacherlist 和 teacher det…

過濾器 攔截器 區別

轉 http://www.cnblogs.com/wangyuyu/archive/2013/07/02/3167354.html1、攔截器是基于java的反射機制的&#xff0c;而過濾器是基于函數回調 2、過濾器依賴與servlet容器&#xff0c;而攔截器不依賴與servlet容器 3、攔截器只能對action請求起作用&#xff0c;而過濾器則可以對…

php --魔術常量 /魔術方法

魔術常量&#xff1a;1. __LINE__返回文件中的當前行號。2. __FILE__返回所在文件的完整路徑。包含文件名3. __FUNCTION__返回所在函數名稱。4. __CLASS__返回所在類的名稱。5. __METHOD__返回所在類方法的名稱。需要注意__METHOD__返回的是"class::function"的形式&…

【pyradiomics學習】——影像組學特征

目錄 1、形狀特征&#xff08;14個&#xff09; 2、一階特征&#xff08;18個&#xff09; 灰度共生矩陣特征&#xff08;24個&#xff09; 灰度區域大小矩陣特征&#xff08;16個&#xff09; 灰度行程矩陣特征&#xff08;16個&#xff09; 鄰域灰度差矩陣特…

NLP系列學習:前向算法和后向算法

在上一篇文章里,我們簡單的概述了隱馬爾科夫模型的簡單定義在<CRF-tutorial>這一篇文章里,我們可以看到HMM經過發展之后是CRF產生的條件,因此我們需要學好隱馬爾科夫模型.在這一部分,我比較推薦閱讀宗成慶老師的<自然語言處理>這本書,這一部分宗老師寫的很不錯,相關…

Java日期處理 開始時間-結束時間查詢

//開始時間 timeBegin " 00:00:00"; //結束時間 timeEnd " 23:59:59"; //時間轉換 SimpleDateFormat format new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //Java時間類型轉換成Long類型(可封裝成工具類) public static Long stringToLong(St…

angular路由操作中'#'字符的解決辦法

var appangular.module("myapp",["ngRoute"]);app.controller("ctr",function($scope){});//angular1.6.0以上版本需要配置app.config(["$locationProvider",function($locationProvider){ $locationProvider.hashPrefix(""…

【TypeError: float() argument must be a string or a number, not ‘map’】

初始 相關系數過濾法調用函數 from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr SelectKBest(lambda X,Y:np.array(map(lambda x:pearsonr(x,Y),X.T)).T,k2) .fit_transform(X_test,y_test) TypeError: float() argument must be a strin…

CvScalar

CvScalar定義可存放1—4個數值的數值&#xff0c;其結構如下。 typedef struct CvScalar { doubleval[4]; } CvScalar; CvScalar pt&#xff1b; 如果使用的圖像是1通道的&#xff0c;則pt.val[0]中存儲數據 如果使用的圖像是3通道的&#xff0c;則pt.val[0]&#xff0c;pt…

UVA1493 - Draw a Mess(并查集)

UVA1493 - Draw a Mess(并查集) 題目鏈接 題目大意:一個N * M 的矩陣&#xff0c;每次你在上面將某個范圍上色&#xff0c;不論上面有什么顏色都會被最新的顏色覆蓋&#xff0c;顏色是1-9&#xff0c;初始的顏色是0.最后輸出這個矩形中。每一個顏色有多少個。某個范圍這個分為了…

Hyper-v Server 2012 Release Candidate 部署體驗

很多人知道&#xff0c;Microsoft Hyper-V分為兩種類型&#xff1a;一種是作為Windows Server的一個組件&#xff0c;另一種是作為虛擬化產品的單獨服務器。雖然兩者都是技術上的Hyper-V&#xff0c;每個版本的特性和用例各不相同。 Hyper-V Server直接在物理機器硬件上運行&am…

Unity 讀取資源(圖片)

方法一&#xff1a; 采用Resource.Load方法讀取&#xff0c;讀取在Unity中Assets下Resources目錄下的資源名&#xff08;不采用后綴&#xff09;。 //圖片放在Asset/Resources/ Texture2D tex (Texture2D)Resources.Load("圖片名稱"); 方法二&#xff1a; 采用WWW類…