99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀使用Spark+Cassandra打造高性能數(shù)據(jù)分析平臺(一)
使用Spark+Cassandra打造高性能數(shù)據(jù)分析平臺(一)
2014-11-24
收藏


使用Spark+Cassandra打造高性能數(shù)據(jù)分析平臺(一)



看Spark源碼的時間不長,記筆記的初衷只是為了不至于日后遺忘。在源碼閱讀的過程中秉持著一種非常簡單的思維模式,就是努力去尋找一條貫穿全局的主線索。在筆者看來,Spark中的線索就是如果讓數(shù)據(jù)的處理在分布式計算環(huán)境下是高效,并且可靠的。

在對Spark內(nèi)部實現(xiàn)有了一定了解之后,當然希望將其應(yīng)用到實際的工程實踐中,這時候會面臨許多新的挑戰(zhàn),比如選取哪個作為數(shù)據(jù)倉庫,是HBase、MongoDB還是Cassandra。即便一旦選定之后,在實踐過程還會遇到許多意想不到的問題。

要想快速的解決開發(fā)及上線過程中遇到的系列問題,還需要具備相當深度的Linux知識,恰巧之前工作中使用Linux的經(jīng)驗在大數(shù)據(jù)領(lǐng)域中還可以充分使用。

筆者不才,就遇到的一些問題,整理出來與諸君共同分享。

1. Cassandra

NoSQL數(shù)據(jù)庫的選擇之痛,目前市面上有近150多種NoSQL數(shù)據(jù)庫,如何在這么龐雜的隊伍中選中適合業(yè)務(wù)場景的佼佼者,實非易事。

好的是經(jīng)過大量的篩選,大家比較肯定的幾款NoSQL數(shù)據(jù)庫分別是HBase、MongoDB和Cassandra。

Cassandra在哪些方面吸引住了大量的開發(fā)人員呢?下面僅做一個粗略的分析。

1.1 高可靠性

Cassandra采用gossip作為集群中結(jié)點的通信協(xié)議,該協(xié)議整個集群中的節(jié)點都處于同等地位,沒有主從之分,這就使得任一節(jié)點的退出都不會導(dǎo)致整個集群失效。

Cassandra和HBase都是借鑒了Google BigTable的思想來構(gòu)建自己的系統(tǒng),但Cassandra另一重要的創(chuàng)新就是將原本存在于文件共享架構(gòu)的p2p(peer to peer)引入了NoSQL。

P2P的一大特點就是去中心化,集群中的所有節(jié)點享有同等地位,這極大避免了單個節(jié)點退出而使整個集群不能工作的可能。

與之形成對比的是HBase采用了Master/Slave的方式,這就存在單點失效的可能。

1.2 高可擴性

隨著時間的推移,集群中原有的規(guī)模不足以存儲新增加的數(shù)據(jù),此時進行系統(tǒng)擴容。Cassandra級聯(lián)可擴,非常容易實現(xiàn)添加新的節(jié)點到已有集群,操作簡單。

1.3 最終一致性

分布式存儲系統(tǒng)都要面臨CAP定律問題,任何一個分布式存儲系統(tǒng)不可能同時滿足一致性(consistency),可用性(availability)和分區(qū)容錯性(partition tolerance)。

Cassandra是優(yōu)先保證AP,即可用性和分區(qū)容錯性。

 

Cassandra為寫操作和讀操作提供了不同級別的一致性選擇,用戶可以根據(jù)具體的應(yīng)用場景來選擇不同的一致性級別。

1.4 高效寫操作

寫入操作非常高效,這對于實時數(shù)據(jù)非常大的應(yīng)用場景,Cassandra的這一特性無疑極具優(yōu)勢。

數(shù)據(jù)讀取方面則要視情況而定:

  • 如果是單個讀取即指定了鍵值,會很快的返回查詢結(jié)果。
  • 如果是范圍查詢,由于查詢的目標可能存儲在多個節(jié)點上,這就需要對多個節(jié)點進行查詢,所以返回速度會很慢
  • 讀取全表數(shù)據(jù),非常低效。

1.5 結(jié)構(gòu)化存儲

Cassandra是一個面向列的數(shù)據(jù)庫,對那些從RDBMS方面轉(zhuǎn)過來的開發(fā)人員來說,其學習曲線相對平緩。

Cassandra同時提供了較為友好CQL語言,與SQL語句相似度很高。

1.6 維護簡單

從系統(tǒng)維護的角度來說,由于Cassandra的對等系統(tǒng)架構(gòu),使其維護操作簡單易行。如添加節(jié)點,刪除節(jié)點,甚至于添加新的數(shù)據(jù)中心,操作步驟都非常的簡單明了。

參考資料

  • 1.http://cassandra.apache.org
  • 2.http://www.datastax.com/doc
  • 3.http://planetcassandra.org/documentation/

2. Cassandra數(shù)據(jù)模型

2.1 單表查詢

2.1.1 單表主鍵查詢

在建立個人信息數(shù)據(jù)庫的時候,以個人身份證id為主鍵,查詢的時候也只以身份證為關(guān)鍵字進行查詢,則表可以設(shè)計成為:

create table person (
	userid text primary key,
	fname text,
	lname text,
	age	int,
	gender int);

Primary key中的第一個列名是作為Partition key。也就是說根據(jù)針對partition key的hash結(jié)果決定將記錄存儲在哪一個partition中,如果不湊巧的情況下單一主鍵導(dǎo)致所有的hash結(jié)果全部落在同一分區(qū),則會導(dǎo)致該分區(qū)數(shù)據(jù)被撐滿。

解決這一問題的辦法是通過組合分區(qū)鍵(compsoite key)來使得數(shù)據(jù)盡可能的均勻分布到各個節(jié)點上。

舉例來說,可能將(userid,fname)設(shè)置為復(fù)合主鍵。那么相應(yīng)的表創(chuàng)建語句可以寫成

create table person (
userid text,
fname text,
lname text,
gender int,
age int,
primary key((userid,fname),lname);
) with clustering order by (lname desc);

稍微解釋一下primary key((userid, fname),lname)的含義:

  • 其中(userid,fname)稱為組合分區(qū)鍵(composite partition key)
  • lname是聚集列(clustering column)
  • ((userid,fname),lname)一起稱為復(fù)合主鍵(composite primary key)

2.1.2 單表非主鍵查詢

如果要查詢表person中具有相同的first name的人員,那么就必須針對fname創(chuàng)建相應(yīng)的索引,否則查詢速度會非常緩慢。

Create index on person(fname);

Cassandra目前只能對表中的某一列建立索引,不允許對多列建立聯(lián)合索引。

2.2 多表關(guān)聯(lián)查詢

Cassandra并不支持關(guān)聯(lián)查詢,也不支持分組和聚合操作。

那是不是就說明Cassandra只是看上去很美其實根本無法解決實際問題呢?答案顯然是No,只要你不堅持用RDBMS的思路來解決問題就是了。

比如我們有兩張表,一張表(Departmentt)記錄了公司部門信息,另一張表(employee)記錄了公司員工信息。顯然每一個員工必定有歸屬的部門,如果想知道每一個部門擁有的所有員工。如果是用RDBMS的話,SQL語句可以寫成:

select * from employee e , department d where e.depId = d.depId;
要用Cassandra來達到同樣的效果,就必須在employee表和department表之外,再創(chuàng)建一張額外的表(dept_empl)來記錄每一個部門擁有的員工信息。
Create table dept_empl (
deptId text,

看到這里想必你已經(jīng)明白了,在Cassandra中通過數(shù)據(jù)冗余來實現(xiàn)高效的查詢效果。將關(guān)聯(lián)查詢轉(zhuǎn)換為單一的表操作。

2.3 分組和聚合

在RDBMS中常見的group by和max、min在Cassandra中是不存在的。

如果想將所有人員信息按照姓進行分組操作的話,那該如何創(chuàng)建數(shù)據(jù)模型呢?

Create table fname_person (
fname text,
userId text,
primary key(fname)
);
 2.4 子查詢 

Cassandra不支持子查詢,下圖展示了一個在MySQL中的子查詢例子: 

 

要用Cassandra來實現(xiàn),必須通過添加額外的表來存儲冗余信息。 

Create table office_empl (
officeCode text,
country text,
lastname text,
firstname,
primary key(officeCode,country));
create index on office_empl(country);

 2.5 小結(jié)

總的來說,在建立Cassandra數(shù)據(jù)模型的時候,要求對數(shù)據(jù)的讀取需求進可能的清晰,然后利用反范式的設(shè)計方式來實現(xiàn)快速的讀取,原則就是以空間來換取時間。CDA數(shù)據(jù)分析師培訓(xùn)官網(wǎng)


數(shù)據(jù)分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個參數(shù)驗證碼對象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務(wù)器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }