当数据库遇到分布式,你会怎么做?
副标题[/!--empirenews.page--]
数据库通常有着完善的事务支持,但是局限于单机的存储和性能,于是就出现了各种分布式解决方案。最近读了《Designing Data-Intensive Applications》这本书,所以做一个总结,供大家做个参考,有什么不对的请大家指正,一起讨论。 数据模型 数据模型可以说软件开发中最重要的部分,因为影响着我们的思考方式、解题思路以及代码的编写方式。多数应用使用层层叠加的数据模型进行构建,对于每层数据模型的关键问题是:它如何用低一层的数据模型来表示。 多数应用程序开发都使用面向对象编程的编程语言来开发,所以一个数据模型是否能够很好表示对象以及对象之间的关系就成为我们选择的标准。 对象由各类属性组成,对象的关系通常有一对多/多对一和多对多。 关系模型 关系模型使用表、行、字段分别表示一类实体的集合、一个实体以及一个实体的一个属性;在其中一个实体的字段中存储另一实体的Id标识来表示实体之间多对一的关系,使用单独的关联表存储两个实体的Id标识来表示实体建多对多的关系。 关系模型具有强模式,必须在写数据前定义好,即写模式,类似编程语言的静态(编译时)类型检查。 下面的示例是Linked的一个简历的关系型表示: 文档模型 采用类似JSON的格式存储,存储的内容是文档型。利用JSON天然的嵌套关系可以灵活表示一对多的实体关系,当然通过存储文档的Id,也可以表示多对一和多对多的关系。 相对于关系模型,文档模型减少了应用程序代码和存储层之间的阻抗不匹配,在一对多关系下,具有更好的局部性。 文档模型具有读时模式,对写入没有模式要求。类似编程语言的动态(运行时)类型检查。 对于上面简历的例子,使用文档模型的表示如下: 图模型 图模型强调是对象之间的连接,当应用是围绕众多对象连接以及对这些连接进行的查询和计算时,就需要考虑使用图模型的数据库。 一个图由顶点(表示的是实体)和边(实体之间关系)组成,一个复杂的图模型通常由数十亿的顶点和千亿的边组成。 以下是社交网络的一个示例:表示的是两个人之间的以及居住地点。 每种数据模型都有其对应的查询语言,关系型使用SQL,而图模型也有相应的查询语言来描述图模型的特点,但是还没有形成业界标准。 存储引擎 上面我们熟悉了数据模型,但是了解数据内部的存储和检索原理,对于我们设计和开发应用以及数据库的选型也是非常有帮助的。 数据库的主要功能是存储数据以及后续进行查询和更新,目前主要有两大类数据库:传统关系型数据库(面向页面 page-oriented) 和 NoSQL数据库(基于日志结构log-structured)。 面向页面 B树是几乎是数据库标准的索引实现,B数将数据库分解成固定大小的块或页面,通常在4k-32k范围,一次只能读取或写入一个页面。这种设计更接近与底层的硬件,因为磁盘也是由固定大小的块组成的。 每个页面都可以使用地址来标识,一个页面引用另一个页面,类似于指针,但是在磁盘而不是在内存中,如图所示: 在B树的页面中对子页面的引用的数量称为分支因子,分支因子取决于页面大小和索引key的大小,分支因子越大越好。(分支因子为500的4KB页面的四级树可以存储多大256TB) 数据查询时,从根页面(通常缓存在内存)出发,根据页面引用寻找满足条件范围的页面,一直到叶子节点。 数据更新时,定位到叶子结点,用新数据覆盖磁盘的页面。 数据插入和删除时,会涉及到页面的拆分和合并,来保持B树的平衡 为了保证数据查询和写入的高性能,数据库通常会对页面数据进行内存缓存,当数据有更新时,不会立即更新磁盘数据,而是先更新内存缓存的页面数据,同步追加写入WAL日志(write-ahead-log),异步将内存中的脏页刷到磁盘上(将磁盘随机写变为顺序写)。当数据库崩溃后恢复时,这个日志用来是B树恢复到一致的状态。 日志结构 基于日志结构的存储模式,每次数据新增或更新时,仅仅将数据追加到特定日志文件中,当文件超过一定大小时,则打开一个新的文件写入。 每个日志结构存储段都是一系列键值对,但是为了后续便于查询数据,要求键值对在文件中按照键排序,这种排序的字符串表(Sorted String Table)称为SSTable。 为了保证日志文件保持在一定的个数,多个文件段进行合并(归并算法),当出现多个同一键值时,用新的值覆盖老的,保证一个合并段同一个键出现一次。 内存中维护者键到日志文件的索引,该索引是稀疏的,每几千个字节的段文件就有一个键就足够了,因为几千字节可以很快被扫描。(可以将部分记录分组到块,压缩写入磁盘) 如何构建和维护SSTable呢(保证按照键排序存储) 写入数据时(新增、删除、更改),将其添加到内存中的平衡树结构(如红黑树),这个内存树称为内存表(memtable); 为了避免丢失数据,写入内存表的同时会通过追加的方式写入WAL日志(数据库崩溃恢复时使用); 当内存表大于某个阈值(通常为几兆字节)时,将其作为SSTable文件写入磁盘。新的SSTable文件成为数据库的最新部分。 数据查询时,首先尝试在内存表中查找,然后在多个文件段中进行查找。(通过合并文件段使其维持在一定的个数,保证查找效率) 这种基于合并和压缩排序文件原理的存储引擎通常被称为LSM存储引擎。 当查找不存在的键时,LSM树算法可能会很慢。为了优化这种访问,通常使用额外的Bloom过滤器。 LSM树的基本思想 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |