迷彩 潜伏 隐蔽 伪装
分类: 数据库开发技术
2014-01-06 20:39:20
原文地址:Symfoware的高可用和高性能技术探秘 作者:skykiker
Symfoware是一款富士通的关系型数据库,诞生于1990年,目前在日本本土市场占有约8%的份额,名列前五。如今Symfoware已发展到V12,但是V12与之前的版本截然不同,分为Open和Native两个部分。Native版还是以前的Symfowre,Open版已经是基于开源的PostgreSQL定制的了。并且将来Open版可能会完全取代Native版。这么做的目的主要是想改善旧Symfoware对SQL标准支持不足,不易和其他关系数据库互换的问题。
由于SQL标准支持不足导致的“不易使用”确实可以说是Native Symfoware(或V11以前的旧Symfoware)的一大顽疾,我们公司整天和它打交到的开发和测试人员深有体会(尤其是用过PostgreSQL之后)。然而Native Symfoware也有不少值得称道的地方,而这些闪光点往往正是体现在那些看上去很"难用"的功能上(有些不可思议)。
正巧最近有时间看了一本介绍Symfoware的日文书《Symfowareの実力》(本文的插图全部来自此书),结合这些年开发Symfofware的经验,深深感到Native Symfwoarec中采用的一些技术还是很有特点的,尤其是关于高可用和高性能(水平扩展)的。下面就简单介绍几个。
1、DSO和DSI
Symfoware中数据通过DSO(Data Structure Organization)和DSI(Data Structure Instance)进行存储空间的分配。DSO和DSI是Symfoware特有的概念。DSO定义数据的存储形式(顺序,随机,BTree等)和分区方法,每个表或索引都有一个对应的DSO。DSI定义数据chu在表空间中的分配。每个DSO可以对应1个或多个DSI,1个DSI又可以将存储区域映射到1个或多个表空间。这样通过DSO/DSI的介入,数据在物理存储上的分布可以非常灵活。
部分日文词汇翻译:インデックス(索引)
一个DSO对应多个DSI的情形实现了数据的分区。比如,通过下面例子中的定义可以将表SCH01.TABLE01的数据根据"位置"的值分散到不同存储区域。
CREATE TABLE SCH01.TABLE01 ( ...,位置 NCHAR,...);
CREATE DSO DSO01 FROM SCH01.TABLE01
TYPE SEQUENTIAL(PAGESIZE(4),ORDER(1))
WHERE(位置) = (?);
CREATE DSI 北京DSI DSO DSO01
USING(N'北京') ALLOCATE DATA ON DBSP_1 SIZE 100M
CREATE DSI 上海DSI DSO DSO01
USING(N'上海') ALLOCATE DATA ON DBSP_2 SIZE 100M
CREATE DSI 南京DSI DSO DSO01
USING(N'南京') ALLOCATE DATA ON DBSP_3 SIZE 100M
:
一个DSI对应多个表空间实现了无限制的动态容量扩张。当数据量增长到超出原来分配的存储设备容量时,可以添加一个新的存储设备并新建一个表空间指向它。然后动态的把新建的表空间的全部或部分容量追加分配给原有的DSI。
比如:
CREATE DBSPACE DBSP_4 ALLOCATE RAWDEVICE /dev/raw/raw13;
ALTER DSI TB1_DSI1 ADD ALLOCATE ON DBSP_4 SIZE 1000M;
注:DSO和DSI虽然很有用,但很多使用者往往深切的感到创建表后还要附带创建跟着一堆参数的DSO和DSI太繁琐。所以V10以后对那些不那么需要精确控制存储参数的场景提供了建表时就自动创建DSO和DSI的选项。
2、Log Group
数据库IO负载的分散通常通过前面提到的分区技术实现,但是分区只能分散"数据"的IO,不能分散Log的IO。当事务并发非常高的时候Log的IO也相当可观,更重要的是基于Log技术的备份和恢复也必须在整个数据库级别实施。针对这个问题Symfoware提出了一个独特的解决方案"Log Group"。即把数据连同Log分成若干个Log Group,每个Log Group管理不同的数据,各自独立地记录Log,可以分别进行备份和恢复。为确保事务的原子性,当一个事务操作跨多个Log Group时,Symfoware内部采用了二阶段提交的方式。从某种意义上讲,每个Log Group都像一个独立的“物理数据库”,而所有Log Group合在一起形成一个“逻辑数据库”。通过Log Group,Symfoware在DSI分区的基础上再次提高了可扩展性。
部分日文词汇翻译:データ(数据)、ログ(日志)
数据究竟归属哪个Log Group是在创建表空间时指定的。由于在逻辑结构(表,索引)到表空间之间有前面介绍的DSO,DSI作为存储映射的中介,因此逻辑数据在Log Group上的分布可以非常灵活的定制,既支持按库、表的垂直划分,也支持按表分区的水平划分。
例:
CREATE DBSPACE DBSP_4 ALLOCATE RAWDEVICE /dev/raw/raw13 ATTRIBUTE LOG GROUP LGP1;
注:创建表空间时如果不指定Log Group,实际使用的是默认的系统Log Group,系统Log Group是一个特殊的Log Group,会存储一些全局数据,比如数据字典。
3、Load Share
Symfoware的负载均衡方案称之为"Load Share",它是Share Nothing并且是“多主”的。组成Load Share的集群中的每个节点都平等地对应用公开读写访问接口,但是每个节点只处理隶属于自己的一个或多个Log Group。各个节点负责的Log Group互不重叠,当应用请求的数据不在本节点维护的Log Group时需要向持有数据的那个节点(称为数据偏在节点)请求数据,收到数据处理后再返回给应用。为确保事务的原子性,跨节点资源的事务访问采用二阶段提交。这些对应用是透明的,所以应用可以选择连接集群中的任意一个节点。
并且不需要借助额外的机制,Load Share集群自身就有故障移转的机制。虽然一个Log Group只能由一个节点访问,但一个Log Group可以指定一个由多个节点组成的中继链,链中的第一个节点是主节点。当第一个节点宕机时,由下一个节点接替这个Log Group,并以此类推。通过这种方式可以很灵活的配置备机。
有专门备机的配置实例:
下面的配置中,每个Log Group都把待机节点配置成中继链中的第二个节点。这样任一台主节点宕机都可以由待机节点接替。
比如:
N-1A(B,C): 节点1,待机节点
N-2A(B,C): 节点2,待机节点
N-3A(B,C): 节点3,待机节点
部分日文词汇翻译:データ(数据)、ノード(节点)、ダウン(宕机)
无专门备机的配置实例:
下面的配置中,每个Log Group都把所有节点配置到中继链中,但是中继链的节点次序不一样,从而达到负载分担的目的 。
比如:
N-1A: 节点1,节点2,节点3,节点4
N-1B: 节点1,节点3,节点4,节点2
N-1C: 节点1,节点4,节点2,节点3
...
部分日文词汇翻译:データ(数据)、ノード(节点)、ダウン(宕机)
Symfoware的Load Share机制既能实现性能提升接近线性的水平扩展(随着业务量的增加动态追加Log Group和服务节点),又可以在不增加额外备机投入的情况下消除单点故障。但是需要注意的是,Load Share虽然是"Share Nothing"的,但为了应对故障移转,Load Share集群需要一个共同的存储服务器。
注:在Load Share集群中有一个特殊的节点,称之为Capital,相对应的其他节点叫Satellite。Capital的特殊之处在于它托管的是系统Log Group。本文的“节点”通常都是指Satellite节点。
4、Connection Manager
前面讲的Load Share技术使得所有节点看上去都是等价的,应用可以连接任意一个节点。然而实际上应用可能只对某一个特定的Log Group感兴趣,如果它连接的节点不是这个Log Group的数据偏在节点,会照成连接节点和数据偏在节点之间产生额外的IO及CPU负载。所以出于性能的考虑,这类应用应该连接到它所关注的Log Group的数据偏在节点。然而,即使应用知道哪个节点现在是自己所关注的Log Group的数据偏在节点,并且已经连接到了正确的节点,当Load Share集群由于宕机等原因发生节点状态变迁时,也需要应用程序及时做出应对。数据偏在节点的判断以及动态切换这类工作如果完全交给应用程序是不恰当的,于是有了Connection Manager。
Connection Manager和应用程序运行在同一台机器上,并且有一部分功能内嵌在客户端API驱动(JDBC,ODBC等)里。应用程序通过API驱动透明地向Connection Manager请求一个虚拟的服务器,Connection Manager将这个虚拟服务器名翻译成一组节点的IP和端口号,并根据节点的运行状况(生死,负载,Log Group偏在)选择一个最合适的节点返回给应用,通过这种方式还可以达到负载均衡的目的。Load Share + Connection Manager的这种架构省掉了集中式的负载均衡器,避免了一个很容因引发性能瓶颈和单点故障的机会。需要注意的是在每个应用服务器节点上都有一个Connection Manager实例,所以Connection Manager的负载均衡只是在一个应用节点的复数并发连接上做负载均衡,不是跨应用节点的。
部分日文词汇翻译:データ(数据)、ノード(节点)
Connection Manager还支持故障移转,当应用连接的DB节点宕机时,Connection Manager会自动化切换到下一个节点。故障如果发生在两个事务的间隙,那么故障移转对应用是完全透明的,如果故障发生在事务处理中,那么应用需要重试事务。
5、Mirror Control & Grand Connection Manager
Mirror Control用于构建完全冗余的HA集群。主机和备机间通过日志传送保持同步,并且备机可以同时提供只读服务。Connection Manager对Mirror Control同样提供了故障移转的支持。当主节点宕机时,Connection Manager会自动把应用的连接切换到备节点。并且Connection Manager对备节点是预先连接好的,所以切换速度很快。通过Connection Manager应用还可以选择连接到备机做查询业务,这样可以不增加主机的负载。
构成HA集群的2台主机有时自己不能正确判断对方是否宕机,比如发生网络故障时。为解决这个问题通常需要专门的硬件或独立的仲裁节点。然而Symfoware采用了一种很巧妙的方法,从安装了Connection Manager的应用节点中选举一台作为作为仲裁节点,仲裁的相关功能整合到了Connection Manager中,作为仲裁节点的Connection Manager被称为"Grand Connection Manager"。当构成HA集群的节点发现联络不上另外一个节点时,询问Grand Connection Manager,并根据Grand Connection Manager的答复做出相应行动。