目前有针对各种特殊场景设计的数据库系统。在实践中,可以根据具体应用的规模、复杂度和功能需求来选择合适的数据库。这与早期“用一套Oracle数据库解决所有问题”的信息化解决方案形成鲜明对比。数据库有四大操作:增、查、改、删,简称CRUD(Create、Read、Update、Delete)操作。不同数据库技术设计的本质是对这四种操作的性能进行优化和平衡。1、关系数据库和NoSQL关系数据库一直是信息技术发展的主流。随着大数据的出现,由于关系数据库在处理大数据时面临的挑战,针对某些特定场景,一种新的NoSQL数据库技术开始出现。NoSQL数据库可以提供丰富的数据模型支持、高吞吐量的“读”或“写”效率高以及良好的可扩展性。NoSQL数据库技术一般选择牺牲对复杂SQL和ACID事务的支持来换取弹性扩展能力。通常不保证强一致性,但支持最终一致性。同时,关系型数据库也在不断发展。通过支持列式存储模式和MPP分布式架构,它们在保持一定的关系型数据处理能力的基础上,也能获得良好的分析性能支持。关系数据库技术与NoSQL数据库技术之间,不同路线的技术不是完全的替代,而是互补的关系。综合应用更能满足不同场景的需求。(一)关系数据库理论及优势关系数据库(RelationalDatabase)建立在严格的关系数据模型之上,支持强事务,通过统一的结构化语言(SQL)进行操作。关系型数据库主要是为事务设计的,要求事务处理的正确执行和数据的正确性,即使在执行过程中遇到错误、断点、系统崩溃等异常。关系数据库严格遵循ACID原则。原子性:确保将事务视为一个单元,事务中的所有操作要么完成,数据库更新为新的状态,要么不完成,数据库状态保持不变。一致性:确保事务执行前后的数据库状态有效。ValidState是指事务完成后,数据库中的数据符合所有预定义的规则:约束(Constraint)、级联(CascadesofRollback)、触发器(Trigger)及其任意组合。一致性可以防止数据库被非法交易破坏。例如,参照完整性(ReferentialIntegrity)保证了主键-外键关系。一致性并不能从应用层保证事务是正确的。隔离性,又称独立性:保证事务并发执行得到的数据库状态与串行执行得到的数据库状态相同。为了提高数据库的处理效率,事务通常需要并行执行,例如多个事务同时读写一张表。为了保持隔离,需要对事务进行并发控制,不同级别的控制方式在事务之间提供不同的效率和影响平衡。持久性:事务一旦提交,即使系统出现故障,也能保证事务生效。为了实现上述原理,数据库需要实现同步锁、多版本并发控制(MVCC)、日志(Log)等功能。例如,在提交事务之前,将事务写入WAL(WriteAheadLog)。关系型数据库在理论、技术、商业产品、产业生态等方面都非常成熟。它们易于理解、易于使用且易于维护。除了支持交易,它们还支持一定程度的分析应用。(二)关系型数据库在处理大数据时遇到的挑战关系型数据库技术难以应对大数据场景下数据量大、增长速度快、响应时间长、内容丰富等数据处理需求。例子如下。低延迟、高并发:大数据时代需要海量数据的高效存储和访问,而关系型数据库受限于事务和架构。随着数据量的增加,它们的读写性能会迅速下降,难以实现高并发和实时动态的大数据量的获取和更新。可扩展性:在大数据时代,用户数量可能会出现爆发式增长,这就要求数据系统具备快速扩展的能力,而关系型数据库很难以方便、灵活、可扩展的方式满足这种需求。周期短、成本低的方式。模型自由:对于半结构化(如JSON)和非结构化数据(如文档、图片),关系型数据库只能将其存储为二进制数据块,不支持数据内容的检索和分析。大规模数据读取:数据统计分析经常需要批量读取数据。随着数据量的增长,传统关系型数据库在需要批量扫描读取数据时效率不够。有两种常见的解决方案:ScaleUp和ScaleOut。对于关系型数据库,纵向扩展是为了提高单台服务器的性能。这是IOE(IBM、Oracle、EMC)厂商向大型银行等机构提供的通用一体机解决方案。上限瓶颈明显,成本高;横向扩展是在数据库设计和应用层通过读写分离、分库分表等方式实现的,这会让应用层的实现和维护变得非常复杂和僵化,无法应对随着需求的快速变化。随着数据量的不断增长,我们需要不断地调整计划,这样效率很低,而且容易出错。(3)NoSQL数据库的特点NoSQL主要是指非关系型、分布式、无ACID的数据库设计模式,支持快速、大规模的水平扩展。NoSQL最常见的解释是“非关系”。NoSQL是一组彼此差异很大的数据库系统的总称,很难将它们归为一类。NoSQL数据库的数据模型主要包括键值模型(Key-Value)、列族模型(WideColumn)、文档模型(Document)、图模型(Graph)。另外,DB-ENGINES网站将搜索引擎(SearchEngine)系统视为NoSQL数据库,但严格来说,搜索引擎并不是一般意义上的数据库。DB-ENGINES网站还认为NoSQL包括RDF存储库、本机XMLDBMS和内容存储库。通过放宽标准关系数据模型和支持ACID原则,NoSQL数据库具有以下优势:更高的性能;易于将数据分布(如分片)在不同的节点上,从而实现可伸缩性(scalability)和容错性(faulttolerance);通过使用无模式数据模型提高灵活性;简化管理。2.Key-value模型数据库目前key-value数据库应用广泛,适用于高性能缓存场景,如session的数据存储,用户配置,购物车等,单次超低延迟读/写,高并发要求,内容简单,相互独立,但不适合事务处理,多键关系数据,统计分析。Amazon工程师分析了自己的数据库查询和使用情况,发现70%的工作负载是单键值操作,键值操作很少使用Oracle数据库提供的关系函数,另外20%的工作负载访问也仅限于一张表,只有10%的工作负载需要在使用关系数据库功能时跨多个键访问数据。(1)key-value模型介绍从用法上来说,key-value模型数据库是最简单的NoSQL数据库。客户端可以对key对应的value进行CRUD操作。键值数据库支持广泛的键值类型。key-value模型大大简化了传统的关系数据模型,相当于一张只有两个字段的表。key-value模型的实现类似于Map结构,在key和value之间建立映射关系。key-value模型数据库面向高效访问场景,应用广泛,如Memcached、Redis、DynamoDB等。(2)RedisRedis是一个开源的、key-value模型的NoSQL数据库,适合在高速响应场景下作为数据缓存使用,提供持久化数据的能力。Redis集群采用主从架构来实现高可用。Redis不是一个简单的key-value存储数据库,而是一个数据结构服务器。这里的取值不限于简单的字符串,还包括几种复杂的数据结构。Redis中的每条记录都有一个键和一个值。密钥是二进制安全的,这意味着任何二进制序列都可以用作密钥,例如字符串,或者JPEG图像文件的内容。最大支持512MB,但是key太长会影响存储效率和查询效率。Value支持五种数据结构类型:String、List、Hash、Set、Zset。下面描述了不同的数据结构类型。列表是按插入顺序排列的字符串列表。Hash是一个映射表,其字段和值都是String类型。Set是一个唯一的无序集合,其成员类型为String。Zset(或Sortedset)与Set的区别在于每个元素都关联一个分数,元素按照分数从小到大排序。为了支持多种值类型、优化存储、内存回收、共享对象等功能,Redis的值存储使用了内部定义的RedisObject结构。该结构包括五个字段:值数据结构类型(type)、内部编码格式(encoding)、最后访问时间(lru)、引用次数(refcount)、值或值指针(*ptr)。该结构在64位系统上占用16个字节。Redis支持多种数据结构类型。在不同的使用场景下,Redis会选择合适的内部编码来节省内存或优化性能。它可以节省高达90%的内存(平均50%),这对用户和API都是有利的。据说是透明的。内部编码涉及以下内容。String有三种内部编码:int(8字节)、embstr(≤44字节)、raw(>44字节)。当List元素数量较少时,使用ziplist(压缩列表)存储;当元素个数超过配置的阈值时,List会自动转为linkedlist(双向链表)存储。Ziplist是Redis专门为节省内存而开发的一种连续数据结构。同样的,Hash和Zset在数据量不大的时候也会使用ziplist存储。当超过配置的阈值时,它们将分别被转储到hashtable(哈希表)和skiplist(跳过链表)中。当Set的元素较少时,使用intset(一组整数)进行存储,当超过配置的阈值时,会转储到一个hashtable(哈希表)中。3.列族模型数据库列族模型数据库可以支持大量的动态列,与文档模型数据库具有类似无模式的特性,但实现方式完全不同。列族可以被认为是二维键值存储。注意,列族模型和列存储不是同一个概念。列族模??型数据库支持低延迟的单数据读写、高并发、灵活的表结构调整,但不适合需要大规模批量读取的统计数据分析。(1)列族模型介绍在列族模型数据库中,列族是预先定义的,而不是列。一个列族下可以有很多列,每个列族中的列数可以不同。列族下的数据存储在一起。列族是在建表时定义的,一般是不可变的,但也可以在后续使用中添加列。列族不需要像关系数据库的列那样预先定义数据类型,只要能将数据转换成字节数组即可。比较常见的开源列族模型数据库有Hbase、Cassandra/ScyllaDB。(2)HBaseHBase的设计思想来源于谷歌2006年发布的Bitable论文。HBase是一个开源的、分布式的、可扩展的、面向列族的NoSQL数据库。主要解决超大规模数据集的实时性和随机访问问题。其底层文件存储基于HDFS。HBase采用主从架构,主要由HBaseMaster(也称HMaster)和HRegionServer组成,并使用ZooKeeper进行协同管理。HBase通过水平划分表实现分布式存储,将一张表划分为多个部分(HRegion),同一张表的不同HRegion分布在不同的RegionServer上。HMaster负责创建、删除表等DDL(数据库定义语言)操作。同时负责在新表上线、集群启动、负载均衡时,将每个表的HRegion分配给RegionServers。ZooKeeper维护集群中所有节点的状态,例如节点故障。HBase中的表由行和列族组成,列族对应的逻辑概念是存储。HBase先写内存,然后把内存中的数据刷到HDFS,所以存储分为内存中的MemStore和HDFS上的StoreFile。HBase架构示意图如图1所示。▲图1HBase架构4.文档模型数据库文档模型数据库是无模式的,适用于处理半结构化数据,如日志、网页、内容等。不需要将文档解析成独立字段的表,但支持基于文档的方式,不适合复杂的交易场景对字段进行查询分析等操作。(1)文档模型简介文档模型数据库用于存储、检索和管理面向文档的信息。与关系数据库按字段进行处理不同,在文档模型数据库中,文档是信息处理的基本单位。文档格式其实是半结构化数据,一般是有序的键值对集合,支持嵌套结构,如XML、JSON、BSON等。文档模型没有预定义的schema,键值对文档不需要固定的类型和大小。常见的文档模型数据库有CouchDB、MongoDB等。(2)MongoDBMongoDB不需要像关系型数据库那样预先定义表结构,而是通过BSON将数据和结构保存在一起。参照关系数据库的库、表、行、列(字段)等层次,MongoDB的逻辑结构按照库、集合、文档、字段的顺序分层。但是,这些库和集合的功能与关系数据库中的库和表的功能相同。完全不同,主要是为了方便用户分类整理和管理数据。字段:每个字段包含两部分:字段名和字段值。字段名为字符串类型,区分大小写,字段名不能重复。字段值可以是string、int、long、double、boolean、subdocument、array等。Document:MongoDB中数据的基本存储单位。文档由BSON结构表示。文档中的字段是有顺序的,不同的顺序是不同的文档。每个文档都有一个默认的_id键,相当于关系数据库中的主键,默认为ObjectId类型。如果用户没有显式定义文档的_id值,MongoDB会自动生成。集合:集合由多个文档记录组成。集合是无模式的,即集合中的文档可以有不同的结构。文档中的字段可以在集合上建立索引。数据库:一个数据库可以包含多个集合。5.图模型数据库图模型数据库适用于处理知识图谱、推荐、反欺诈、物流、社交关系等场景。近年来,图模型数据库是各种数据库类型中增长最快的。目前最流行的图模型数据库仍然是2007年发布的开源图数据库Neo4j,但Neo4j不支持横向扩展,其处理数据规模受限于单机。集群模式仅用于高可用性和提高查询性能。支持水平扩展的图模型数据库是Titan开发的JanusGraph,其底层依赖Hbase、ScyllaDB等作为外部存储。分布式原生图模型数据库有2019年开源的Nebula和2017年发布的TigerGraph(未开源)。(一)图模型简介图模型数据库使用图结构进行语义查询,主要使用节点、边和属性来描述和存储数据。图模型可以高效地存储实体“关系”数据,这与关系数据库具有不同的含义。关系数据最常见的例子是人与人之间的关系、知识图谱。以图的形式表示实体之间的关系,对于关系的检索非常方便,无论是正向关系还是反向关系。如果使用关系型数据库处理“关系型”数据,需要使用外键关联数据,检索时需要进行表间JOIN操作。计算成本高,关系查找不易逆向。图结构是顶点、边和属性的集合。顶点:图中的一个节点,每个顶点都会有一个唯一的ID,顶点可以有一个或多个属性描述。边:边用来连接顶点,表达节点之间的关系。边可以是无方向的、单向的或双向的,边也可以有属性和ID。图通常使用邻接矩阵或邻接表等存储方案。邻接是指顶点之间的关系。如果两个顶点之间有边,则这两个顶点相邻。邻接矩阵和邻接表分别使用数组和链表作为基本的存储数据结构,所以数组和链表的优缺点就是邻接矩阵和邻接表的优缺点。邻接矩阵使用二维数组来存储图关系。矩阵的行和列代表顶点,相同的行号和列号对应相同的顶点。如果两个顶点之间存在关系,则将相应的数字存储在数组的相应位置。对于无向图,数组只能是0、1值,0表示没有关系,1表示有关系。使用数组存储数据可以实现数据的快速定位和更新,但是对于顶点数量多但边稀疏的图,比如路网图,会存在大量的存储浪费,所以邻接矩阵比较合适对于具有少量顶点和密集关系图片的关系。邻接表使用链表来存储图关系。顶点信息存储在一维数组中。数组的每个元素都是一个结构体对应一个顶点,每个元素存储一个指向该元素的邻接点的链表的指针。(2)Neo4jNeo4j是一个具有商业支持的开源图模型数据库。它是基于图的原生底层存储设计的,而不是嫁接在关系数据库之上。Neo4j具有以下特点:ACID事务处理模式、高可用性、可扩展到数十亿节点和关系、通过遍历实现高速查询、强大的图搜索能力。Neo4J通过Cypher语言操作数据库。Cypher是当前图模型数据库领域主流的图查询语言之一。Neo4j不支持数据规模水平扩展,但支持高可用集群模式Neo4jHA。Neo4j由独立的主数据库(Master)和从数据库(Slave)组成。Master主要负责数据写入,Slave从Master同步数据变化。Slave是Master的精确副本,以改进查询负载支持。如果Master出现故障,集群会选举一个新的Leader作为新的Master。6、搜索引擎系统搜索引擎系统并不是为数据库场景设计的,但在某些场景下可以替代数据库作为存储系统,比如文档数据处理、数据分析等。与数据抽取系统相比,搜索引擎系统具有以下特点:全文搜索;词干提取;复杂的搜索表达式;搜索结果的排名和分组;分布式搜索实现高可扩展性。搜索引擎系统所需的存储空间远大于其他数据库系统。此外,为了提高搜索性能,在插入和更新时需要消耗更多的计算和存储资源来建立索引。流行的开源搜索引擎系统有Elasticsearch和Solr,它们都是在全文搜索引擎工具包Lucene的基础上实现的。Elasticsearch是一个分布式、开源、全文搜索和分析引擎,适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。Elasticsearch存储文档并构建倒排索引,支持近实时、快速的全文搜索,可以找到所有包含单词的文档。它通常与Logstash和Kibana结合使用,Logstash用于日志收集,Kibana用于可视化展示,统称为ELK,广泛应用于日志处理领域。7、关系模型MPP数据库在需要大规模数据读取的数据分析场景中,传统的单机数据库已经不能满足需求,所以一些数据库厂商推出了MPP数据库一体机,但是价格很贵。这时候出现了运行在普通硬件集群上的开源MPP数据库软件,最典型的就是Greenplum。(1)Greenplum简介Greenplum数据库系统是基于PostgreSQL开源技术开发的。它实际上是由一组PostgreSQL数据库节点组成的,可以作为一个单一的数据库管理系统。PostgreSQL是目前最完善、健壮的开源关系型数据库,因此Greenplum在所有开源MPP数据库系统中也拥有最完善的功能支持。数据库用户与Greenplum数据库交互就像他们与常规PostgreSQLDBMS交互一样。Greenplum数据库的特点如下。并行数据加载;实施一个新的查询计划器;可以使用附加优化存储;支持行存储和列存储,可以为每个表指定。(2)Greenplum数据库架构Greenplum最初是为管理大型分析数据仓库和BI系统而设计的。Greenplum数据库通过在多个服务器之间分配数据和工作负载来存储和处理大量数据。它的架构实际上是由多个PostgreSQL数据库服务器组成的矩阵。Greenplum中的服务器节点按照功能分为两类:Master实例和Segment实例。Greenplum架构示意图如图2所示。▲图2 Greenplum架构Master是Greenplum数据库系统的入口,客户端通过Master上的数据库实例连接并提交SQL语句。全局系统目录存储在master上,但不包含任何用户数据。实际数据在Segments上存储和处理,Segments是独立的PostgreSQL数据库,每个Segments存储一部分数据并执行大部分查询处理。Master协调所有Segment数据库实例的工作。当用户在Master节点上执行SQL查询时,Master会将SQL和SQLPlan分发给所有Segment节点,Segment处理完数据后,Segment再将数据发回给Master节点。段在称为段主机的服务器上运行。一个分段主机通常运行2到8个Greenplum分段,具体取决于CPU内核、RAM、存储、网络接口和工作负载的数量。一般Segment实例所在的主机应该采用相同的配置,集群的Internet推荐使用10G网络。本文节选自《数据应用工程:方法论与实践》,经出版社授权发布。(ISBN:9787111704096)转载请保留文章出处。
