SequoiaDB巨杉数据库大对象块存储原理与应用
来源:互联网 发布:知乎问题 编辑:程序博客网 时间:2024/06/05 14:48
一、前言
企业内容管理(Enterprise Content Management,ECM)系统是一种管理非结构化内容的系统,传统代表为EMC Documentum或IBM Filenet等ECM解决方案。随着大数据技术的越发普及,越来越多的客户开始尝试把存放在传统ECM系统中的文件、图片、影像等内容向开放分布式平台迁移。一般来说,用户可以选择的方案根据场景与数据类型来看可以分为几类,包括HDFS方案、对象存储方案、NAS方案、以及分布式数据库方案等。
其中,HDFS方案主要面向数据归档,对大量打成大包的文件直接存放,一般不提供在线读写功能,主要的目的是替代磁带。
而NAS方案则类似HDFS,使用独立第三方传统数据库作为元数据管理系统,同时使用外接NAS设备存放中小型文件。一般来说,NAS作为文件系统可以支持较多数量的小文件,但是当小文件数量达到亿级时同样会产生管理、访问性能与扩展性等一系列问题。
对象存储则以S3等接口为通用标准,设备提供商可以在底层使用K/V存储或块存储等不同存储机制,同时提供类似对象访问、版本管理等一系列功能特性。
最后,分布式数据库方案则使用分布式数据库中的大对象机制,将元数据与大对象统一存放在数据库中,在支持批次管理、版本管理、流程管理等元数据管理特性时不需要借助额外第三方数据库进行支持。
二、功能概述
SequoiaDB(巨杉数据库)是一款新一代分布式文档类数据库,同时支持事务与标准SQL的结构化数据访问方式。在同类开源分布式数据库中,SequoiaDB是唯一一款原生集成行存储与块存储双引擎的数据库。除了JSON存储引擎以外,为了提高非结构化文件的读写性能,SequoiaDB核心引擎提供了分布式块存储模式,可以将非结构化大文件按照固定大小的数据块进行切分并存放于不同分区。当用户需要管理海量的小文件(例如照片、音视频、文档、图片等)时,SequoiaDB的双存储引擎特性能够帮助用户快速搭建一个高性能、高可用的内容管理与影像平台系统。使用SequoiaDB搭建的影像平台系统架构相对简单,元数据与内容数据均可使用SequoiaDB服务器的本地磁盘存放,不再需要额外购买昂贵的外部存储设备,节省企业的开发和运维成本。
SequoiaDB的块存储字段类型叫做LOB(Large OBject,大对象),其核心机制是将内容文件打散成多个数据块,每个数据块被分别发送到不同分区独立存放。与其他解决方案相比,由于不存在独立中控元数据节点,SequoiaDB提供的LOB存储机制理论上可以存放近乎无限数量的对象文件,并且不会由于元数据堆积而造成性能下降。同时,由于数据块被散列分布到所有数据节点,整个系统的吞吐量随集群磁盘数量的增加近乎线性提升。最后,SequoiaDB提供原生的内容管理接口,通过REST访问方式支持批次管理、版本管理、流程管理等一系列基本CM特性。
从使用方式上看,SequoiaDB的LOB机制可以使用原生API的访问形式,对底层LOB对象进行读写访问;同时,用户也可以通过高阶CM API Java接口,Java驱动会将请求封装成RESTful形式,通过发送接收HTTP报文进行对象和批次级别读写更新操作。
三、架构
SequoiaDB的LOB存储结构分为元数据文件(lobm)与数据文件(lobd)。其中,元数据文件存储整个LOB数据文件的元数据模型,包括每个页的空闲状况、散列桶、以及数据映射表等一系列数据结构。而数据文件则存储用户真实数据,数据头之后所有数据页按照page size进行切分,每个数据页不包含任何元数据信息。
图1:LOB元数据与数据文件结构映射
在建立集合的过程当中,大对象存储必须依附于普通集合存在,一个集合中的大对象仅归属于该集合,不能被另外一个集合管理。
当用户上传一个大对象时,会经历几次散列操作。
首先,协调节点或客户端会生成(或者用户指定)一个全局唯一的描述符,同时将传入的数据按照用户指定的pagesize大小切片,最后针对每一个切片按照(描述符+切片id)进行散列,用于决定该切片存在哪个数据分区中。注意,集合的分区键设定并不作用于大对象。
在每个分区中,当接收到数据分片后会根据(描述符+切片id)进行再一次散列,决定元数据桶的位置。而真实数据则通过查找元数据信息,在数据文件中找到一个最近的空闲页写入,然后将该页的ID写入元数据桶中,代表该桶指向这个数据页。如果散列后数据桶已经被占用,则使用常规散列冲突的解决方式找到下一个空闲桶。
当用户读取大对象时,协调节点按照其(描述符+偏移+长度)计算出需要读取多少个切片,以及每个切片所在的数据分区,最后将数据节点返回的数据按顺序排列返回客户端。
由于SequoiaDB将文件切片存储,一个大文件可能存在有非常多个分片,所以在访问的时候协调节点还需要进行请求合并,尽可能使用最小的报文一次性请求多个连续的数据页,以防止访问一个对象时协调节点需要向数据节点发送成千上万的此类请求,同时对数据节点做到I/O合并,一次性读入尽可能多的连续页面。
四、行业应用案例
企业内容管理平台
随着网络技术的渐渐普及,越来越多的银行开始将传统渠道向互联网与移动端靠拢。随之而来的,是更多监管业务的需要,例如针对远程开户等业务,银行需要开始提供“双录”能力,对用户的音频与视频数据进行存储。传统EMC、IBM提供的企业内容管理系统以小机加高端存储硬件为基础,对于仅存票据证照等相对小量的图片存储还可以勉强满足需要,但是当存储类型扩展到音视频等领域性能并不出色,同时开销还会指数级增加。
SequoiaDB提供的分布式、双引擎以及对象存储的功能,天然为海量的音视频、影像、证照等内容提供了分布式存储的能力。SequoiaDB可以使用高存储密度的PC服务器替代传统的小机加高端存储的配置,能够使用户以1/5的拥有成本,提供更多的存储空间与更高的吞吐能力。
图2:基于SequoiaDB的新一代企业内容管理平台与旧平台的对比
在SequoiaDB内容管理解决方案中,数据库除了提供基本的记录与文件的读写操作外,还提供了内容管理平台的批次管理、版本管理、流程控制等一系列后台管控能力,为与用户中间件对接提供了最大便利。
图3:SequoiaDB内容管理平台架构图
五、操作指南
SequoiaDB提供基于shell的命令行界面,以及C、C++、Java、Python、PHP、Nodejs等驱动访问原生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 &
传出游标
表2:sdbCollection类中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 *
本对象创建时间的传出参数
表3:sdbLob类中的相关函数
样例代码可以参考安装目录下samples/CPP/lob.cpp文件。
5.3 Java
com.sequoiadb.base.DBCollection类:
名称
参数
类型
说明
createLob
id
ObjectId
指定创建对象
createLob
-
-
-
openLob
id
ObjectId
指定打开对象
removeLob
id
ObjectId
指定删除对象
listLobs
-
-
-
表4:DBCollection类中LOB相关函数
com.sequoiadb.base.DBLob类:
名称
参数
类型
说明
getID
-
-
-
getSize
-
-
-
getCreateTime
-
-
-
write
b
byte[]
写入字节数组
read
b
byte[]
读取字节数组
seek
size
long
转移偏移
seekType
int
寻址起始方式
close
-
-
-
表5:DBLob类中的相关函数
样例代码可以参考安装目录下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
下载文档存储路径
表6:CM 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 V2@ 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
表8:DIO模式
普通文件系统模式
线程数
文件大小
写操作数量
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)。
图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
表10:DIO模式
普通文件系统模式
线程数
缓存大小
读取数量
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读取时每次读取的缓存大小对于读取性能基本上不构成太大的影响。
测试中吞吐量上限基本达到客户端千兆网瓶颈,因此通过增加网络带宽依然有可以提升的空间。
图5:读操作吞吐量对比
七、结论
SequoiaDB的大对象机制主要为用户存储海量中小型文件所设计。通过配置pagesize大小,SequoiaDB在存储100KB到100MB区间内的文件性能与磁盘开销比例最优,因此针对各个企业的票据、扫描件、合同件、照片、小视频、音频等文件最为适用。
总体来看,使用SequoiaDB替代传统ECM,为企业存储海量中小型文件不单能够大大降低企业的总体拥有成本,还能够大幅度提升数据访问层面的吞吐量,并从开发、运维、管理等各个层面大幅度降低使用难度,帮助企业更快地在企业内容管理系统上落地。
产品特性
解决方案与案例
数据库下载
技术文档
微信客服:
sequoiadb111
- SequoiaDB巨杉数据库大对象块存储原理与应用
- NewSQL数据库大对象块存储原理与应用
- SequoiaDB(巨杉数据库)是企业级NoSQL分布式大数据库
- 腾讯云存储实践与SequoiaDB数据库详解
- 巨杉数据库SequoiaDB的安装部署
- 巨杉数据库SequoiaDB的常用操作
- 巨杉数据库SequoiaDB分区介绍
- 巨杉数据库SequoiaDB备份恢复方案
- python使用sequoiadb巨杉数据库
- 数据库存储大对象
- 【技术解密】SequoiaDB分布式存储原理
- 【技术解密】SequoiaDB分布式存储原理
- SequoiaDB巨杉数据库,开源分布式数据库
- SequoiaDB 受邀参加旧金山Spark 技术峰会,与Spark联手推动大数据企业级应用
- SequoiaDB 受邀参加旧金山Spark 技术峰会,与Spark联手推动大数据企业级应用
- 巨杉数据库创始人兼CTO王涛:SequoiaDB为何要开源?
- SequoiaDB巨杉数据库2.6版本正式发布啦
- SequoiaDB巨杉数据库的分区类型和分区方式
- 谷歌正式发布Android 8.0,TestBird支持Android Oreo测试
- JAVA开发的23种设计模式之 --- 状态模式
- Android中解析不规则json的理解(基于Gson)
- navigationview的样式设置
- 记录一下关于编码的问题
- SequoiaDB巨杉数据库大对象块存储原理与应用
- PAT甲级1002. A+B for Polynomials (25)
- maven学习笔记:命令行模式创建scala_spark项目并运行程序
- iframe 高度自适应,并且子页面的高度不断变化
- Java处理csv文件
- F: 火柴棒等式
- (六)Spring Boot整合mybtis
- 安卓Socket使用之服务器端
- 机器学习基础知识