针对 SaaS 应用程序的基于 Hibernate 框架的数据库分片
SaaS 正在改变设计、构建、部署和操作应用程序的方式。开发一个 SaaS 应用程序与开发一个通用企业应用程序之间的关键区别在于,SaaS 应用程序必须是多租户的。其他关键 SaaS 需求,比如安全性、定制、面向服务的架构(SOA)和集成,也影响 SaaS 应用程序架构。
多租户是指应用程序在单一代码库内寄存多个承租者并共享数据库等架构的能力。有多种设计选项可启用多租户数据架构 — 每个承租者的专用数据库、每个承租者的共享数据库独立模式,以及所有承租者的碎片数据库共享模式。一种经济高效的策略是,为所有承租者采用一种共享数据库和共享模式策略。采用这种方法会对数据库伸缩带来重大挑战,因为数据库在 SaaS 应用程序支持的所有承租者之间共享。一种简单的方法是基于承租者 ID、通过数据库分片横向扩展共享数据库。
数据库分片 是指对数据库进行水平分区,其中每个分区称为一个碎片。有一些开源以及专用软件,比如 Hibernate Shards、Apache Slice、SQLAlchemy ORM 和 dbShards,可提供分片功能。本文将 Hibernate 作为 J2EE 空间中最常用的 ORM 框架。我们将使用 Hibernate Shards(Hibernate 的一个扩展)解决 SaaS 应用程序的数据库扩展问题,并向 Hibernate 用户提供分片的功能。
SaaS 应用程序的数据库分片
SaaS 应用程序采用一种共享数据库,共享模式的方法,其设计考虑因素在于,当它不能再满足基本性能指标时就需要予以伸缩 — 例如,当太多用户尝试同时访问数据库时,或数据库的大小会导致查询和更新的执行时间太长。横向扩展共享数据库的一种方式是数据库分片。这是横向扩展数据库最有效的方式,因为根据承租者 ID,一个共享模式中的行对于不同承租者是不同的。可以基于承租者 ID 轻松地对数据库进行水平分区。从而便于将属于每个承租者的数据移动到单个分区。
在对多租户 SaaS 应用程序进行数据分区时,我们需要考虑这样的因素,比如因并发用户数量的增多而导致性能降低,或因多个承租者的配置而增加数据库大小,从而影响现有数据库的性能特征。这将有助于您根据单个承租者的数据库大小需求或同时访问数据库的单个承租者的用户数来选择合适的分区技术。数据库分片提供许多优势,比如对数据库的更快读写、改进的搜索响应、更小的表格尺寸以及对表格的按需分配。
Hibernate 数据库分片可用于构建采用其他多租户数据架构选项的 SaaS 应用程序,比如每个承租者的专用数据库,或每个承租者的共享数据库独立模式。Hibernate 数据库分片可以基于承租环境将连接到多个数据库的应用程序代码抽取出来,方法就是提供元数据配置并进行 API 分区,即根据承租环境处理插入数据的操作和从多个数据库中读取数据的操作。
使用 Hibernate Shards 实现分区
Hibernate Shards 是一个旨在通过向 Hibernate Core 添加水平分区支持来封装和最小化这种复杂性的框架。它最小化处理碎片数据的实现复杂性。Hibernate Shards 的主要目标是让应用程序使用标准 Hibernate Core API 查询和办理共享数据集。该方法具有以下优势:
提供非侵入性解决方案来支持数据库分片,同时使用 Hibernate 构建现有 SaaS 应用程序。
允许使用 Hibernate、但尚不需要分片的 SaaS 应用程序采用解决方案,而无需重大重构,前提是它们确实达到了这个阶段。
Hibernate Shards 提供:
Hibernate Core 提供碎片感知的界面扩展,因此代码不需要知道它是在与一个分片数据集交互。充当分片引擎的碎片感知扩展如下所示:
org.hibernate.shards.ShardedSessionFactory
org.hibernate.shards.criteria.ShardedCriteria
org.hibernate.shards.session.ShardedSession
org.hibernate.shards.query.ShardedQuery
实现特定于应用程序的分片策略的界面。上面描述的分片引擎使用应用程序提供的分片策略。
org.hibernate.shards.strategy.access.ShardAccessStrategy — 通过该策略,Hibernate 决定如何跨多个碎片应用数据库操作。每执行一次查询,都会引用该策略。两个默认实现 SequentialShardAccessStrategy 和 ParallelShardAccessStrategy 已经提供。
org.hibernate.shards.strategy.resolution.ShardResolutionStrategy — 该策略用于决定给定 ID 的对象所在的碎片集。碎片解析与 ID 生成相联,Hibernate 为 ID 生成提供多种策略,比如本地、应用程序级 UUID 生成和分布式 hilo 生成。
org.hibernate.shards.strategy.selection.ShardSelectionStrategy — 该策略允许我们决定创建新对象所在的碎片。基于应用程序的需求,我们决定该界面的实现。尽管 Hibernate 最初提供一个开箱即用的循环实现,我们需要为基于 SaaS 的应用程序提供基于承租者 ID 的实现。