|
9.5 消除更新瓶颈$ y# J3 k$ \4 M& L) |" t
UpdateServer单点看起来像是OceanBase架构的软肋,然而,经过OceanBase团队
) a2 ?5 d9 d# V# V$ P6 k$ a0 g3 d持续不断地性能优化以及旁路导入功能的开发,单点的架构在实践过程中经受住了
7 @! l2 D& A, ^. Y0 }5 X2 {线上考验。每年淘宝网“双十一”光棍节,OceanBase系统都承载着核心的数据库业
$ f& O. l) |8 v务,系统访问量出现5到10倍的增长,而OceanBase只需简单地增加机器即可。) g3 n; a6 Z7 k" P' m+ |
当然,UpdateServer单点架构并不是不可突破。虽然目前UpdateServer单点架构
5 a9 O! M8 Z& W+ x还不是瓶颈,但是OceanBase系统设计时已经留好了“后门”,以后可以通过对系统打
" M' _4 S7 h- S% \* }0 u补丁的方式支持UpdateServer线性扩展。当然,这里可能会做一些牺牲,比如短期内
1 a% g' [/ @7 x; w暂不支持全局事务,只支持针对单个用户的事务操作。" ~) {! C: N8 F7 R
本节首先回顾OceanBase已经实现的优化工作,包括读写性能优化以及旁路导入
* F: R& y; s8 a3 V3 W) ~+ ~功能,接着介绍一种数据分区实现UpdateServer线性扩展的方法。
( s7 ~6 g* A% e8 N9 i {/ [3 N9.5.1 读写优化回顾8 z, a5 b q9 c5 o5 ?
OceanBase UpdateServer相当于一个内存数据库,其架构设计和“世界上最快的内
2 @2 O0 L6 ~, K. F" a存数据库”MemSQL比较类似,能够支持每秒数百万次单行读写操作,这样的性能对
9 B8 S% z: x; f. X7 `& T7 i$ U% D5 B于目前关系数据库的应用场景都是足够的。为了达到这样的性能指标,我们已经完
- w+ _$ Q V/ e5 J! p" W8 }) _成或正在进行的工作如下。. ]; n! d9 p4 e& W
1.网络框架优化* f% f! L: i+ Q/ O1 D+ d
9.2.2 节中提到,如果不经过优化,单机每秒最多能够接收的数据包个数只有9 d4 I! g( @# E1 |: O! G8 \
10万个左右,而经过优化后的libeasy框架对于千兆网卡每秒最多收包个数超过50
( d& T. D. w+ [& \万,对于万兆网卡则超过100万。另外,UpdateServer内部还会在软件层面实现多块* e0 x# V/ v5 Y- U8 b! ~% i
网卡的负载均衡,从而更好地发挥多网卡的优势。通过网络框架优化,使得单机支6 l& N- k* @/ [" Y4 R4 S0 _- @
持百万次操作成为可能。: v7 M2 c5 K0 v8 ]7 l
2.高性能内存数据结构
# u, s" G" \% H/ v m$ T; LUpdateServer的底层是一颗高性能内存B树。为了最大程度地发挥多核的优势,B, Y5 | G1 R1 b& y4 D
树实现时大部分情况下都做到了无锁(lock-free)。测试数据表明,即使在普通的166 a5 Q* v2 U! }: a
核机器上,OceanBase B树每秒支持的单行修改操作都超过150万次。' Q( t/ g# H/ |: L6 q; @
3.写操作日志优化
7 r- r7 D9 Q) j在软件层面,写操作日志涉及的工作主要有如下几点:
0 R s- V1 H' u: Q! M9 M: Q3 F1)成组提交。将多个写操作聚合在一起,一次性刷入磁盘中。
8 ]3 e4 k( n b0 O4 p4 {5 |# m& I2)降低日志缓冲区的锁冲突。多个线程同时往日志缓冲区中追加数据,实现时
7 @3 a* o6 I% o. ^需要尽可能地减少追加过程的锁冲突。追加过程包含两个阶段:第一个阶段是占& k# F) |, P# G
位,第二个阶段是拷贝数据,相比较而言,拷贝数据比较耗时。实现的关键在于只; O' d8 C1 O5 S* l
对占位操作互斥,而允许多线程并发拷贝数据。例如,有两个线程,线程1和线程
) n) N2 J; R) m8 e$ Y5 q2 }# h2,他们分别需要往缓冲区追加大小为100字节和大小为300字节的数据。假设缓冲区
( K O1 o8 D6 j3 x, m7 k5 x初始为空,那么,线程1可以首先占住位置0~100,线程2接着占住100~300。最" g' ^0 `9 E4 a4 R# ]
后,线程1和线程2并发将数据拷贝到刚才占住的位置。& @+ ~3 z- A5 u$ q6 H1 M
3)日志文件并发写入。UpdateServer中每个日志缓冲区的大小一般为2MB,如
1 Y R) B3 Q7 T; ]$ l果写入太快,那么,很快会产生多个日志缓冲区需要刷入磁盘,可以并发地将这些
% E" L4 u# F8 p" }日志缓冲区刷入不同的磁盘。当然,UpdateServer目前并没有实现2和3这两个优化
3 t( \, w, [) i5 P0 L: g4 F5 s点。在硬件层面,UpdateServer机器需要配置较好的RAID卡。这些RAID卡自带缓
$ I* j6 [9 ~( ], q% ~存,而且容量比较大(例如1GB),从而进一步提升写磁盘性能。3 h% Z! o F C- g4 b
4.内存容量优化6 z. I/ h. R, S- B
随着数据不断写入,UpdateServer的内存容量将成为瓶颈。因此,有两种解决思
- e1 b; m: o/ F, Z# P" t) ^3 b1 t路。一种思路是精心设计UpdateServer的内存数据结构,尽可能地节省内存使用;另
; }5 q$ A: e4 J e5 A R外一种思路就是将UpdateServer内存中的数据很快地分发出去。' T) j- m" r4 M, {5 e
OceanBase实现了这两种思路。首先,UpdateServer会将内存中的数据编码为精+ L, G# o% ] B2 ~9 `
心设计的格式,从9.3.1节中可以看出,100以内的64位整数在内存中只需要占用两个
; a5 S# h1 |4 t% Y1 G% s# J: `+ b字节。这种编码格式不仅能够有效地减少内存占用,而且往往使得CPU缓存能够容
' R! N" \( v' O5 T纳更多的数据,从而弥补编码和解码操作造成的性能损失。另外,当UpdateServer的2 R' G4 z y% j
内存使用量到达一定大小时,OceanBase会自动触发数据分发操作,将UpdateServer( U5 p! [) H' J' F; U$ s
的数据分发到集群中的ChunkServer中,从而避免UpdateServer的内存容量成为瓶颈。8 x1 n1 n- d( X; }3 V
当然,随着单机内存容量变得越来越大,普通的2U服务器已经具备1TB内存的扩展
" _0 W. B. l4 `2 N+ {% a- _2 O能力,数据分发也可能只是一种过渡方案。2 n: b8 p) Z0 k% {
9.5.2 数据旁路导入1 h8 e; e# L/ @& Y
虽然OceanBase内部实现了大量优化技术,但是UpdateServer单点写入对于某些8 z4 n, Y( L3 H
OLAP应用仍然可能成为问题。这些应用往往需要定期(例如每天,每个月)导入大
) X9 V, M% C, Q$ l4 T批数据,对导入性能要求很高。为此,OceanBase专门开发了旁路导入功能,本节介3 T. I9 V. }; b, k
绍直接将数据导入到ChunkServer中的方法(即ChunkServer旁路导入)。
: c" n0 v2 `' D1 i. m1 t2 bOceanBase的数据按照全局有序排列,因此,旁路导入的第一步就是使用Hadoop
9 @9 C( u6 r! aMapReduce这样的工具将所有的数据排好序,并且划分为一个个有序的范围,每个范, m, p% b5 @+ w: n
围对应一个SSTable文件。接着,再将SSTable文件并行拷贝到集群中所有的
! H3 Q* q$ W8 j6 ]3 z1 n$ R) w+ nChunkServer中。最后,通知RootServer要求每个ChunkServer并行加载这些SSTable文
: N$ Y+ `& u3 V2 W2 e件。每个SSTable文件对应ChunkServer的一个子表,ChunkServer加载完本地的SSTable
6 |/ G& x$ T+ f4 r3 |; V0 A* }$ H文件后会向RootServer汇报,RootServer接着将汇报的子表信息更新到RootTable中。
: }2 S* I H# R I4 h6 l% j$ l: j6 L4 }例9-7 有4台ChunkServer:A、B、C和D。所有的数据排好序后划分为6个范
) [. p, ?& ?. Y7 H! `围:r1(0~100]、r2(100~200]、r3(200~300]、r4(300~400]、r5(400~- Q6 F4 m3 {4 A3 Q4 Y( G) |
500]、r6(500~600],对应的SSTable文件分别记为sst1,sst2,……,sst6。假设每. }% O/ v7 y: t- X- B* `9 H0 _
个子表存储两个副本,那么,拷贝完SSTable文件后,可能的分布情况为:: ?6 A6 t7 l5 O; i. _ a/ A
A:sst1,sst3,sst4
! B4 @5 c" |5 x! n3 ~/ uB:sst2,sst3,sst52 j, U3 z8 D1 M. v' u7 @5 [8 i
C:sst1,sst4,sst6+ D5 t9 F0 ~: X- G6 O3 f! Z+ \& a" H
D:sst2,sst5,sst6
+ L8 [: C. M3 p( p5 M& W7 ?$ k- C接着,每个ChunkServer分别加载本地的SSTable文件,完成后向RootServer汇
7 N# D/ j, D7 |- v报。RootServer最终会将这些信息记录到RootTable中,如下:
5 M! _( p1 G! W9 Z& }$ U5 b8 ^r1(0~100]:A、C% o1 s+ T3 R) R2 y) ~
r2(100~200]:B、D
: U5 i: \: Z% w5 u1 D$ ur3(200~300]:A、B+ ?+ z; P) ^* g; ]- h1 C# B
r4(300~400]:A、C. S- a7 }+ I' n& f
r5(400~500]:B、D% q6 G9 Z y1 F. r0 I
r6(500~600]:C、D0 u0 q; F1 Z* d' Z5 Q
如果导入的过程中ChunkServer发生故障,例如拷贝sst1到机器C失败,那么,旁8 ^: f3 ^( H, V; l5 |
路导入模块会自动选择另外一台机器拷贝数据。
- J2 _$ N0 O# M' I. t. K. a- j当然,实现旁路导入功能时还需要考虑很多问题。例如,如何支持将数据导入: g' l6 \" \" e7 i1 m
到多个数据中心的主备OceanBase集群,这里不会涉及这些细节。( u7 ?. y6 ?& s7 K; O
9.5.3 数据分区
1 F" z8 |8 {8 t k虽然我们坚持认为通过单机性能优化以及硬件性能的提升,UpdateServer单点对( D9 L) n1 d9 t$ C$ ]
于互联网数据库业务不会成为瓶颈。但是,随着OceanBase的应用场景越来越广,例. k; q, X$ _) b4 K
如,存储原始日志,我们也可能需要实现更新节点可扩展。本节探讨一种可能的做
6 O! |- u! F/ P$ g+ Y法。
* `( O' K8 S, }4 D% ^$ }# {OceanBase可以借鉴关系数据库中的分区表的概念,将数据划分为多个分区,允
3 f W% g! ]+ b4 J许不同的分区被不同的UpdateServer服务。例如,将所有的数据按照哈希的方式划分
* n ~2 }4 ^' ^- Z2 \为4096个分区,这样,同一个集群中最多允许4096个写节点。
3 H* s+ Z- j7 e9 U如图9-11所示,可以将Users表格和Albums的user_id列按照相同的规则做哈希,# S; O! f7 m" Y n2 A: e% S
这样,同一个用户的所有数据属于相同的分区。由于同一个分区只会被同一个
; {4 o! _) q& G- n! t1 rUpdateServer服务,因此,保证了同一个用户下读写操作的事务性,另外,不同用户
6 Y4 n" k: w; ~" _1 ]( G6 `之间的事务可以通过两阶段提交或者最终一致性的方式实现。这种方式实现起来非
7 |- z, B L% j a0 R5 h常简单,而且能够完全兼容SQL语法。
; f5 F2 e1 T+ ] N图 9-11 哈希分区SQL语法
3 v" Q8 s3 k( t5 Y4 R: l从图8-1中的整体架构图可以看出,在目前的单更新节点架构中,UpdateServer进& e* z0 e; r$ K0 |3 `
程总是与ChunkServer进程部署到不同的服务器,而且两种服务器对硬件的要求不
/ \: X5 k. F# c* V: w同。如果OceanBase支持哈希分区,还能够将UpdateServer进程和ChunkServer进程部
3 O9 c6 }1 p( ?+ E署到一起,这样部署起来会更加方便。
3 M$ W9 _7 x7 c: _! Q除了哈希分区,OceanBase还能够通过范围分区实现更新节点可扩展,即不同的. g) Y3 J Q0 g' E
用户按照user_id有序分布到多台UpdateServer。虽然支持UpdateServer线性可扩展的
( K6 D6 t. n0 T/ @$ c2 x架构看似“比较优雅”,但是,这件事情并不紧急。这是因为,OLTP类应用对性能的, y( ]% z+ |% c6 E0 N& |
需求是有天花板的(例如全世界人口共50亿,即使其中五分之一的人都在某一天产
x. k0 X1 g2 j) c- C生了一笔交易,这一天的总交易笔数也只有10亿笔),单UpdateServer对于OLTP类数
% }9 T0 \9 |/ O8 i/ G: o% J$ i据库业务的性能是足够的。
k A# S9 I. L+ W4 L1 G- Z; f3 }* Y/ w4 E
6 }" v; t% T& X* Q+ e
|
|