|
5.2 淘宝Tair
+ c; D( N9 R2 C& x8 L1 o) l% |Tair是淘宝开发的一个分布式键/值存储引擎。Tair分为持久化和非持久化两种使
1 f& b% Y5 d! k( J0 N- [用方式:非持久化的Tair可以看成是一个分布式缓存,持久化的Tair将数据存放于磁 Q6 i( J* P$ n. ~8 P1 H
盘中。为了解决磁盘损坏导致数据丢失,Tair可以配置数据的备份数目,Tair自动将" y, T/ B& h3 ]: \9 h
一份数据的不同备份放到不同的节点上,当有节点发生异常,无法正常提供服务的. u! Q1 O4 z ~5 n: P5 T
时候,其余的节点会继续提供服务。
8 I4 ^9 [3 e |* w, i2 r' B; m' Q" _5.2.1 系统架构
5 k4 R) x: O- r/ r# G( H: rTair作为一个分布式系统,是由一个中心控制节点和若干个服务节点组成。其2 b; y+ B3 H. N
中,中心控制节点称为Config Server,服务节点称为Data Server。Config Server负责; t- W4 o# O7 }2 X
管理所有的Data Server,维护其状态信息;Data Server对外提供各种数据服务,并以; y; q. c+ x; }' B# H+ s
心跳的形式将自身状况汇报给Config Server。Config Server是控制点,而且是单点,: E) t- K4 R# b' S
目前采用一主一备的形式来保证可靠性,所有的Data Server地位都是等价的。/ j6 h7 e' w& K. Y# M: G5 ~
图5-5是Tair的系统架构图。客户端首先请求Config Server获取数据所在的Data
+ F, O X* a1 y4 Q6 uServer,接着往Data Server发送读写请求。Tair允许将数据存放到多台Data Server,以/ I3 \6 C. R* d' h( r- }, @
实现异常容错。
" G1 C0 s7 u: h9 {$ I; v6 W图 5-5 Tair系统架构# W& t& i3 K+ S4 m& _' Y
5.2.2 关键问题
" a- e; _+ X- Z# z! c0 J o(1)数据分布
1 t. Q: D- {# F: l& A" u根据数据的主键计算哈希值后,分布到Q个桶中,桶是负载均衡和数据迁移的基
" B3 ?* ~6 v+ v. k7 ^本单位。Config Server按照一定的策略把每个桶指派到不同的Data Server上。因为数
+ O1 U; l7 N+ _9 m, H, |# N据按照主键计算哈希值,所以可以认为每个桶中的数据基本是平衡的,只要保证桶. A9 S6 R- [% R. u6 H8 e
分布的均衡性,就能够保证数据分布的均衡性。根据Dynamo论文中的实验结论,Q
" y/ E4 N7 \% k6 m' k8 X取值需要远大于集群的物理机器数,例如Q取值10240。; z# o( p7 Y8 w& e2 N" B- |
(2)容错( E- ]6 b, \3 |6 A9 q1 v
当某台Data Server故障不可用时,Config Server能够检测到。每个哈希桶在Tair
0 f; w+ ^0 F N# g/ T中存储多个副本,如果是备副本,那么Config Server会重新为其指定一台Data4 @3 d! w& ?" }& H
Server,如果是持久化存储,还将复制数据到新的Data Server上。如果是主副本,那5 p0 j2 q0 r8 V d' y- d
么ConfigServer首先将某个正常的备副本提升为主副本,对外提供服务。接着,再选
, U2 ]: G) J! P6 r) Y择另外一台Data Server增加一个备副本,确保数据的备份数。
/ b- X5 R3 R4 y1 H( @(3)数据迁移
+ s$ B: V& v! Q: o2 m机器加入或者负载不均衡可能导致桶迁移,迁移的过程中需要保证对外服务。
- y# @7 H0 f( ^: J; a当迁移发生时,假设Data Server A要把桶3、4、5迁移到Data Server B。迁移完成2 t5 x0 m/ u2 I1 }/ a
前,客户端的路由表没有变化,客户端对3、4、5的访问请求都会路由到A。现在假$ s' g) d) M! Y$ ~/ |
设3还没开始迁移,4正在迁移中,5已经迁移完成。那么如果对3访问,A直接服务;
% B% h& [ _2 ^) i* |, S5 g$ e5 L如果对5访问,A会把请求转发给B,并且将B的返回结果返回给用户;如果对4访. S4 W: ^9 ]: d( g; q
问,由A处理,同时如果是对4的修改操作,会记录修改日志,等到桶4迁移完成时, y8 C7 Y4 l8 K6 ?! C- U b5 t1 L
还要把修改日志发送到B,在B上应用这些修改操作,直到A和B之间数据完全一致迁% c0 K/ g0 _3 _! Y* K
移才真正完成。5 V# N( \7 d o8 S0 a
(4)Config Server
C5 r6 Q: G! X0 M( O2 V+ `客户端缓存路由表,大多数情况下,客户端不需要访问Config Server,Config
l1 M$ f! x1 c& nServer宕机也不影响客户端正常访问。每次路由的变更,Config Server都会将新的配 j% D+ g1 E! U; _3 ~$ y: M
置信息推给Data Server。在客户端访问Data Server的时候,会发送客户端缓存的路由
. |* B7 Q; \3 X% M* |表的版本号。如果Data Server发现客户端的版本号过旧,则会通知客户端去Config
. M" z7 h3 y/ V7 \) k+ N+ lServer获取一份新的路由表。如果客户端访问某台Data Server发生了不可达的情况& W \2 I7 | o' q
(该Data Server可能宕机了),客户端会主动去Config Server获取新的路由表。2 M$ @/ m6 S) f! \* u6 F5 _
(5)Data Server4 L: a |% c5 @" o7 A- J2 d# @
Data Server负责数据的存储,并根据Config Server的要求完成数据的复制和迁移! @& X- B9 C' J7 }" {7 }
工作。Data Server具备抽象的存储引擎层,可以很方便地添加新存储引擎。Data
6 [ P- m* H0 Y7 Y/ w4 UServer还有一个插件容器,可以动态加载/卸载插件,如图5-6所示。
9 { V$ X4 q1 ` U# Z" z图 5-6 Data Server内部结构
9 s. o1 }* \/ g& {Tair存储引擎有一个抽象层,只要满足存储引擎需要的接口,就可以很方便地替
5 b$ I2 x* M- [% E; O. T% _& d换Tair底层的存储引擎。Tair默认包含两个存储引擎:Mdb和Fdb,此外,还支持
" O5 w5 a$ e& r( x I# y% a1 q, wBerkerly DB、Tokyo Cabinet、InnoDB、Leveldb等各种存储引擎。
- Z6 \, Y5 l& C: k& k' B( _/ C* e5.2.3 讨论$ B! I2 \4 |! d# r$ ?( ]6 @3 [
Amazon Dynamo采用P2P架构,而在Tair中引入了中心节点Config Server。这种方
* f( b7 A' l1 U8 N式很容易处理数据的一致性,不再需要向量时钟、数据回传、Merkle树、冲突处理
8 E: m( z6 ^6 y, w等复杂的P2P技术。另外,中心节点的负载很低。笔者认为,分布式键值系统的整体+ q# {7 K/ w# O' m3 }7 B6 _
架构应该参考Tair,而不是Dynamo。
5 H7 A* U9 X0 L9 ?8 ]当然,Tair最主要的用途在于分布式缓存,持久化存储起步比较晚,在实现细节/ i0 i3 V$ z/ z. t l: g
上也有一些不尽如人意的地方。例如,Tair持久化存储通过复制技术来提高可靠性,/ I4 W3 b) F+ Z/ ~. F. D: A
然而,这种复制是异步的。因此,当有Data Server发生故障时,客户有可能在一定时' P* }1 R$ x$ y7 b6 s
间内读不到最新的数据,甚至发生最新修改的数据丢失的情况。
: X* I& V" x) U/ Y( w# e8 o
Z0 R' `) r/ m& \
. O! B3 A; e+ V5 s |
|