SequoiaDB巨杉数据库大对象块存储原理与应用

时间:2024-05-22 18:38:49

一、前言

企业内容管理(Enterprise Content ManagementECM)系统是一种管理非结构化内容的系统,传统代表为EMC DocumentumIBM FilenetECM解决方案。随着大数据技术的越发普及,越来越多的客户开始尝试把存放在传统ECM系统中的文件、图片、影像等内容向开放分布式平台迁移。一般来说,用户可以选择的方案根据场景与数据类型来看可以分为几类,包括HDFS方案、对象存储方案、NAS方案、以及分布式数据库方案等。

其中,HDFS方案主要面向数据归档,对大量打成大包的文件直接存放,一般不提供在线读写功能,主要的目的是替代磁带。

NAS方案则类似HDFS,使用独立第三方传统数据库作为元数据管理系统,同时使用外接NAS设备存放中小型文件。一般来说,NAS作为文件系统可以支持较多数量的小文件,但是当小文件数量达到亿级时同样会产生管理、访问性能与扩展性等一系列问题。

对象存储则以S3等接口为通用标准,设备提供商可以在底层使用K/V存储或块存储等不同存储机制,同时提供类似对象访问、版本管理等一系列功能特性。

最后,分布式数据库方案则使用分布式数据库中的大对象机制,将元数据与大对象统一存放在数据库中,在支持批次管理、版本管理、流程管理等元数据管理特性时不需要借助额外第三方数据库进行支持。

二、功能概述

SequoiaDB(巨杉数据库)是一款新一代分布式文档类数据库,同时支持事务与标准SQL的结构化数据访问方式。在同类开源分布式数据库中,SequoiaDB是唯一一款原生集成行存储与块存储双引擎的数据库。除了JSON存储引擎以外,为了提高非结构化文件的读写性能,SequoiaDB核心引擎提供了分布式块存储模式,可以将非结构化大文件按照固定大小的数据块进行切分并存放于不同分区。当用户需要管理海量的小文件(例如照片、音视频、文档、图片等)时,SequoiaDB的双存储引擎特性能够帮助用户快速搭建一个高性能、高可用的内容管理与影像平台系统。使用SequoiaDB搭建的影像平台系统架构相对简单,元数据与内容数据均可使用SequoiaDB服务器的本地磁盘存放,不再需要额外购买昂贵的外部存储设备,节省企业的开发和运维成本。

SequoiaDB的块存储字段类型叫做LOBLarge OBject,大对象),其核心机制是将内容文件打散成多个数据块,每个数据块被分别发送到不同分区独立存放。与其他解决方案相比,由于不存在独立中控元数据节点,SequoiaDB提供的LOB存储机制理论上可以存放近乎无限数量的对象文件,并且不会由于元数据堆积而造成性能下降。同时,由于数据块被散列分布到所有数据节点,整个系统的吞吐量随集群磁盘数量的增加近乎线性提升。最后,SequoiaDB提供原生的内容管理接口,通过REST访问方式支持批次管理、版本管理、流程管理等一系列基本CM特性。

从使用方式上看,SequoiaDBLOB机制可以使用原生API的访问形式,对底层LOB对象进行读写访问;同时,用户也可以通过高阶CM API Java接口,Java驱动会将请求封装成RESTful形式,通过发送接收HTTP报文进行对象和批次级别读写更新操作。

 

三、架构

SequoiaDBLOB存储结构分为元数据文件(lobm)与数据文件(lobd)。其中,元数据文件存储整个LOB数据文件的元数据模型,包括每个页的空闲状况、散列桶、以及数据映射表等一系列数据结构。而数据文件则存储用户真实数据,数据头之后所有数据页按照page size进行切分,每个数据页不包含任何元数据信息。

SequoiaDB巨杉数据库大对象块存储原理与应用

1LOB元数据与数据文件结构映射

在建立集合的过程当中,大对象存储必须依附于普通集合存在,一个集合中的大对象仅归属于该集合,不能被另外一个集合管理。

当用户上传一个大对象时,会经历几次散列操作。 

首先,协调节点或客户端会生成(或者用户指定)一个全局唯一的描述符,同时将传入的数据按照用户指定的pagesize大小切片,最后针对每一个切片按照(描述符+切片id)进行散列,用于决定该切片存在哪个数据分区中。注意,集合的分区键设定并不作用于大对象。

在每个分区中,当接收到数据分片后会根据(描述符+切片id)进行再一次散列,决定元数据桶的位置。而真实数据则通过查找元数据信息,在数据文件中找到一个最近的空闲页写入,然后将该页的ID写入元数据桶中,代表该桶指向这个数据页。如果散列后数据桶已经被占用,则使用常规散列冲突的解决方式找到下一个空闲桶。

当用户读取大对象时,协调节点按照其(描述符+偏移+长度)计算出需要读取多少个切片,以及每个切片所在的数据分区,最后将数据节点返回的数据按顺序排列返回客户端。

由于SequoiaDB将文件切片存储,一个大文件可能存在有非常多个分片,所以在访问的时候协调节点还需要进行请求合并,尽可能使用最小的报文一次性请求多个连续的数据页,以防止访问一个对象时协调节点需要向数据节点发送成千上万的此类请求,同时对数据节点做到I/O合并,一次性读入尽可能多的连续页面。

 

四、行业应用案例

企业内容管理平台

随着网络技术的渐渐普及,越来越多的银行开始将传统渠道向互联网与移动端靠拢。随之而来的,是更多监管业务的需要,例如针对远程开户等业务,银行需要开始提供“双录”能力,对用户的音频与视频数据进行存储。传统EMCIBM提供的企业内容管理系统以小机加高端存储硬件为基础,对于仅存票据证照等相对小量的图片存储还可以勉强满足需要,但是当存储类型扩展到音视频等领域性能并不出色,同时开销还会指数级增加。

SequoiaDB提供的分布式、双引擎以及对象存储的功能,天然为海量的音视频、影像、证照等内容提供了分布式存储的能力。SequoiaDB可以使用高存储密度的PC服务器替代传统的小机加高端存储的配置,能够使用户以1/5的拥有成本,提供更多的存储空间与更高的吞吐能力。

SequoiaDB巨杉数据库大对象块存储原理与应用

2:基于SequoiaDB的新一代企业内容管理平台与旧平台的对比

 

SequoiaDB内容管理解决方案中,数据库除了提供基本的记录与文件的读写操作外,还提供了内容管理平台的批次管理、版本管理、流程控制等一系列后台管控能力,为与用户中间件对接提供了最大便利。

SequoiaDB巨杉数据库大对象块存储原理与应用

3SequoiaDB内容管理平台架构图

五、操作指南

SequoiaDB提供基于shell的命令行界面,以及CC++JavaPythonPHPNodejs等驱动访问原生LOB API。同时,SequoiaDB提供访问协议的CM API Java接口。本文将会就命令行、C++Java以及CM API接口进行详细描述。

5.1      命令行

名称

参数

类型

说明

putLob

oid

string

大对象OID

file_path

string

大对象文件的本地路径

forced

boolean

如果大对象OID已经存在则直接覆盖

deleteLob

oid

string

大对象OID

getLob

oid

string

大对象OID

file_path

string

大对象文件的本地路径

forced

boolean

如果本地文件已经存在则直接覆盖

listLobs

-

-

-

1:命令行操作指令

样例:

>  db.foo.bar.putLob('/opt/sequoiadb/standalone/diaglog/sdbdiag.log')

579f55b7389d2aef0a000000

Takes 0.166125s.

> db.foo.bar.listLobs()

{

    "Size": 29342,

    "Oid": {

      "$oid": "579f55b7389d2aef0a000000"

    },

    "CreateTime": {

      "$timestamp": "2016-08-01-21.59.19.939000"

    },

    "Available": true

}

Return 1 row(s).

Takes 0.6703s.

>   db.foo.bar.getLob('579f55b7389d2aef0a000000',   '/opt/sequoiadb/standalone/test.log')

{

    "LobSize": 29342,

    "CreateTime": {

      "$timestamp": "2016-08-01-21.59.19.939000"

  }

}

Takes 0.910s.

 

5.2      C++

sdbclient::sdbCollection类:

名称

参数

类型

说明

createLob

lob

sdbLob &

传出对象

oid

bson::OID *

指定OID,如果不指定则自动生成

removeLob

oid

bson::OID &

大对象OID

openLob

lob

sdbLob &

传出对象

oid

bson::OID &

指定OID

listLobs

cursor

sdbCursor &

传出游标

2sdbCollection类中LOB相关函数

sdbclient::sdbLob类:

名称

参数

类型

说明

close

-

-

-

read

len

UINT32

一次读取长度

buf

CHAR *

缓冲区指针

read

UINT32 *

真实读取长度,传出参数

write

buf

CHAR *

缓冲区指针

len

UINT32

一次写入长度

seek

size

SINT64

转移偏移

whence

SDB_LOB_SEEK

寻址起始方式

isClosed

-

-

-

isClosed

flag

BOOLEAN &

本对象是否已被关闭的传出参数

getOid

-

-

-

getOid

oid

bson::OID &

本对象的Oid传出参数

getSize

-

-

-

getSize

size

SINT64 *

本对象大小的传出参数

getCreateTime

-

-

-

getCreateTime

millis

UINT64 *

本对象创建时间的传出参数

3sdbLob类中的相关函数

样例代码可以参考安装目录下samples/CPP/lob.cpp文件。

5.3      Java

com.sequoiadb.base.DBCollection类:

名称

参数

类型

说明

createLob

id

ObjectId

指定创建对象

createLob

-

-

-

openLob

id

ObjectId

指定打开对象

removeLob

id

ObjectId

指定删除对象

listLobs

-

-

-

4DBCollection类中LOB相关函数

com.sequoiadb.base.DBLob类:

名称

参数

类型

说明

getID

-

-

-

getSize

-

-

-

getCreateTime

-

-

-

write

b

byte[]

写入字节数组

read

b

byte[]

读取字节数组

seek

size

long

转移偏移

seekType

int

寻址起始方式

close

-

-

-

5DBLob类中的相关函数

样例代码可以参考安装目录下samples/Java/com/sequoiadb/samples/Lob.java文件。

5.4      CM API

名称

参数

类型

说明

createBatch

itemTypeBean

ItemTypeBean

批次信息属性封装对象

userId

String

用户ID

deleteBatch

batchId

String

批次ID

userId

String

用户ID

updateBatch

iteamTypeBean

ItemTypeBean

批次信息属性封装对象

userId

String

用户ID

queryItemByBatchID

batchId

String

批次ID

version

int

版本号

queryItemByType

batchId

String

批次ID

type

String

类型

queryBatch

map

Map

批次匹配条件

queryItem

map

Map

文档匹配条件

putContent

path

String

上传文档

getContent

oid

String

对象OID

path

String

下载文档存储路径

6CM API中的相关函数

六、性能指标

6.1      系统配置

本文测试使用3台物理机作为服务器与1台物理机作为客户端。客户端使用C程序与服务端直连,使用LOB API进行读写访问操作。

服务端
  CPU:Intel® Xeon® CPU E5-2420 0 @1.90GHZ(6core *2)  (一台物理机)
  CPU:Intel® Xeon® CPU E5-2620 [email protected] 2.10GHZ (6core *2) (二台物理机)
  MEMORY:48
  DISK: 2T/6块
  客户端
  CPU:Intel® Xeon® CPU E5-2420 0 @1.90GHZ(6core *2)  (一台物理机)
  MEMORY:48
  DISK: 2T/6块












集群部署方式为6分区3副本,三台机器构成高可用集群,网络为千兆网,协调节点与编目节点分别部署在3台服务器上。数据节点分布见表3,其中红色部分代表该分区的主节点,黑色为从节点。

部署      角色

分区1

分区2

分区3

分区4

分区5

分区6

192.168.3.78

disk1

disk2

disk3

disk4

disk5

disk6

192.168.3.79

disk1

disk2

disk3

disk4

disk5

disk6

192.168.3.72

disk1

disk2

disk3

disk4

disk5

disk6

7:数据节点分布

6.2      写操作测试

文件系统的配置分别使用两种方式:打开DIO以及用普通文件系统缓存方式。

DIO模式

线程数

文件大小

写操作数量

TPS(MB/s)

TPS(ops/s)

50

146998

201620

47.10791391

343.8

100

146998

214133

50.03153918

357.27

300

146998

222832

52.06403468

371.49

500

146998

215038

50.24298974

358.057

800

146998

185968

43.45087062

309.1






50

811769

56303

72.64618875

94.35

100

811769

57673

74.41386149

96.45

300

811769

62301

80.38524066

105.47

500

811769

59982

77.39309972

102.34

800

811769

60004

77.4214857

101.77






50

1896452

23111

69.66416386

38.96

100

1896452

26518

79.9339837

45.97

300

1896452

25260

76.14195747

43.93

500

1896452

26553

80.03948523

44.43

800

1896452

26930

81.17588736

44.65






50

299965

114141

54.4203203

190.65

100

299965

126282

60.20892482

210.83

300

299965

136820

65.23324855

228.02

500

299965

135630

64.66587853

225.7

800

299965

130531

62.23476953

216.73

8DIO模式

普通文件系统模式

线程数

文件大小

写操作数量

TPS(MB/s)

TPS(ops/s)

50

146998

264871

61.88632211

441.4516667

100

146998

303467

70.90416283

505.7783333

300

146998

337284

78.8054044

562.14

500

146998

351829

82.20380043

586.3816667

800

146998

336921

78.72059052

561.535






50

811769

59785

77.13891612

99.64166667

100

811769

63255

81.61616023

105.425

300

811769

62133

80.16847496

103.555

500

811769

61177

78.93497485

101.9616667

800

811769

64792

83.59930841

107.9866667






50

1896452

27426

82.67099468

45.71

100

1896452

27269

82.19774499

45.44833333

300

1896452

27331

82.3846334

45.55166667

500

1896452

27345

82.42683401

45.575

800

1896452

26470

79.7892959

44.11666667






50

299965

143673

68.50063236

239.455

100

299965

163098

77.76211352

271.83

300

299965

171627

81.82858317

286.045

500

299965

169584

80.85451851

282.64

800

299965

171306

81.6755363

285.51

9:文件系统模式

可以看到,打开DIO与普通文件系统缓存相比,性能确实存在一定下降。在三台服务器的情况下,尺寸较小的文件在DIO打开的情况下显示出与普通文件系统缓存更大的差异。当文件尺寸平均达到1-2MB左右后,使用DIO与普通文件系统的差异几乎可以忽略不计。图1显示了启用与关闭DIO的情况下,在800线程并发中整个集群的吞吐量(MB/s)。

SequoiaDB巨杉数据库大对象块存储原理与应用

4:写操作吞吐量对比

6.3      读操作测试

不同于写操作,SequoiaDB LOB机制在读操作中受DIO的影响较小。

DIO模式


线程数

缓存大小

读取数量

TPS(MB/s)

TPS(ops/s)

50

131072

37162

112.0185045

61.94

100

131072

37151

111.9853469

61.92

300

131072

37057

111.7019999

61.9

500

131072

37020

111.5904697

61.4

800

131072

37340

112.5550551

62.17






50

262144

36841

111.0509048

61.4

100

262144

37066

111.7291289

61.91

300

262144

37046

111.6688423

61.74

500

262144

37046

111.6688423

61.74

800

262144

37354

112.5972557

61.95






50

2097152

37189

112.0998914

61.99

100

2097152

37156

112.0004185

61.93

300

2097152

37061

111.7140572

61.77

500

2097152

37049

111.6778853

61.75

800

2097152

37385

112.6906999

62.31

10DIO模式

普通文件系统模式

线程数

缓存大小

读取数量

TPS(MB/s)

TPS(ops/s)

50

131072

37223

112.2023786

61.96

100

131072

37247

112.2747225

62.02

300

131072

37331

112.5279261

62.21

500

131072

37430

112.8263447

62.38

800

131072

37581

113.2815085

62.64






50

262144

37222

112.1993643

61.94

100

262144

37252

112.2897941

62.06

300

262144

37337

112.5460121

62.24

500

262144

37410

112.7660582

62.25

800

262144

37554

113.2001216

62.59






50

2097152

37223

112.2023786

61.96

100

2097152

37259

112.3108944

62.09

300

2097152

37353

112.5942414

62.31

500

2097152

37422

112.8022301

62.37

800

2097152

37560

113.2182076

62.6

11:文件系统模式

在文件读取的过程当中,因为绝大部分读取都是顺序I/O,因此是否打开文件系统缓存基本对性能不构成影响。从性能读数可以看出,SequoiaDB LOB读取时每次读取的缓存大小对于读取性能基本上不构成太大的影响。

测试中吞吐量上限基本达到客户端千兆网瓶颈,因此通过增加网络带宽依然有可以提升的空间。

SequoiaDB巨杉数据库大对象块存储原理与应用

5:读操作吞吐量对比

七、结论

SequoiaDB的大对象机制主要为用户存储海量中小型文件所设计。通过配置pagesize大小,SequoiaDB在存储100KB100MB区间内的文件性能与磁盘开销比例最优,因此针对各个企业的票据、扫描件、合同件、照片、小视频、音频等文件最为适用。

总体来看,使用SequoiaDB替代传统ECM,为企业存储海量中小型文件不单能够大大降低企业的总体拥有成本,还能够大幅度提升数据访问层面的吞吐量,并从开发、运维、管理等各个层面大幅度降低使用难度,帮助企业更快地在企业内容管理系统上落地。







SequoiaDB巨杉数据库大对象块存储原理与应用