[NewLife.XCode]百億級(jí)性能
NewLife.XCode是一個(gè)有10多年歷史的開(kāi)源數(shù)據(jù)中間件,支持nfx/netcore,由新生命團(tuán)隊(duì)(2002~2019)開(kāi)發(fā)完成并維護(hù)至今,以下簡(jiǎn)稱XCode。
整個(gè)系列教程會(huì)大量結(jié)合示例代碼和運(yùn)行日志來(lái)進(jìn)行深入分析,蘊(yùn)含多年開(kāi)發(fā)經(jīng)驗(yàn)于其中,代表作有百億級(jí)大數(shù)據(jù)實(shí)時(shí)計(jì)算項(xiàng)目。
開(kāi)源地址:https://github.com/NewLifeX/X (求star, 795+)
大數(shù)據(jù)投名狀
先來(lái)看看“大數(shù)據(jù)演示平臺(tái)”:http://bigdata.newlifex.com
SQLite單表4億行訂單數(shù)據(jù),文件大小26.5G,阿里云1C1G的ECS服務(wù)器,由 NewLife.XCode + NewLife.Cube 驅(qū)動(dòng)

如上,在4億行中查詢第1000頁(yè),耗時(shí)16毫秒。
對(duì)于高手來(lái)說(shuō),這個(gè)算不得什么,只要注意好索引就行。
這個(gè)“演示平臺(tái)”建立于兩年前,給兩家領(lǐng)先物流企業(yè)遞交了簡(jiǎn)歷,其中一家因SQLite拒絕了,另一家給了數(shù)據(jù)架構(gòu)師!
現(xiàn)在,每天1億個(gè)快遞包裹在路上,產(chǎn)生大量掃描數(shù)據(jù)。單表數(shù)十億數(shù)據(jù)很常見(jiàn)(Oracle按月分區(qū)),一款數(shù)據(jù)產(chǎn)品幾億明細(xì)數(shù)據(jù)比比皆是(MySql分表)。
代碼之巔、天外飛仙
再來(lái)看一下各種數(shù)據(jù)庫(kù)的極致性能,飛仙平臺(tái) http://feixian.newlifex.com

SQLite插入第一名 56萬(wàn)tps;
MySql插入第一名 60萬(wàn)tps;
SQLite查詢(帶緩存)1126萬(wàn)qps;
這是上百人用了各種機(jī)器(筆記本、臺(tái)式機(jī)、服務(wù)器)調(diào)整參數(shù)進(jìn)行大量測(cè)試后得到的性能排行榜!
所有測(cè)試,由 NewLife.XCode 支持!
實(shí)際應(yīng)用中,即使能達(dá)到上述性能十分之一,亦能立于不敗之地。有時(shí)候甚至還達(dá)不到百分之一。
盡管如此,極致性能的研究也給我們的應(yīng)用方式以及數(shù)據(jù)庫(kù)參數(shù)設(shè)置指明了方向!
索引完備
使用關(guān)系型數(shù)據(jù)庫(kù)來(lái)做大數(shù)據(jù),第一步必然是索引!
單表超過(guò)1000萬(wàn)數(shù)據(jù),任何查詢都必須走索引!否則數(shù)據(jù)庫(kù)一定跟你說(shuō)ByeBye!
前面SQLite單表4億數(shù)據(jù),共有兩個(gè)索引,自增ID作為主鍵,另外有訂單號(hào)索引。
大表索引不宜過(guò)多,務(wù)必以數(shù)據(jù)的主要使用方式來(lái)建立一兩個(gè)即可,盡量不要超過(guò)三個(gè),經(jīng)索引過(guò)濾后的數(shù)據(jù)盡量控制住1萬(wàn)行以內(nèi)。
常見(jiàn)大型表索引用法:
1,日志型
訂單操作表、快遞掃描表、傳感數(shù)據(jù)表等超大日志型數(shù)據(jù)表,每日數(shù)千萬(wàn)到數(shù)億行,只插入不修改,最重要的字段就是時(shí)間戳CreateTime,建立索引,同時(shí)可以按時(shí)間分區(qū)分表。
這種大表最常見(jiàn)用法就是根據(jù)時(shí)間戳去抽取來(lái)做業(yè)務(wù)處理,那就是鼎鼎大名的ETL。處理性能1000~10000tps
更高大上一點(diǎn),就是抽取數(shù)據(jù)寫入Kafka/RocketMQ,名正言順進(jìn)行大數(shù)據(jù)分析!處理性能10萬(wàn)tps
因工作需要,我們依據(jù)時(shí)間戳抽取了30天共100億數(shù)據(jù)寫入Redis,供100+應(yīng)用進(jìn)行實(shí)時(shí)數(shù)據(jù)分析。處理性能100萬(wàn)tps
抽取數(shù)據(jù)時(shí)以每批次抽取5000~20000行為宜,依次調(diào)整查詢時(shí)間段,重量級(jí)螞蟻調(diào)度系統(tǒng)(https://github.com/NewLifeX/AntJob)具備動(dòng)態(tài)步進(jìn)抽取能力,可自動(dòng)調(diào)節(jié)最優(yōu)抽取間隔。
總結(jié)起來(lái)一句話:按時(shí)間戳輪數(shù)據(jù)!
2,狀態(tài)表
訂單運(yùn)單都是有狀態(tài)數(shù)據(jù),在整個(gè)生命周期中,狀態(tài)會(huì)多次改變。許多業(yè)務(wù)往往要求兩個(gè)或多個(gè)狀態(tài)相匹配,那就要求有一張龐大的狀態(tài)表。
狀態(tài)表最合適的主鍵就是訂單號(hào),并且一般分表分庫(kù)存儲(chǔ),常見(jiàn)分表公式 Crc16(code)%1024,分表數(shù)以單表不超過(guò)1000萬(wàn)為宜。
使用1024狀態(tài)表的數(shù)據(jù)庫(kù)一般是分布式玩法,比較合適分8庫(kù),每個(gè)庫(kù)128表,很多應(yīng)用服務(wù)器各司其職,大家共同操作一張表的幾率大減。
3,統(tǒng)計(jì)分析表
統(tǒng)計(jì)表主鍵一般由統(tǒng)計(jì)日期和分類構(gòu)成,為了方便可建立字符串ID主鍵,由 {date}_{cid} 組成,也可以對(duì) date + cid 兩個(gè)字段建立唯一聯(lián)合索引。
之所以建立 {date}_{cid} 的ID主鍵,主要是為了方便寫明細(xì)數(shù)據(jù),無(wú)需等待統(tǒng)計(jì)表插入后(假如使用自增)才得到統(tǒng)計(jì)ID。
明細(xì)表一定必須根據(jù)統(tǒng)計(jì)ID來(lái)查,由統(tǒng)計(jì)ID跟其它主要業(yè)務(wù)字段構(gòu)成主索引。
合理查詢
既然有了索引,那么大表的任意查詢都必須命中索引(或者部分使用索引) 。
為了索引,為了降低數(shù)據(jù)庫(kù)負(fù)擔(dān),有時(shí)候?qū)幙啥嗖橐稽c(diǎn),先把數(shù)據(jù)查出來(lái),再在內(nèi)存里面做二次處理!
大數(shù)據(jù)的瓶頸一定是數(shù)據(jù)庫(kù),應(yīng)用服務(wù)器往往性能過(guò)剩!
因此,完全可以把一部分“計(jì)算”由數(shù)據(jù)庫(kù)轉(zhuǎn)移到應(yīng)用服務(wù)器之中來(lái)進(jìn)行處理。
大表少用join關(guān)聯(lián),寧可多次查詢;
字段精煉
常聽(tīng)到許多人說(shuō)每天處理數(shù)據(jù)多少多少TB/PB,聽(tīng)起來(lái)數(shù)據(jù)分析還可以論斤稱?挺尷尬的!
雖然數(shù)據(jù)庫(kù)很容易遇到IO瓶頸,但很多人達(dá)不到那一步。
數(shù)據(jù)容量上的優(yōu)化空間還是極大的。
大表字段精簡(jiǎn)原則:
- 能存ID就別存Name。經(jīng)常見(jiàn)到用戶、商家、地區(qū)等信息,又存ID又存Name,甚至還存一個(gè)Code。此時(shí)需要XCode的擴(kuò)展屬性
- 適當(dāng)冗余。為了便于查詢,可以適當(dāng)冗余一些字段,但絕不能濫用。比如商家所在地區(qū),如果查詢用不到而只是分析時(shí)使用,就不需要保存商家ID以外還保存地區(qū)
- 只查詢需要的字段。這一點(diǎn)跟XCode推崇 select * 并不相悖,絕大部分百萬(wàn)級(jí)以內(nèi)小表可以這么干,但是千萬(wàn)億萬(wàn)級(jí)大表則需按需查詢了。
充分利用緩存
少用join關(guān)聯(lián),慎用字段冗余,即可大量發(fā)揮XCode的緩存優(yōu)勢(shì)。
10萬(wàn)乃至100萬(wàn)維表數(shù)據(jù)可盡量緩存起來(lái),隨時(shí)配合億萬(wàn)級(jí)大表進(jìn)行數(shù)據(jù)分析。
另一方面就是數(shù)據(jù)庫(kù)緩存,需要DBA大力支持!
系列教程
NewLife.XCode教程系列[2019版]
- 增刪改查入門。快速展現(xiàn)用法,代碼配置連接字符串
- 數(shù)據(jù)模型文件。建立表格字段和索引,名字以及數(shù)據(jù)類型規(guī)范,推薦字段(時(shí)間,用戶,IP)
- 實(shí)體類詳解。數(shù)據(jù)類業(yè)務(wù)類,泛型基類,接口
- 功能設(shè)置。連接字符串,調(diào)試開(kāi)關(guān),SQL日志,慢日志,參數(shù)化,執(zhí)行超時(shí)。代碼與配置文件設(shè)置,連接字符串局部設(shè)置
- 反向工程。自動(dòng)建立數(shù)據(jù)庫(kù)數(shù)據(jù)表
- 數(shù)據(jù)初始化。InitData寫入初始化數(shù)據(jù)
- 高級(jí)增刪改。重載攔截,自增字段,Valid驗(yàn)證,實(shí)體模型(時(shí)間,用戶,IP)
- 臟數(shù)據(jù)。如何產(chǎn)生,怎么利用
- 增量累加。高并發(fā)統(tǒng)計(jì)
- 事務(wù)處理。單表和多表,不同連接,多種寫法
- 擴(kuò)展屬性。多表關(guān)聯(lián),Map映射
- 高級(jí)查詢。復(fù)雜條件,分頁(yè),自定義擴(kuò)展FieldItem,查總記錄數(shù),查匯總統(tǒng)計(jì)
- 數(shù)據(jù)層緩存。Sql緩存,更新機(jī)制
- 實(shí)體緩存。全表整理緩存,更新機(jī)制
- 對(duì)象緩存。字典緩存,適用用戶等數(shù)據(jù)較多場(chǎng)景。
- 百億級(jí)性能。字段精煉,索引完備,合理查詢,充分利用緩存
- 實(shí)體工廠。元數(shù)據(jù),通用處理程序
- 角色權(quán)限。Membership
- 導(dǎo)入導(dǎo)出。Xml,Json,二進(jìn)制,網(wǎng)絡(luò)或文件
- 分表分庫(kù)。常見(jiàn)拆分邏輯
- 高級(jí)統(tǒng)計(jì)。聚合統(tǒng)計(jì),分組統(tǒng)計(jì)
- 批量寫入。批量插入,批量Upsert,異步保存
- 實(shí)體隊(duì)列。寫入級(jí)緩存,提升性能。
- 備份同步。備份數(shù)據(jù),恢復(fù)數(shù)據(jù),同步數(shù)據(jù)
- 數(shù)據(jù)服務(wù)。提供RPC接口服務(wù),遠(yuǎn)程執(zhí)行查詢,例如SQLite網(wǎng)絡(luò)版
- 大數(shù)據(jù)分析。ETL抽取,調(diào)度計(jì)算處理,結(jié)果持久化

浙公網(wǎng)安備 33010602011771號(hào)