分庫分表:
跨庫的問題
分佈式事務問題
查詢數據結果集合並
全局唯一性ID保證
要求:
1、全局唯一性:不能出現重複的id號(基本的要求)。
2、信息安全:防止惡意用戶規矩id的規則來獲取數據。混淆效果
3、數據遞增:保證我下一個ID一定大於上一個ID。
當前201709122030 下一個:201709122031 下一個:201709122032
互斥關係:信息安全、數據遞增規律
CREATE TABLE `tl_id` ( `id` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
業界分案:
UUID:
通用唯一識別碼 16個字節128位的長數字、
組成部分:當前日期和時間序列+全局的唯一性網卡mac地址
執行任務數:10000 ------------------------ 所有線程共耗時:38.305 s 併發執行完耗時:449.0 ms 單任務平均耗時:3.8305 ms 單線程最小耗時:0.0 ms 單線程最大耗時:193.0 ms |
總結:
優點 | 缺點 |
代碼實現簡單、不佔用寬帶、數據遷移不受影響 | 無序、無法保證趨勢遞增(要求3)字符存儲、傳輸、查詢慢、不可讀 |
Snowflake雪花算法
國外的twitter分佈式下iD生成算法
1bit+41bit+10bit+10+bit=62bit
高位隨機+毫秒數+機器碼(數據中心+機器id)+10的流水號
國內:
保證數據的唯一性就行了 IDC機房。總結:
優點 | 缺點 |
代碼實現簡單、不佔用寬帶、數據遷移不受影響、低位趨勢遞增 | 強以來時鐘(多臺服務器時間一定要一樣)、無序無法保證趨勢遞增(要求3) |
水平切分方式
範圍法
哈希法
水平切分後碰到的問題
通過uid屬性查詢能直接定位到庫,通過非uid屬性查詢不能定位到庫。
非uid屬性查詢的典型業務
用戶側,前臺訪問,單條記錄的查詢,訪問量較大,服務需要高可用,並且對一致性的要求較高。
運營側,後臺訪問,根據產品、運營需求,訪問模式各異,基本上是批量分頁的查詢,由於是內部系統,訪問量很低,對可用性的要求不高,對一致性的要求也沒這麼嚴格。
用戶側與運營側架構設計思路
針對用戶側,應該採用“建立非uid屬性到uid的映射關係”的架構方案。
針對運營側,應該採用“前臺與後臺分離”的架構方案。
用戶前臺側,“建立非uid屬性到uid的映射關係”最佳實踐
索引表法:數據庫中記錄login_name->uid的映射關係。
緩存映射法:緩存中記錄login_name->uid的映射關係。
login_name生成uid。
login_name基因融入uid。
運營後臺側,“前臺與後臺分離”最佳實踐
前臺、後臺系統web/service/db分離解耦,避免後臺低效查詢引發前臺查詢抖動。
可以採用數據冗餘的設計方式。
可以採用“外置索引”(例如ES搜索系統)或者“大數據處理”(例如HIVE)來滿足後臺變態的查詢需求。
“1對多”類業務,在架構上,採用元數據與索引數據分離的架構設計方法
帖子服務,元數據滿足uid和tid的查詢需求。
搜索服務,索引數據滿足複雜搜索尋求。
對於元數據的存儲,在數據量較大的情況下,有三種常見的切分方法:
tid切分法,按照tid分庫,同一個用戶發佈的帖子落在不同的庫上,通過 - uid來查詢要遍歷所有庫。
uid切分法,按照uid分庫,同一個用戶發佈的帖子落在同一個庫上,需要通過索引表或者緩存來記錄tid與uid的映射關係,通過tid來查詢時,先查到uid,再通過uid定位庫。
基因法,按照uid分庫,在生成tid里加入uid上的分庫基因,保證通過uid和tid都能直接定位到庫。
在數據庫架構設計過程中,除了水平切分,至少還會遇到這樣一些問題:
可用性:不管是主庫實例,還是從庫實例,如果數據庫實例掛了,如何不影響數據的讀和寫。
讀性能:互聯網業務大多是讀多寫少的業務,如果提升數據庫的讀性能是架構設計中必須考慮的問題。
一致性:數據一旦冗餘,就可能出現一致性問題,如何解決主庫與從庫之間的不一致,如何解決數據庫與緩存之間的不一致,也是需要重點設計的。
擴展性:如何在不停服務的情況下擴充數據表的屬性,實施數據遷移,實施存儲引擎的切換,架構設計上都是十分有講究的。
分佈式SQL語句:單庫情況下,所有SQL語句的執行都沒問題問題,一旦實施了水平切分,如何實現SQL的集函數,分頁,非patition key上的查詢都成了大問題。
Mysql:
奇數跟我們偶數 遞增步長2
適合小型互聯網公司、比如可以知道我們一定生成的ID數量 五萬的訂單量
一年1千8百萬
Mysql一張表500萬
如果公司每天訂單量5萬的數據 我們用mysql設置步長位100的話可以用27年
只能為100庫 公司來到風投了 每天的訂單量50萬100萬的時候
總結:
優點 | 缺點 |
代碼實現方便、性能不錯、數字排序、可讀性很強 | 受限數據庫、擴展麻煩、插入數據庫才能拿到ID、單點故障的問題 |
主從同步的時候:電商下單->支付 insert master db select 數據 因為數據同步延遲導致查不到這個數據。加cache(不是最好的解決方式)數據要求比較嚴謹的話查master主庫。
CREATE TABLE `tl_num` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
KEY (`id`) USING BTREE
) ENGINE=InnoDB auto_increment=1 DEFAULT CHARSET=utf8;
Redis:
執行任務數:10000 ------------------------ 所有線程共耗時:136.587 s 併發執行完耗時:1.515 s 單任務平均耗時:13.6587 ms 單線程最小耗時:1.0 ms 單線程最大耗時:254.0 ms |
總結:
優點 | 缺點 |
不依賴數據、靈活方便、性能優於數據庫的、沒有單點故障(高可用) | 需要佔用網絡資源、性能要比本地生成慢、需要增加插件 |