|
9.5 消除更新瓶颈* v+ \8 M" f7 `
UpdateServer单点看起来像是OceanBase架构的软肋,然而,经过OceanBase团队
% z; d1 k7 N r3 r% b2 Z持续不断地性能优化以及旁路导入功能的开发,单点的架构在实践过程中经受住了1 l x3 b8 |4 y: D7 n) ^ ?
线上考验。每年淘宝网“双十一”光棍节,OceanBase系统都承载着核心的数据库业
0 y- @: e& Y6 t5 S3 B, X务,系统访问量出现5到10倍的增长,而OceanBase只需简单地增加机器即可。
1 v1 @* A3 y% V$ v( M7 Z当然,UpdateServer单点架构并不是不可突破。虽然目前UpdateServer单点架构" \+ P+ e* c5 D6 v# z
还不是瓶颈,但是OceanBase系统设计时已经留好了“后门”,以后可以通过对系统打
: q$ k# y9 \! `4 C$ u3 f4 L补丁的方式支持UpdateServer线性扩展。当然,这里可能会做一些牺牲,比如短期内8 o% O- m' m3 \: C% O
暂不支持全局事务,只支持针对单个用户的事务操作。
; s- C+ B4 i; n. {" S. d! ]; n本节首先回顾OceanBase已经实现的优化工作,包括读写性能优化以及旁路导入: b4 w6 I7 j3 r! [
功能,接着介绍一种数据分区实现UpdateServer线性扩展的方法。
9 V0 `. q0 g8 i" U( H9.5.1 读写优化回顾6 {% e* G" O2 P. w5 s
OceanBase UpdateServer相当于一个内存数据库,其架构设计和“世界上最快的内4 a" [ g. P5 X7 F
存数据库”MemSQL比较类似,能够支持每秒数百万次单行读写操作,这样的性能对; c* z' [; L# U7 }+ p3 C& {) I
于目前关系数据库的应用场景都是足够的。为了达到这样的性能指标,我们已经完% c: a6 u* Q( R u" ~
成或正在进行的工作如下。4 Y: e- q. c* A2 X) J4 E
1.网络框架优化: `/ _! l4 D/ Z" t5 ^ p x, q; A: G/ B
9.2.2 节中提到,如果不经过优化,单机每秒最多能够接收的数据包个数只有
/ }6 z2 Z) h/ b" J+ G10万个左右,而经过优化后的libeasy框架对于千兆网卡每秒最多收包个数超过50; @% ^$ u5 [! M( i8 }+ T
万,对于万兆网卡则超过100万。另外,UpdateServer内部还会在软件层面实现多块4 K w6 q5 p* C5 T- l
网卡的负载均衡,从而更好地发挥多网卡的优势。通过网络框架优化,使得单机支5 m- i5 ^- E, J4 n# v
持百万次操作成为可能。& }( n+ G1 d5 k4 y+ c$ d
2.高性能内存数据结构 K/ [+ ?" K; V& X
UpdateServer的底层是一颗高性能内存B树。为了最大程度地发挥多核的优势,B0 m# ?# A9 d. h. s- f
树实现时大部分情况下都做到了无锁(lock-free)。测试数据表明,即使在普通的16
/ H3 X# }$ z4 ]& t( Y# c核机器上,OceanBase B树每秒支持的单行修改操作都超过150万次。4 @" R& C( N4 i0 X6 o k
3.写操作日志优化! n9 C4 n4 [* t9 m6 h2 y+ K, D/ i
在软件层面,写操作日志涉及的工作主要有如下几点:/ D; Z, j5 Q; M2 {; e
1)成组提交。将多个写操作聚合在一起,一次性刷入磁盘中。5 `: Y- m( y8 l" }2 e% L
2)降低日志缓冲区的锁冲突。多个线程同时往日志缓冲区中追加数据,实现时: n) g# P+ C, J) z3 Q
需要尽可能地减少追加过程的锁冲突。追加过程包含两个阶段:第一个阶段是占
e& k. M7 g7 M4 A位,第二个阶段是拷贝数据,相比较而言,拷贝数据比较耗时。实现的关键在于只
! y) g: R2 c4 H! r# E2 `6 g o' b- M对占位操作互斥,而允许多线程并发拷贝数据。例如,有两个线程,线程1和线程: d* z- w. V. U' F, f' ?
2,他们分别需要往缓冲区追加大小为100字节和大小为300字节的数据。假设缓冲区
# q$ p+ N1 f% L' U' Y初始为空,那么,线程1可以首先占住位置0~100,线程2接着占住100~300。最$ T& g0 g+ e) I' r" b: z
后,线程1和线程2并发将数据拷贝到刚才占住的位置。3 ~2 f' u9 `4 s- k) E0 g
3)日志文件并发写入。UpdateServer中每个日志缓冲区的大小一般为2MB,如/ T6 z5 \* v* q* p) c
果写入太快,那么,很快会产生多个日志缓冲区需要刷入磁盘,可以并发地将这些
2 D! A0 `3 y5 V" _) u" Y日志缓冲区刷入不同的磁盘。当然,UpdateServer目前并没有实现2和3这两个优化; j& j- I4 |; Y$ Q
点。在硬件层面,UpdateServer机器需要配置较好的RAID卡。这些RAID卡自带缓
. k/ y C: T# b7 `" W存,而且容量比较大(例如1GB),从而进一步提升写磁盘性能。
8 c d0 r$ X5 z+ _& [6 T4.内存容量优化9 V6 M% ^7 U: C! `0 ^
随着数据不断写入,UpdateServer的内存容量将成为瓶颈。因此,有两种解决思
0 a# P4 H1 w3 r! ^: e路。一种思路是精心设计UpdateServer的内存数据结构,尽可能地节省内存使用;另- J# B5 B7 k! e. o
外一种思路就是将UpdateServer内存中的数据很快地分发出去。, x& Z. p3 `' O6 v% f
OceanBase实现了这两种思路。首先,UpdateServer会将内存中的数据编码为精
4 m& G9 e- p. f l$ K心设计的格式,从9.3.1节中可以看出,100以内的64位整数在内存中只需要占用两个' i' z! |( U& J
字节。这种编码格式不仅能够有效地减少内存占用,而且往往使得CPU缓存能够容
; s' m2 j5 t2 z s纳更多的数据,从而弥补编码和解码操作造成的性能损失。另外,当UpdateServer的+ B' G$ z) c/ S' e! |
内存使用量到达一定大小时,OceanBase会自动触发数据分发操作,将UpdateServer
6 }7 p) m' L W) o的数据分发到集群中的ChunkServer中,从而避免UpdateServer的内存容量成为瓶颈。
# ~) g8 J' k6 h# w& P当然,随着单机内存容量变得越来越大,普通的2U服务器已经具备1TB内存的扩展7 Q X; q( F! h/ T# ?" _2 e
能力,数据分发也可能只是一种过渡方案。
7 g; ]3 }) J6 ~+ ]6 m N0 P% F3 [% m1 r9.5.2 数据旁路导入
6 }* C* \9 q2 V7 P- G1 K; y6 a2 s虽然OceanBase内部实现了大量优化技术,但是UpdateServer单点写入对于某些
9 q) b" ]* J+ o, Q) s- IOLAP应用仍然可能成为问题。这些应用往往需要定期(例如每天,每个月)导入大
9 D0 Z( @* @: b! a# `* b0 S4 L; r批数据,对导入性能要求很高。为此,OceanBase专门开发了旁路导入功能,本节介4 [0 f) ^9 c- {8 U8 O, b7 r
绍直接将数据导入到ChunkServer中的方法(即ChunkServer旁路导入)。
8 E2 D% M- g" F8 n i2 |. `OceanBase的数据按照全局有序排列,因此,旁路导入的第一步就是使用Hadoop3 f5 W W$ h' o. Y' W
MapReduce这样的工具将所有的数据排好序,并且划分为一个个有序的范围,每个范
: E) w8 h9 \; [2 }7 Z围对应一个SSTable文件。接着,再将SSTable文件并行拷贝到集群中所有的
5 {& ]9 N8 t( {2 ~ChunkServer中。最后,通知RootServer要求每个ChunkServer并行加载这些SSTable文
" i% t6 N; P" n s件。每个SSTable文件对应ChunkServer的一个子表,ChunkServer加载完本地的SSTable
" }1 O# p! ]1 p E# v4 C文件后会向RootServer汇报,RootServer接着将汇报的子表信息更新到RootTable中。& |5 b/ a8 x( I! M
例9-7 有4台ChunkServer:A、B、C和D。所有的数据排好序后划分为6个范7 f6 `. d* n0 T; B! K {
围:r1(0~100]、r2(100~200]、r3(200~300]、r4(300~400]、r5(400~
$ M& K; y8 A- b$ @3 D500]、r6(500~600],对应的SSTable文件分别记为sst1,sst2,……,sst6。假设每
m0 z. _4 v( T" G$ R: F+ M个子表存储两个副本,那么,拷贝完SSTable文件后,可能的分布情况为:4 {; k* l+ {; u" I
A:sst1,sst3,sst4: \; h5 j( \( s9 u
B:sst2,sst3,sst56 Z& p8 ~8 u# p, g" j) a, }( a
C:sst1,sst4,sst6$ k: D, m& ^5 Y8 N: f
D:sst2,sst5,sst6
" Y! m* n0 y2 r2 f; |7 P接着,每个ChunkServer分别加载本地的SSTable文件,完成后向RootServer汇
; k1 Q* ]2 l$ F1 `6 o: o" [报。RootServer最终会将这些信息记录到RootTable中,如下:& J6 H; K( l# j
r1(0~100]:A、C; | \0 M* D# \5 v' C
r2(100~200]:B、D
X1 x* R) D# g/ zr3(200~300]:A、B3 R1 J+ O7 f( x+ G' Z! p
r4(300~400]:A、C! Y) K G; P3 B, z1 L& v, I
r5(400~500]:B、D
- U) Z1 f' ^7 H. t; ~- j# J4 @/ C u0 l7 tr6(500~600]:C、D
; f; z6 h& t5 N4 b如果导入的过程中ChunkServer发生故障,例如拷贝sst1到机器C失败,那么,旁
% }+ ?8 i. L+ R) C6 _路导入模块会自动选择另外一台机器拷贝数据。
# b% h6 l/ w3 o当然,实现旁路导入功能时还需要考虑很多问题。例如,如何支持将数据导入8 o; H5 K* K$ E5 Z: H1 D; ?0 ]
到多个数据中心的主备OceanBase集群,这里不会涉及这些细节。4 R7 h' E I8 C. {
9.5.3 数据分区8 F. A/ x: S$ o0 \
虽然我们坚持认为通过单机性能优化以及硬件性能的提升,UpdateServer单点对: t' m* N" R& W0 r$ I# H
于互联网数据库业务不会成为瓶颈。但是,随着OceanBase的应用场景越来越广,例
8 x( W. E& W0 ]) r& d/ Q如,存储原始日志,我们也可能需要实现更新节点可扩展。本节探讨一种可能的做
: ^4 t- l: a9 o# ~; @法。
4 u# q0 T4 C7 {OceanBase可以借鉴关系数据库中的分区表的概念,将数据划分为多个分区,允0 m+ s& o j" Q0 {$ A. |
许不同的分区被不同的UpdateServer服务。例如,将所有的数据按照哈希的方式划分4 B) _ D6 c7 |) x7 ]: w4 M) u
为4096个分区,这样,同一个集群中最多允许4096个写节点。6 x, N. L8 }- Y! y! k
如图9-11所示,可以将Users表格和Albums的user_id列按照相同的规则做哈希, h l9 x4 `- L
这样,同一个用户的所有数据属于相同的分区。由于同一个分区只会被同一个/ n0 z" w7 F4 J$ a c, x" B+ T
UpdateServer服务,因此,保证了同一个用户下读写操作的事务性,另外,不同用户
$ S. R; t. q. f/ ~" \之间的事务可以通过两阶段提交或者最终一致性的方式实现。这种方式实现起来非. q6 \" `- }1 [8 I1 u
常简单,而且能够完全兼容SQL语法。: U, ^" @- S# I
图 9-11 哈希分区SQL语法! g: A4 s m$ C& w; S
从图8-1中的整体架构图可以看出,在目前的单更新节点架构中,UpdateServer进4 X5 ]* u% v. {. d$ ]% u
程总是与ChunkServer进程部署到不同的服务器,而且两种服务器对硬件的要求不' X, N: a V4 F
同。如果OceanBase支持哈希分区,还能够将UpdateServer进程和ChunkServer进程部
1 A- s' f% I' J0 Q9 H署到一起,这样部署起来会更加方便。8 n$ ^( ?9 T; U0 {+ G3 z' E
除了哈希分区,OceanBase还能够通过范围分区实现更新节点可扩展,即不同的* _% w) ?6 U3 L6 H0 W5 k' `; l
用户按照user_id有序分布到多台UpdateServer。虽然支持UpdateServer线性可扩展的
! [9 z! I7 Y9 X架构看似“比较优雅”,但是,这件事情并不紧急。这是因为,OLTP类应用对性能的
' u- V- R2 l6 t$ A" F- E需求是有天花板的(例如全世界人口共50亿,即使其中五分之一的人都在某一天产
9 S4 j( j5 S+ j U4 k生了一笔交易,这一天的总交易笔数也只有10亿笔),单UpdateServer对于OLTP类数
# o% |( j$ u7 w5 x- k据库业务的性能是足够的。
2 d: C- G* w0 ?, r- p% A- W+ m$ K- E' r( w \+ x4 I
/ t; [' @% G8 |5 i |
|