官术网_书友最值得收藏!

1.2 數據庫分區,從學習到放棄

先講一下數據庫的分區功能。分區并不是生成新的數據表,而是將表的數據均衡分配到不同的硬盤、系統或不同的服務器存儲介質中,實際上還是一張表。

比如,要創建以下數據庫表:

那么,數據庫就會把這個t2表的數據根據YEAR(dob)這個表達式的值分布存儲在d0~d7這8個分區。

數據庫分區有以下優點。

1)比起單個文件系統或硬盤,分區可以存儲更多的數據。

2)在清理數據時,可以直接刪除廢棄數據所在的分區。同樣,有新數據時,可以增加更多的分區來存儲新數據。

3)可以大幅度地優化特定的查詢,讓這些查詢語句只去掃描特定分區的數據。比如,原來有2000萬的數據,設計10個分區,每個分區存200萬的數據,那么可以優化查詢語句,讓它只去查詢其中兩個分區,即只需要掃描400萬的數據。

第3個優點正好可以解決此處的項目需求。但是,要怎么設計分區字段?也就是說,要根據什么來分區?

下面具體說一下該業務場景中的數據表。工單表ticket中的關鍵字段見表1-1。

表1-1 工單表關鍵字段

工單表最主要的幾個查詢語句如下。

1)客服查詢無處理人的工單:“Where assignedUserID=?”。

2)客服獲取分派給自己的工單:“Where status in(…)and assignedUserID=?”。

3)客服組長查看自己組的工單:“Where assignedUserGroupID=?”。

4)客服查詢特定客戶的工單:“Where consumerEmail=?”。

為了達到只掃描特定分區的效果,必須在Where語句里面加上一個包含分區字段的條件,但是上面這些主要語句并不包含相同的字段。

另外,MySQL的分區還有個限制,即分區字段必須是唯一索引(主鍵也是唯一索引)的一部分。工單表是用ticketID當主鍵,也就是說接下來無論使用什么當分區字段,都必須把它加到主鍵當中,形成復合主鍵。MySQL官方文檔原文如下。

All columns used in the partitioning expression for a partitioned table must be part of every unique key that the table may have.

In other words,every unique key on the table must use every column in the table's partitioning expression(This also includes the table's primary key, since it is by definition a unique key.This particular case is discussed later in this section).

接著深入分析一下業務流程。

1)系統從郵件服務器同步到郵件以后,創建一個工單,createdTime就是工單創建的時間。

2)客服先去查詢無處理人的工單,然后把工單分派給自己。

3)客服處理工單,每處理一次,系統自動增加一條處理記錄。

4)客服處理完工單以后,將工單狀態改為“關閉”。

通過跟客服的交流,項目組發現,一般工單被關閉以后,客服查詢的概率就很低了。對于那些關閉超過一個月的工單,基本上一年都打開不了幾次。

調研到這里,基本的思路是增加一個狀態:歸檔。首先將關閉超過一個月以上的工單自動轉為“歸檔”狀態,然后將數據庫分為兩個區,所有“歸檔”狀態的工單存放在一個區,所有非“歸檔”狀態的工單存放在另外一個區,最后在所有的查詢語句中加一個條件,就是狀態不等于“歸檔”。

簡單估算一下:客服頻繁操作的工單基本上都是1個月內的工單,按照后期一天10萬來算,也就是300萬的數據,這樣數據庫的非歸檔區基本就沒什么壓力了。

那么,是否就將status設為分區字段,然后直接使用MySQL的分區功能?不是的。

因為相關的開發人員并沒有用過數據庫分區的功能,而當時面臨的情況是只有1周的時間來解決問題,并且工單表是系統最核心的數據表,不能出問題。

這種情況下,沒人敢在生產的核心功能上使用一項沒用過的技術,但是項目組評估了一下,要實現一個類似的方案,其實工作量并不大,而且代碼可控。因此,項目組放棄了數據庫分區,并決定基于同樣的分區理念,使用自己熟悉的技術來實現這個功能。

這個思路也很簡單:新建一個數據庫,然后將1個月前已經完結的工單數據都移動到這個新的數據庫。這個數據庫就叫冷庫,因為里面基本是冷數據(當然,叫作歸檔數據庫也可以),之后極少被訪問。當前的數據庫保留正常處理的較新的工單數據,這是熱庫。

這樣處理后,因為客服查詢的基本是近期常用的數據,大概只有300萬條,性能就基本沒問題了。即使因為查詢頻繁,或者幾個客服同時查詢,也不會再像之前那樣出現數據庫占滿CPU、整個系統幾乎宕機的情況了。

上面這個方法,其實就是軟件系統常用的“冷熱分離”。接下來介紹一下冷熱分離的方案。

主站蜘蛛池模板: 襄汾县| 靖远县| 商丘市| 凌云县| 曲阜市| 巢湖市| 麦盖提县| 南乐县| 马关县| 汤原县| 全椒县| 泌阳县| 于都县| 德江县| 三河市| 商都县| 鱼台县| 会宁县| 宝兴县| 吴旗县| 财经| 区。| 彭山县| 北碚区| 海口市| 周口市| 泗洪县| 南川市| 沂南县| 吐鲁番市| 沧源| 西安市| 西平县| 襄垣县| 深水埗区| 辽宁省| 河间市| 保山市| 黄浦区| 仁寿县| 临夏市|