天天看點

實戰:從零開始搭建彈性應用

一、背景介紹

(一)課程預覽

實戰:從零開始搭建彈性應用

Ø  What?

基于Spring boot 架構 + Cassandra資料庫,實作一個支援海量使用者 的使用者管理系統。

Ø  Why?

Spring Boot大幅簡化了應用搭建和開發的成本,Cassandra作為開源分布式資料庫,既具備NoSQL資料庫高性能,高可用,海量無限擴充的特點,又具備類似關系型資料庫的資料模型,非常适合開發線上應用。

Ø  Who?

Web開發入門者,希望深入了解Cassandra設計和使用的使用者。

Ø  How?

本文将從設計開始,手把手教使用者實作一個使用者管理系統

(二)Spring Data for Cassandra簡介

1.Cassandra

- 去中心化,海量資料擴充能力;

- Zero Down Time;

- 支援二級索引,物化視圖,集合等實用功能;

- 被Apple,Netflix,360,華為等大公司廣泛采用。

2.Spring Data

- 強大的存儲庫和靈活的抽象映射;

- 便于與Spring MVC controller 內建;

- 支援MySQL,Redis,Redis,ES,Cassandra等資料庫。

3.Spring Data for Cassandra

- 降低CQL語言的學習成本,提升開發速度;

- 支援同步,反應式和異步等多種模式;

- 支援使用者自定義複雜查詢;

- 一套代碼支援MySQL冷熱分離,ES加速查詢,Redis緩存等多種玩法。

(三)準備工作

準備工作主要分為以下三個步驟:

1.  購買Cassandra叢集

1)購買Cassandra雲服務

2)使用者密碼:雲Cassandra控制台-> 叢集詳情->賬号管理頁面

3)連結URL:在資料庫連接配接頁面

實戰:從零開始搭建彈性應用

2.  配置叢集

1)  雲Cassandra控制台 -> 叢集詳情-> 資料庫連接配接頁面開通公網連結

2)  雲Cassandra控制台-> 叢集詳情-> 資料安全頁面配置本機IP到白名單

3. 配置開發環境

1)下載下傳并安裝Idea開發環境

2)在Spring模版生成器中生成項目模版

位址:

https://start.spring.io/

3)将生成好的項目導入Idea

當完成上述步驟後,使用者可以獲得一個工程,如下所示:

實戰:從零開始搭建彈性應用

這個工程是空的,裡面隻有一個Main函數可以執行,其他功能需要後續操作進行添加。

二、系統設計

(一)需求分析

需求分析主要分為三部分:資料需求、功能需求和其他需求。

1.資料需求

實戰:從零開始搭建彈性應用

由于要做的是使用者管理系統,使用者的資料存儲在Cassandra資料庫中。使用者資料可分為以下幾個屬性:使用者ID、使用者名、密碼與使用者年齡,後續可根據需求擴充更多使用者資訊,例如email,電話号碼,住址等。

2.功能需求

實戰:從零開始搭建彈性應用

功能一般分為增删改查4個部分。

增指的是在系統中增加一個新的使用者,删指的是把使用者資訊删除,改指的是修改使用者資訊,查則較為複雜。查詢可以包含很多場景,例如基于使用者ID查詢,基于使用者年齡查詢,或者要展示全部使用者的資訊。

3.其他需求

除了上述基本功能需求外,還需要注意以下四點:

1)高并發高性能

使用者可能會頻繁更新同一條資料,或者系統需要支撐100萬個使用者同時注冊的場景,或者當有1億個使用者的時候,能不能快速展示全部使用者,以上都屬于高并發高性能場景。

2)可擴充性

系統功能在設計初期,可能有一些地方沒有考慮到,例如初期沒有設計通過電子郵箱位址搜尋使用者的功能,後續有需求需要添加這個功能,是以對可擴充性有一定的要求。

3)開發靈活

系統最開始的功能可能開發起來并不會特别複雜,但随着系統的累加,功能會越來越複雜,是以需要注意開發靈活性。

4)美觀

該系統作為外部服務,會存在與使用者互動的界面,是以希望這個界面對使用者足夠友好。

(二)Schema設計

需求完成後,我們接下來需要做的事情是設計一個Schema。

這裡需要注意,一定要先完成Schema的設然後再去實作功能,否則可能會導緻系統性能會出現一些瓶頸。

實戰:從零開始搭建彈性應用
實戰:從零開始搭建彈性應用

分析剛才的資料,由于ID字段是唯一的,是以可以把ID字段放在主鍵的位置。

主鍵有幾個要求,首先要符合使用者查詢常見次元,例如上方提到的使用者查詢,有可能通過使用者ID、年齡等資訊進行查詢。

将ID作為主鍵而不是年齡的原因在于,一方面是年齡的區分度不夠,很多使用者擁有同樣的年齡,如果以年齡做主鍵的話,可能會導緻相同年齡的資料很多,必然要年齡後面再結合一個其他字段去保證主鍵的唯一。

其次,年齡作為主鍵可能會存在熱點問題,比如所有的使用者都是20~25歲,那麼資料都會集中在分片,導緻分片非常不均勻。

那麼,把ID放在主鍵是不是就可以解決這些問題了呢?

這要看ID本身是否足夠打散,如果是随機生成一些ID,則資料本身非常均勻。如果ID是自增的,這對于Cassandra來說并不是一個特别好的選擇。對于Cassandra的ID,我們希望盡可能去打散。當然,如果說ID把它放在Partition Key的話,因為它本身是有一些哈希可以去做打散的,是以也是可行的。

但是如果把ID放在Partition Key的話,Partition Key本身是不做排序,是以想查詢ID在5~100範圍内的所有使用者,這個查詢無法實作。由于這次的系統設計較為簡易,沒有排序的要求,是以設計當中沒有包含這項功能。

除此之外,有一個基于age字段做查詢,age字段不在主鍵中出現。如果現在不對它建一個二級索引,它本身會轉化成一個過濾邏輯,類似于全表掃描,如果資料量較小則沒有問題。由于設計的目标是一個較大的使用者管理系統,資料存儲可能是幾千萬條甚至幾億條,在這些資料當中過濾出來年齡符合一定要求的存在一定難度,是以建一個二級索引加速查詢。

建立二級索引的DDL如下所示:

實戰:從零開始搭建彈性應用

(三)CQL設計

CQL設計遵循增删改查原則,實作方式如下。

1.增

insert into test_keyspace.user(id, age, username, password) values(20, 18,'apple','banana');

2.删

可以根據具體id進行删除,如:

delete from test_keyspace.user where id=20;

3.改

更改分為兩個部分,第一部分是更改的字段,第二部分是更改的資料,如要把id為2的使用者年齡改為20,則實作語句如下:

update test_keyspace.user set age=20 where id=2;

4.查

查詢分為多個方式,如果查詢所有資料,則:

select * from test_keyspace.user ;

如果根據ID查詢,例如id為2的使用者:

select * from test_keyspace.user where id=2 ;

如果根據年齡查詢,例如年齡為2的使用者:

select * from test_keyspace.user where age=2 ;

如果資料量少,不需要二級索引,通過年齡進行過濾查詢:

select * from test_keyspace.user where age=2 allow filtering ;

n  此處必須加上allow filtering屬性,否則Cassandra可能會拒絕查詢。

三、編碼實戰

(一)代碼架構

實戰:從零開始搭建彈性應用

Ø  架構主要由以下幾個部分構成:

1)UserController:控制層,負責與前段互動,頁面跳轉

2)UserService:業務層,負責處理業務邏輯

3)User Repo:DAO層,負責通路資料庫擷取資料

4)CassandraConfig:存儲Cassandra叢集的通路配置

5)Resource:前端頁面位置

整個代碼按照MVC的設計分成數個子產品。前端子產品會提供三個網頁,一個是list.html,用來展示User;第二個是userAdd.html,增加一個user;最後一個是userEdit.html,表示更新一個user。

所有的html會把請求發到控制層和前端做互動,包括擷取資料發到前端做展示,跳轉到某個頁面,這些都是在控制層進行。

控制層下面是業務層,傳統的業務層更多的是處理一些業務的請求。我們這次的系統相對簡單,業務層主要承擔的作用是把DAO層的資料傳回給上面的控制層。同時,業務層也會做一些簡單的處理,比如統計一些使用者的數目,然後将這些資訊發給控制層。

最下面是DAO層,可以跟Cassandra做一一映射,負責Cassandra資料庫的通路和連結。

(二)增删改查

1.Cassandra通路配置

實戰:從零開始搭建彈性應用

在通路Cassandra之前,首先要進行通路配置。CassandraConfig本身就是在Spring Data架構裡,需要繼承AbstractCassandraConfiguration去定義需要的資訊。

這裡面包括了hostList,即資料庫的連接配接串,這些資訊可以在Cassandra管理頁面找到。

第二個是keyspaceName,即通路的keyspace的具體名字。

第三個就是通路的使用者名和密碼,做權限的驗證。

最後一個是datacenter,它其實也可以在雲控制台裡面去找到。在雲控制台上它叫資料中心ID,不叫資料中心名稱,通常情況是一個CN開頭的字元串。

值得一提的是底下會有一個cassandraSession實作,它發送使用者名和密碼幫助Cassandra連接配接。

2.DAO層

實戰:從零開始搭建彈性應用

Ø  定義User對象,并指定id對應user表的PrimaryKey

完成配置後開始定義資料。剛才存的是User,這個類對應到Cassandra當中是Table表,它有4個字段,分别是ID,UserName,Password和Age。這裡面有一個@PrimaryKey的定義,作用是告知Cassandra架構,ID字段是一個PrimaryKey,它是一個BIGINT。除此之外,這個實體實作了一些簡單的Get和Set的方法。

實戰:從零開始搭建彈性應用

Ø  DAO層隻需要繼承CassandraRepository即可實作基本的增删改查,對于帶條件的增删改查通過@Query的方式支援。

如何把實體對象真正的去與Cassandra進行讀取?對于DAO層,Spring Data也做了很多事情。

如上圖所示,CassandraRepository實作了很多基本的Cassandra通路,比如findAll是擷取一張表裡所有的資料,findAllById是可以通過ID擷取一個資料,insert是插入一條資料。有了這些之後,可以實作基本的增删改操作。

如果想實作的查詢比較複雜,例如基于年齡做查詢,可以做一個新的interface,讓userRepository繼承CassandraRepository,在裡面定義一種新的查詢叫findByAge。Spring Data支援@Query關鍵詞,它定義了要通路的資料。

3.Service層

實戰:從零開始搭建彈性應用

Ø  通過AutoWired标記連結DAU層;

Ø  本例子中業務邏輯比較簡單,并未包括複雜的處理,實際開發過程中Service中可以處理複雜業務邏輯。

這裡有幾個需要關注的點:

第一個是類本身為@Service關鍵詞進行标記。第二個是AutoWired屬性,可以将UserRepository和Service層連結。第三個是實作了getUserNum,可以去userRepository拿到所有的資料,然後調size。

4.Controller層

實戰:從零開始搭建彈性應用

Ø  @RequestMapping來映射請求,也就是通過它來指定控制器 可以處理哪些URL請求, 函數傳回值标記跳轉的頁面位址;

Ø  傳回值通過model.addAttribute傳回前端。

(三)前端頁面

實戰:從零開始搭建彈性應用

前端頁面的實作代碼可在GitHub上檢視。

左下角的add按鍵可以添加新使用者,後右上角的Edit和Delete,可以對使用者進行修改與删除。下方的搜尋使用者功能,可以根據年齡搜尋使用者。

四、總結

(一)功能示範

1.前端頁面

實戰:從零開始搭建彈性應用

2.添加使用者

實戰:從零開始搭建彈性應用

3.修改使用者

實戰:從零開始搭建彈性應用

4.按年齡搜尋使用者

實戰:從零開始搭建彈性應用

(二)示範總結

通過上述講解與示範,可以總結出設計系統主要有以下步驟組成:

1. 明确需求

-  需要存儲什麼資料

-  需要什麼查詢語句

2. 設計表結構

-  主鍵設計

-  二級索引

3. MVC實作

-  基于Model實作控制器

-  實作前端展示

n  進階思考:

1)系統需要處理高并發,如這是一個使用者點選統計,有一列是點選次數,如何能統計出使用者點選的精确次數?

2)如果該使用者系統需要支援100w tps/qps每秒,應該如何繼續疊代?

實戰:從零開始搭建彈性應用

(三)更多進階功能 - Serverless Cassandra

實戰:從零開始搭建彈性應用

阿裡雲推出了一個新的服務叫Serverless Cassandra,核心是解決使用者的資源管理成本和穩定性問題。

傳統模式存在幾個問題:

第一,可能使用者的服務本身體量很小,如果購買資料庫服務的話,起步門檻較高,成本對于使用者來說不太友好。

第二,如果在使用Cassandra的過程中,使用者的網站做大了,此時傳統資料庫需要不停地運維和規劃,需要通過人為觸發來擴充資料庫。

第三,傳統資源管理的方式需要提前規劃資源,可能造成較大的資源浪費。例如使用者的服務在晚上請求量較低,但在配置時需要按照高請求量場景進行配置,成本較高。

實戰:從零開始搭建彈性應用

Serverless Cassandra無需任何資料庫管理,執行個體運作于龐大的資源池 ,按使用量計費,如用電一般,随取随用,适用于不頻發的、間歇性的或不可預測的工作負載。

Ø  Serverless Cassandra适用場景

1)變化或不可預測的工作負載

2)定時處理任務的場景

3)新上線應用

4)完全免運維的使用者

Ø  Serverless Cassandra三大特性

1)簡單易用

全托管,無需資料庫管理;

開源标準接口,應用0 改造;

豐富生态和周邊工具配套

2)經濟高效

超低門檻

存儲計算獨立計費

按使用量計費

多存儲/ 可用性級别

3)按需彈性

存儲計算獨立伸縮

無需容量規劃,自動伸縮