|
9.5 消除更新瓶颈% N5 Y0 N3 @6 \
UpdateServer单点看起来像是OceanBase架构的软肋,然而,经过OceanBase团队
; ~6 t0 E1 V. _* [持续不断地性能优化以及旁路导入功能的开发,单点的架构在实践过程中经受住了) P9 }' e# X( H, r
线上考验。每年淘宝网“双十一”光棍节,OceanBase系统都承载着核心的数据库业
7 ?+ S. P; x1 _1 P务,系统访问量出现5到10倍的增长,而OceanBase只需简单地增加机器即可。
s7 {7 S A: k. F7 ^当然,UpdateServer单点架构并不是不可突破。虽然目前UpdateServer单点架构* j9 g1 i# B' X4 j( [0 s& p0 I: i
还不是瓶颈,但是OceanBase系统设计时已经留好了“后门”,以后可以通过对系统打5 Z$ H$ B6 M' M1 z: p( n2 C
补丁的方式支持UpdateServer线性扩展。当然,这里可能会做一些牺牲,比如短期内% M& ?* m( d0 J3 p! p* ^
暂不支持全局事务,只支持针对单个用户的事务操作。
& B& P$ a" D7 M6 M本节首先回顾OceanBase已经实现的优化工作,包括读写性能优化以及旁路导入6 u3 p' @5 b7 s, N, _( {$ A
功能,接着介绍一种数据分区实现UpdateServer线性扩展的方法。2 C) @% a+ W0 ~, Z" C
9.5.1 读写优化回顾+ ?+ J# D2 H, e% P: R6 q
OceanBase UpdateServer相当于一个内存数据库,其架构设计和“世界上最快的内9 s1 ^0 w8 f$ {6 ~/ N. e3 P. Z7 P9 p
存数据库”MemSQL比较类似,能够支持每秒数百万次单行读写操作,这样的性能对6 v8 _" O ^2 z- c, z% e- v
于目前关系数据库的应用场景都是足够的。为了达到这样的性能指标,我们已经完2 v3 X% I2 W, ?0 E* u
成或正在进行的工作如下。/ f8 h. Q0 r# A5 d0 k9 e
1.网络框架优化
9 |- R1 _! O( l; w" j0 u4 m" d9.2.2 节中提到,如果不经过优化,单机每秒最多能够接收的数据包个数只有
! L0 n+ I1 o5 s+ K10万个左右,而经过优化后的libeasy框架对于千兆网卡每秒最多收包个数超过50
% Y, r0 x+ h! F& t+ I; K: W万,对于万兆网卡则超过100万。另外,UpdateServer内部还会在软件层面实现多块
2 F+ t* j' d' K网卡的负载均衡,从而更好地发挥多网卡的优势。通过网络框架优化,使得单机支4 @: T, S0 j" P7 j8 ]1 n$ t
持百万次操作成为可能。
2 t6 T+ O) ]/ A: E. d, M+ x2.高性能内存数据结构
2 `* \! v3 `8 a, nUpdateServer的底层是一颗高性能内存B树。为了最大程度地发挥多核的优势,B' d6 q. P0 o* x* |5 T
树实现时大部分情况下都做到了无锁(lock-free)。测试数据表明,即使在普通的16
7 E9 M! l) Z" |/ x" ]( k7 I% \核机器上,OceanBase B树每秒支持的单行修改操作都超过150万次。+ X( `/ h2 n% x+ z
3.写操作日志优化& F- y4 A/ t2 }
在软件层面,写操作日志涉及的工作主要有如下几点:
. x% B" p+ A5 U1)成组提交。将多个写操作聚合在一起,一次性刷入磁盘中。) `: e) T5 I6 V) u( b! d, c
2)降低日志缓冲区的锁冲突。多个线程同时往日志缓冲区中追加数据,实现时
; S& U- X, @ Z! u需要尽可能地减少追加过程的锁冲突。追加过程包含两个阶段:第一个阶段是占
/ t: R1 D5 n: O1 Q/ q位,第二个阶段是拷贝数据,相比较而言,拷贝数据比较耗时。实现的关键在于只; t! g* y1 `- g0 L
对占位操作互斥,而允许多线程并发拷贝数据。例如,有两个线程,线程1和线程& v: q' o" ?$ |- U
2,他们分别需要往缓冲区追加大小为100字节和大小为300字节的数据。假设缓冲区
3 C9 B9 H/ U: F. o, d初始为空,那么,线程1可以首先占住位置0~100,线程2接着占住100~300。最
8 j, W& ^( d. |; D8 v后,线程1和线程2并发将数据拷贝到刚才占住的位置。
* ]) J9 t. U) n6 ^5 N3)日志文件并发写入。UpdateServer中每个日志缓冲区的大小一般为2MB,如( k, X5 d4 s, S& }( N, u
果写入太快,那么,很快会产生多个日志缓冲区需要刷入磁盘,可以并发地将这些$ L. ~7 U3 k/ B3 ?3 C# ?# c9 r
日志缓冲区刷入不同的磁盘。当然,UpdateServer目前并没有实现2和3这两个优化% _% E/ B8 {- P$ O
点。在硬件层面,UpdateServer机器需要配置较好的RAID卡。这些RAID卡自带缓
- ~: j1 j1 U5 w. S; X- R" j存,而且容量比较大(例如1GB),从而进一步提升写磁盘性能。9 d4 q: W0 j2 h
4.内存容量优化
9 n& Z& F8 X- T" {4 u* ?) r3 C随着数据不断写入,UpdateServer的内存容量将成为瓶颈。因此,有两种解决思
0 h2 m. B/ n1 L" @, D路。一种思路是精心设计UpdateServer的内存数据结构,尽可能地节省内存使用;另% M ^, X$ k- Y- w4 ?" y) o
外一种思路就是将UpdateServer内存中的数据很快地分发出去。% R% Y0 q$ [+ m
OceanBase实现了这两种思路。首先,UpdateServer会将内存中的数据编码为精7 N- E. y2 j8 Y# u6 I7 z. ^
心设计的格式,从9.3.1节中可以看出,100以内的64位整数在内存中只需要占用两个
5 I$ }" d6 q! _ H6 p" x" j! r字节。这种编码格式不仅能够有效地减少内存占用,而且往往使得CPU缓存能够容
" q- P6 Q4 |' [. A/ k" x. ?纳更多的数据,从而弥补编码和解码操作造成的性能损失。另外,当UpdateServer的' Q' A# J$ z, Z& t; D _; I% k9 {! B
内存使用量到达一定大小时,OceanBase会自动触发数据分发操作,将UpdateServer
8 O! t! s8 N! `! h) ^的数据分发到集群中的ChunkServer中,从而避免UpdateServer的内存容量成为瓶颈。
3 A+ i C: K5 _当然,随着单机内存容量变得越来越大,普通的2U服务器已经具备1TB内存的扩展* Y; f; d8 N' ]# C% L
能力,数据分发也可能只是一种过渡方案。
; E$ X) R) a: E* f3 N) L' T9.5.2 数据旁路导入- f. z+ v' C! C; K4 c# X$ {
虽然OceanBase内部实现了大量优化技术,但是UpdateServer单点写入对于某些
/ X# y( F7 r5 ~7 J% J$ POLAP应用仍然可能成为问题。这些应用往往需要定期(例如每天,每个月)导入大
0 L. n1 z8 ^ W* X% e- N批数据,对导入性能要求很高。为此,OceanBase专门开发了旁路导入功能,本节介
' k' N+ D) k1 O% Y绍直接将数据导入到ChunkServer中的方法(即ChunkServer旁路导入)。
( b* L7 o% b/ |OceanBase的数据按照全局有序排列,因此,旁路导入的第一步就是使用Hadoop9 G% g) t; P! o" m+ ~ z* |
MapReduce这样的工具将所有的数据排好序,并且划分为一个个有序的范围,每个范
7 f' e5 c3 t, i1 z- I+ S围对应一个SSTable文件。接着,再将SSTable文件并行拷贝到集群中所有的- L* H6 P1 r& x7 Y
ChunkServer中。最后,通知RootServer要求每个ChunkServer并行加载这些SSTable文
- H0 O# }% S9 y# i5 X件。每个SSTable文件对应ChunkServer的一个子表,ChunkServer加载完本地的SSTable& y) f/ `) }# v* I
文件后会向RootServer汇报,RootServer接着将汇报的子表信息更新到RootTable中。$ g3 d3 e3 ^, I" X
例9-7 有4台ChunkServer:A、B、C和D。所有的数据排好序后划分为6个范
9 y, d) l! P. U- b7 m围:r1(0~100]、r2(100~200]、r3(200~300]、r4(300~400]、r5(400~; g1 {0 T+ L$ H1 z
500]、r6(500~600],对应的SSTable文件分别记为sst1,sst2,……,sst6。假设每
! [* s9 J" v% x! t4 J9 h个子表存储两个副本,那么,拷贝完SSTable文件后,可能的分布情况为:
1 C' r. ?, H0 P, l9 M* `" h" FA:sst1,sst3,sst4
4 Y! U6 `& K! r" \$ YB:sst2,sst3,sst55 ~" ] X; T$ @3 K) D
C:sst1,sst4,sst6! R+ A2 l; @" u8 ?8 j9 V9 [, n
D:sst2,sst5,sst6$ e# z0 {3 N/ F8 d# q N
接着,每个ChunkServer分别加载本地的SSTable文件,完成后向RootServer汇
& E; @- C( n `: q+ L" y! b1 \; J报。RootServer最终会将这些信息记录到RootTable中,如下:* \1 i7 E5 m1 _: o" J
r1(0~100]:A、C) U W$ J& o0 k9 \/ [7 R- Y
r2(100~200]:B、D+ v4 S0 `6 L$ [, L; s
r3(200~300]:A、B- n' b; F e3 J& _$ r5 V9 i- `9 I
r4(300~400]:A、C
2 K' H* x0 Y# vr5(400~500]:B、D
1 G2 b5 c$ ~* F/ Q* ]/ B$ M5 Hr6(500~600]:C、D( f, d0 C; d# P2 H$ B. \* u
如果导入的过程中ChunkServer发生故障,例如拷贝sst1到机器C失败,那么,旁( b! C6 t5 ^7 t! W
路导入模块会自动选择另外一台机器拷贝数据。* y8 }! `( x5 q* Q0 L; [+ p/ V
当然,实现旁路导入功能时还需要考虑很多问题。例如,如何支持将数据导入4 n) {$ H; `; Q+ Y& m
到多个数据中心的主备OceanBase集群,这里不会涉及这些细节。
( z/ S6 U; v0 e) P* M, j6 }9.5.3 数据分区
: j; ]: i3 M+ J' i8 e虽然我们坚持认为通过单机性能优化以及硬件性能的提升,UpdateServer单点对
! L Y1 [/ ~4 v- q. }- S5 N9 u7 N于互联网数据库业务不会成为瓶颈。但是,随着OceanBase的应用场景越来越广,例
2 k" X! }8 o4 H如,存储原始日志,我们也可能需要实现更新节点可扩展。本节探讨一种可能的做
5 K# Y+ K8 F( _. q9 [法。! z5 B9 l8 }2 G2 _4 o8 d
OceanBase可以借鉴关系数据库中的分区表的概念,将数据划分为多个分区,允
W5 d" W4 N8 g5 t- t* y许不同的分区被不同的UpdateServer服务。例如,将所有的数据按照哈希的方式划分
' i2 ~7 n7 y6 E$ Z O- I( _/ d为4096个分区,这样,同一个集群中最多允许4096个写节点。
) X6 s4 m2 T' }& o, ~# P' L( L如图9-11所示,可以将Users表格和Albums的user_id列按照相同的规则做哈希,! q$ w) m* K; Y- R; ]
这样,同一个用户的所有数据属于相同的分区。由于同一个分区只会被同一个
0 l$ B& A1 y# \) I! e fUpdateServer服务,因此,保证了同一个用户下读写操作的事务性,另外,不同用户
& T5 ?! d' F) i之间的事务可以通过两阶段提交或者最终一致性的方式实现。这种方式实现起来非
& z" T9 f# C9 a7 B常简单,而且能够完全兼容SQL语法。
3 j3 X+ R. q. M+ G# V( y0 C图 9-11 哈希分区SQL语法$ H& }( r* X# H0 y
从图8-1中的整体架构图可以看出,在目前的单更新节点架构中,UpdateServer进
; @* h/ {9 P# M程总是与ChunkServer进程部署到不同的服务器,而且两种服务器对硬件的要求不* S0 v5 K3 L5 F- A" c `
同。如果OceanBase支持哈希分区,还能够将UpdateServer进程和ChunkServer进程部
0 E" Y G' h& ~0 S署到一起,这样部署起来会更加方便。
" g: S6 v. { S& h& h& g+ t除了哈希分区,OceanBase还能够通过范围分区实现更新节点可扩展,即不同的
4 v+ F2 a/ u* o- g; p* _用户按照user_id有序分布到多台UpdateServer。虽然支持UpdateServer线性可扩展的0 ]7 W! V3 v3 [6 P6 E
架构看似“比较优雅”,但是,这件事情并不紧急。这是因为,OLTP类应用对性能的
. ~% M$ a9 c# R$ }2 J! G9 Y! g需求是有天花板的(例如全世界人口共50亿,即使其中五分之一的人都在某一天产/ Z' u, h/ b6 _* t
生了一笔交易,这一天的总交易笔数也只有10亿笔),单UpdateServer对于OLTP类数
9 X; L3 d# B- ~& i2 m2 r$ }1 ~据库业务的性能是足够的。: X: |* J8 x5 [$ {3 b C# }, {
" h9 E8 v# P$ g/ w$ |; O
# h# f. v2 I6 U* D% g u |
|