Force.com的多租户架构 salesforce
摘要: Force.com是如今正在使用的优秀的按需应用程序开发平台,支持47000 +个组织。个别企业和商业软件即服务(SaaS)供应商相信该平台可以提供强大、可靠和网络规模的应用。为了满足其庞大的用户人口要求,Force.com以元数据驱动的软件架构为基础,构建多租户应用。本文阐述了这项专利技术,它使Force.com平台对于任何类型的应用来说都是快速的、可扩展的和安全的。
引言
历史表明,每一个如此频繁和增量的技术上的进步,以及商业模式的变化,造就了软件应用方式的重大转变,包括应用程序的设计、建造,并交付最终用户。个人电脑、计算机网络和图形用户界面(UI)的发明,产生了客户端/服务器应用程序,而不再是昂贵、缺乏弹性的字符模式大型机应用。而今天,可靠的宽带因特网接入、面向服务的架构(SOA)以及管理专用交付应用程序的高成本和低效率,驱使向一种可分解、可管理的、共享的、基于Web的所谓软件即服务(SaaS)的服务交付模式的转变。
每一个模式转变都会带来一套新技术的挑战,SaaS也不例外。然而,现有的应用程序框架并不是旨在解决的特殊需要SaaS的。这一空白,造成了另一个新的范式转变——平台即服务(PaaS)。托管的应用软件平台在专门设计的环境中被管理,以满足构建SaaS应用的独特挑战,并以更符合成本效率的方式交付这些应用。
本文的重点是多租户,一个能大大有助于改善管理SaaS应用的基本设计方法。本文定义了多租户,解释了多租户的好处,并演示了为什么元数据驱动架构是实施多租户的首要选择。经过这些一般性的介绍,接下来本文大部分解释了世界一流的PaaS——Force.com的技术设计,它为互联网规模的应用提供了可交付使用的多租户应用。该文详细阐述了Force.com的专利元数据驱动的体系结构组件,提供了对其特性的理解,这些特性用于提供可靠、安全、可扩展的多租户应用。
1. 多租户应用
为了降低成本,向许多不同的用户组提供相同的应用,越来越多的应用是多租户的,而不是单一租户的。传统的单一租户应用只是为了满足一个组织的需要,要求一套专门设置的资源,而一个多租户应用程序能通过使用硬件资源和人员管理单一的软件实例,来满足多个租户(公司或部门内等)的需求,如(图1)。
图1:多租户应用成本高效地共享单一堆栈的资源,以满足多组织需求。
租户们使用多租户服务,相互之间实现虚拟隔离:组织可以使用和自定义一个应用程序,就像它们各自拥有一个单独的实例一样,而他们的数据和自定义相对于所有其他租户的活动来说保持安全和绝缘。这个对于任何特定的租户来说的单一应用实例,可以在任何特定时间运行时发生变体。
多租户是一种架构方法,它同时给应用软件供应商和用户带来益处。多个组织操作一个应用程序实例为供应商带来了巨大的经济效益。只要一组硬件资源就可以满足所有用户,只需相对较少的、有经验的管理人员就可以高效管理一个软硬件堆栈,开发人员只需在一个平台(操作系统,数据库等)上构建和支持单一的代码库。反过来,多租户带来的经济性也使应用程序供应商付出较低的成本为客户提供服务。每个参与者均受益。
多租户的附带好处包括提高了质量、用户满意度和客户忠诚度。不同于单一租户应用程序,应用软件提供商提供超出已有范围之外的孤岛部署,而多租户应用程序则是一个由供应商自行主办的大社区。这种设计转变使得供应商可以从集体用户群(他们的查询响应速度很慢,也会发生错误等)收集业务信息,并频繁、增量式地改善服务,以利于整个用户社区。
基于多租户平台的两个额外的好处是协作和集成。因为所有用户运行在一个空间,很容易让不同应用的用户访问的特定的数据集。此功能大大简化了整合相关应用和他们的数据管理所必需的努力。
2. 原始的云计算和PaaS的比较
原始的计算云是以机器为中心的服务,提供按需的基础设施作为服务(IaaS)的应用部署。这种云提供了比应用虚拟服务器还多的计算能力和存储容量。有些期待快速走向市场战略的SaaS厂商们,为了避免了真正多租户解决方案的挑战,选择通过IaaS发布单租户实例。
而像Force.com的平台即服务(PaaS),是一个以应用为中心的方法,它将服务器的概念抽象在一起。PaaS让开发人员从一开始到应用部署的整个开发过程都只专注于核心应用。提供者从来不需要担心多租户、高可用性、负载平衡、可扩展性、系统备份、操作系统补丁和安全,以及其他类似的与基础设施有关的问题,所有这些服务都是在PaaS中作为 “S” 交付的。
3. 元数据驱动的体系结构
多租户仅当它能够支持可靠的、可定制、可升级、安全快速的应用程序的时候才是现实的。但如何才能让一个多租户应用允许每个租户建立扩展标准的自定义数据对象,并定制全新的数据对象?如何保证租户的具体数据在共享数据库中的安全性,使得一个租户无法看到另一租户的数据?怎样才能使租户实时自定义应用程序的接口和业务逻辑,而不影响其他所有租户应用的功能和可用性?如何才能应用程序代码基的修补或升级不破坏特定的租户的定制应用?以及随着数以万计的租户订阅服务,应用的响应时间怎样实现可扩展?
建立一个应用程序的静态编译的可执行文件,并能够满足这些多租户及其他独特的挑战是很困难的。本质上说,一个多租户的应用,必须在其性质,或多态性方面,达到不同租户和他们的用户的个人期望。
基于这些原因,多租户应用设计已经发展到使用运行时引擎从元数据(即关于应用程序本身的数据)生成应用程序组件的阶段。在一个定义良好的元数据驱动的体系结构中(图2),已编译的运行时引擎(内核)、应用数据、描述一个应用程序的基础功能的元数据,以及与每个租户的数据和定制相关的元数据之间有一个明确的分离。这些明显的边界使人们有可能独立更新系统内核,修改的核心应用程序,或定制租户的具体组成部分,虚拟意义上来说,几乎不会影响其他人。
图2:一个元数据驱动的应用程序明确地分离了运行时引擎、数据、
常见的应用元数据和租户的特定元数据。
4. 新挑战和解决方案
试图编织多租户整体的应用程序的核心逻辑及其底层的基础设施是一件复杂的事情。毫无任何经验地从头构建一个元数据驱动的多租户应用注定是一个耗时且容易出错的工作。最后,许多想成为SaaS提供商的人们争相建立多租户应用,并最终浪费了宝贵的本应花在核心应用功能和特性的创新上的时间。问题是,传统的应用程序发展框架和平台都没有能力处理现代互联网应用的特殊需要。因此,新类型平台正在兴起,以简化开发和多租户应用的部署。
Force.com是现今第一个最成熟的致力于一般目的、多租户、互联网应用的开发平台。本文的其余部分给出了Force.com技术设计的具体细节的解释,这样你就可以更好地了解其功能。
5. Force.com平台体系结构概述
Force.com的优化的元数据驱动架构提供了性能非凡的、可扩展的、按需定制的多租户应用(图3)。
图3:Force.com的元数据驱动的体系结构以最优的方式在运行时产生虚拟的应用程序组件。
在Force.com中,暴露给开发和应用程序用户的一切东西都内在地呈现为元数据。表格、报告、工作流、用户访问权限、租户特定的自定义和业务逻辑,甚至是基础数据表和索引的定义,所有这些都只是作为元数据在Force.com的通用数据字典(UDD)中被抽象和构建。例如,当一个开发人员建立一个新的自定义应用时,定义客户表,放置一个表单,或写一些程序代码,Force.com并不会在数据库中创建一个“实际”的表或编译任何代码。相反,Force.com只是简单地存储元数据,该平台的引擎可使用这些元数据在运行时生成“虚拟”的应用程序组件。当有人想修改或定制一些有关应用程序,所需要做的只是对相应元数据简单的无阻塞更新。
由于元数据是影响Force.com应用的关键成分,该平台的运行时引擎必须优化元数据的访问,否则,频繁访问元数据将会阻碍平台的可扩展性。考虑到这个潜在的瓶颈,Force.com使用元数据缓存,以将最近最多使用的元数据保持在内存中,从而避免性能受到磁盘I / O和代码重新编译的影响,并提高应用程序的响应时间。
Force.com将少数大型数据库虚表中的所有应用数据作为堆存储。然后考虑相应的元数据,该平台的引擎在运行时物化虚拟表中的数据。为了优化系统大表的数据存取,Force.com的引擎上依赖一组专门的数据透视表,来维护各种用途的非规范化的数据,如索引,唯一性,关系,等等。
Force.com的数据处理引擎通过透明地进行批量数据修改操作,精简了大型数据的加载开销和在线事务处理应用。该引擎内置故障恢复机制,自动在分析出导致错误的因素后重试批量保存操作。
为了进一步提升应用程序的响应时间,该平台采用外部搜索服务优化全文索引和搜索。应用程序更新数据时,搜索服务的后台进程近实时地异步更新租户和用户的索引。应用程序引擎和搜索服务之间的职责分离使平台应用可以有效地处理事务,而没有文本索引的更新开销,同时也为用户迅速提供准确的搜索结果。
由于Force.com的运行时应用程序生成器,针对特定的用户请求动态地建立应用程序,所以引擎在很大程度上依赖其“多租户感知”的查询优化器尽可能有效地执行内部操作。查询优化器首先考虑哪些用户正在执行给定的应用功能,然后利用维护在UDD中的相关租户的特定元数据以及内部的系统透视表,建立并执行数据访问操作,以优化数据库查询。
现在你有了一个关于构成的Force.com底层机制的关键架构组件的总体思路,以下章节将更详细地解释其结构和各种内部系统元素的构建目的。
6. Force.com的数据定义和存储
Force.com的存储模型不是试图管理一个庞大的、不断变化的、代表每个应用程序和租户的实际数据库结构集,而是使用一组元数据、数据集和数据透视表来管理“虚拟”数据库结构,如图4所示。
图4:Force.com的数据定义和存储模式包括一组元数据,数据集,数据透视表,
允许对 “虚拟”表中的实际数据进行功能上的访问。
当组织创建自定义应用对象(即自定义表),UDD不断追踪关于对象、字段、关系和其他对象定义特征的元数据。与此同时,一些大型数据库表为所有虚拟表存储结构化和非结构化数据,还有一组相关的专用透视表来维护非规范化数据,使数据极其功能化。
图5是一个Force.com元数据和数据结构的简化实体关系(ER)图的三个核心:对象(Object),字段(Field)和数据表(Data Table)。
注 :为了简洁和清晰,Force.com的系统表和列的真实名字不一定在本文中出现。
6.1 对象元数据表(The Objects Metadata Table)
对象元数据表存储组织为其应用定义的自定义对象(又名表或实体)的信息,包括一个对象的唯一标识符(ObjID),拥有该对象的组织(OrgID),以及该对象的名称(ObjName)。
6.2 字段元数据表(The Fields Metadata Table)
字段元数据表存储组织自定义对象的自定义字段(又名列或属性),包括一个字段的唯一标识符(FieldID),拥有该对象的组织(OrgID),包含该字段的对象(ObjID),字段名称(FieldName),该字段的数据类型,表示如果该字段是否需要索引的Boolean值(IsIndexed)和在对象中相对于其他字段的位置(FieldNum)。
图5:Force.com使用对象和字段的元数据来定义应用对象和字段,
并映射为大型数据库表中存储的相应数据。
6.3 数据表(The Data Table)
数据表存储可供访问的应用程序数据,并通过对象和字段的元数据定义映射到自定义对象和字段。每一行包括一个标识字段如全局唯一标识符(GUID)、拥有该行的组织(OrgID)以及对象标识符(ObjID)。数据表中的每一行也有一个名称字段存储相应对象实例的“自然名”。例如,一个Account对象可以使用“Account Name”,一个Case对象可能会使用“Case Number”等等。这Value0 ...Value500列存储应用数据,这些列将对象和字段分别映射到在对象和字段表中声明过的对象和字段;所有“flex”列使用可变长度字符串数据类型,从而能够存储任何类型的应用程序数据(strings,numbers,dates等)。
自定义字段可以使用任何一种标准结构化数据类型,如text,number,date,和date/time以及特殊用途的结构化数据类型,如选择列表(枚举字段),自动编号(自动递增,系统生成的序列数),公式(只读的派生值),主从关系(外键),复选框(布尔),电子邮件,网址等。自定义字段也可能是必须的(不为空),或者包含自定义的验证规则(例如,一个字段的值必须比其他字段更大),两者都是通过该平台的应用服务器来实现的。
当一个组织声明或修改自定义应用程序的对象,Force.com管理对象元数据表中定义对象的一行。同样,对于每个自定义字段,Force.com管理字段表中的一行,包括将这个字段映射到数据表中的一个存储相应字段数据的flex列的元数据。因为Force.com将对象和字段定义作为元数据而不是实际的数据库结构来管理,所以平台可以容忍多租户应用模式的维护活动,而不阻碍其他租户和用户的并发活动。
同一个对象不会有两个字段映射到数据表中同一个的flex列(槽)存储;然而,一个flex列可以管理多个字段的信息,但每个字段来自于不同的对象。
图6:一个flex列可以存储来自不同对象的属性的数据,它们拥有不同的数据类型。
如图6所示的数据表的简化表示,flex列拥有一种通用数据类型(变长字符串类型),允许Force.com在多个字段间共享一个flex列,使用各种结构化的数据类型(strings,numbers,dates等)。
Force.com使用统一的格式存储所有flex列数据,而且当应用程序从flex列读取和写入数据时,必要时候使用底层数据库系统的数据类型转换函数(例如,TO_NUMBER,TO_DATE,TO_CHAR)。
虽然没有显示在图5中,但是数据表中还包含其他列。例如,有4个用于管理审计数据的列,包括何时和哪些用户创造了对象实例(行),以及何时和哪些用户最后更改了对象的实例。数据表还包含isDeleted字段来说明对象实例是否已被删除。
6.4 Clobs表(The Clobs Table)
Force.com支持将字段作为字符大对象(CLOBs)声明,以允许存储多达32,000个字符的长文本字段。对于每一个在数据表含有CLOB字段的行,Force.com会在一个称为Clobs的透视表中存储CLOB超行,系统可以必要时通过它与数据表中相应的行进行连接运算。
注:Force.com还将CLOBs以索引形式存储在数据库外部,以方便快速的文本搜索。
6.5 索引透视表(The Indexes Pivot Table)
传统的数据库系统依赖索引迅速定位数据库表中的字段满足特定匹配条件的行。但是,为数据表的flex列创建本地索引是不切合实际的,因为Force.com可能用一个flex列来存储很多字段的数据,且它们的数据结构类型各不相同。所以,Force.com通过同步复制有标记的字段来管理数据表的索引,这些标记字段数据被索引到一个称为Indexes的数据透视表中相应的列,如图7简化ER图的描述。
该Indexes表包含强类型的索引列,如StringValue,NumValue和DateValue,Force.com借此查找相应数据类型的字段数据。例如,Force.com将复制一个数据表中flex列的字符串值到Indexes表的stringValue的字段,将日期值复制到DateValue字段,等等。Indexes表的底层索引是标准的非唯一数据库索引。当包含一个查询参数内部系统查询引用了自定义对象中的一个结构化字段,该平台的查询优化器就使用索引表,以帮助优化相关的数据访问操作。
图7:Force.com使用数据透视表来索引存储在flex列的数据。
注 :Force.com可以处理多语言搜索,因为该平台的应用服务器使用大小写折叠算法将字符串值转换成一个普遍的、大小写不敏感的格式。Indexes表的StringValue列以这种格式存储字符串。在运行时,查询优化器自动生成数据访问操作,从而使得对于字面上给定的搜索请求,优化后的SQL语句可以做些相应大小写折叠后的StringValue的过滤。
6.6 唯一域的数据透视表(The UniqueFields Pivot Table)
Force.com允许组织指出何时一个对象中的字段必须包含唯一值(区分大小写或不区分大小写)。考虑到数据表值列上共享使用自定义的字段数据,为表创建唯一的数据库索引是不切实际的,这与前面部分讨论过的非唯一索引问题类似。
为了支持自定义字段的唯一性,Force.com使用称为UniqueFields的数据透视表来实现,这表与Indexes数据透视表非常相似,只不过UniqueFields数据透视表的底层数据库索引强制唯一性。当一个应用程序试图在需要唯一性的字段上插入重复值,或者管理员试图在包含重复值的已有字段上强制唯一性时,Force.com中转一个适当的错误消息给应用程序。
6.7 关系数据透视表(The Relationships Pivot Table)
Force.com提供了组织声明其应用对象间关系的“关系”数据类型(参照完整性)。当一个组织将对象的字段声明为关系类型时,平台将该字段映射到数据表中的一个值字段,然后使用该字段来存储相关对象ObjID。
为了优化连接操作,Force.com维护一个称为关系(Relationships)的数据透视表,如图8所示。
图8:关系表可帮助优化对象连接。
关系索引表(The Relationships Index table)有两个底层数据库的唯一联合索引,即OrgID +GUID,和OrgID + ObjID + RelationID + TargetObjID,从而保证必要时对象双向遍历的高效性。
6.8 FallbackIndex表(The FallbackIndex Table)
在极少数情况下,平台的外部搜索引擎可能超载或不可用,或可能无法及时响应搜索请求。用户提交一个查询请求后,该平台的用户服务器进入后备的二级搜索机制,返回合理的搜索结果,而不是返回一个令人失望的错误。
后备搜索是数据库查询的直接实现,它参照目标应用对象的名称字段进行搜索。为了不必执行潜在的昂贵的Union查询,实现优化搜索全局对象(跨对象搜索),Force.com维护一个称为FallbackIndex的数据透视表来记录所有对象的名称。当事务修改对象时,FallbackIndex同步更新,后备搜索总可以访问到最新的数据库信息。
6.9 NameDenorm表(The NameDenorm Table)
该表是一个精简的数据表,存储ObjID和数据表中每个对象实例的名称。当应用需要给出一个父子关系的对象实例的超链接列表时,Force.com使用NameDenorm表来执行一个相对简单的查询,检索每个引用对象的名称以得到超链接的列表。
6.10 历史跟踪表(History Tracking Table)
Force.com容易实现对任何字段的历史跟踪。当组织审计特定的字段,系统将使用一个用于审计跟踪的内部透视表异步记录该字段的变化信息(旧值,新值,改变的日期等)。
6.11 数据和元数据的分区
所有Force.com的数据、元数据和数据透视表结构,包括底层数据库索引,都是使用本地数据库的分区机制并按OrgID进行物理分区的。数据分割是一个成熟的技术,数据库系统将较大的逻辑数据结构物理上划分为更小、更易于管理的块。
分区还可以改善诸如多租户环境大型数据库系统的性能、可伸缩性和可用性。例如,每一个Force.com应用通过定义来查询一个特定的目标租户的资料,查询优化器只需要访问一个租户而不是整个表或索引的数据分区,这是一种常见的优化方法,有时也称为“partition pruning”。
7. 应用程序开发,逻辑,和处理
Force.com支持两种不同的方法创建和定制应用的个体组件:一是声明的方式,使用本机平台的应用框架,二是编程方式,使用应用程序编程接口(API)。以下部分解释一下每种方法及其相关的应用开发主题。
7.1 应用框架
开发人员可以使用“本地”Force.com应用程序框架,以声明的方式构建自定义的Force.com应用程序。该平台的原生的point-and-click界面支持应用开发过程的所有方面,包括应用数据模型的创建(自定义对象及它们的字段、关系等),安全和共享模式(用户、组织等级、资料等),用户界面(屏幕布局,数据录入表格,报告等),以及逻辑和工作流程。Force.com应用程序框架的用户接口很容易建立,因为不涉及编码工作。幕后,它们支持所有常见的数据访问操作,包括查询,插入,更新和删除。每个本地平台应用执行的数据操作一次修改一个对象,并在另一个单独的事务中自动提交每个改变。
Force.com的本机集成开发环境(IDE)提供了轻松访问许多内置平台功能的特性,使它易于实现通用应用的功能而不用写复杂且容易出错代码。这些特性包括声明性工作流,加密/隐藏字段,验证规则,公式字段,上卷汇总字段和跨对象验证规则。
工作流是一个预定义的行为,在插入或更新一个对象实例(行)时触发。工作流可以触发一个任务,电子邮件提示,更新一个数据字段,或发送消息。工作流规则规定了决定何时触发工作流行为的标准。工作流可以被设置为立即或在触发事件之后的间隔内执行。例如,开发人员可以声明一个工作流,记录更新后立即自动将该行的状态字段更新为“modified”,然后发送一个电子邮件提示。所有的工作流操作都在触发工作流的事务范围内发生。系统回滚事务时,所有相关工作流程也被回滚。
当定义对象的文本字段包含敏感数据时,开发人员可以很容易配置该字段,Force.com加密相应的数据并可以选择性地使用输入掩码来隐藏屏幕信息。Force.com加密字段使用AES(高级加密标准)算法的128位密钥。
声明验证规则是组织不通过编程方式强制域完整性规则的一种简单方式。如图9的第二个截屏展示了开发者是怎样使用简单的IDE表单来为LineItem对象添加一个字段,并计算出LineTotal的值。
一个上卷的汇总字段是一个跨对象的字段,使父对象中聚集子字段信息变得简单。如图9中的最后一个截屏,展示了如何使用IDE基于LineItem对象的LineTotal字段,在SalesOrder对象中创建一个OrderTotal汇总字段。
注: 从内部来看,Force.com使用原始数据库的功能实现了公式和上卷汇总字段,并在正在进行的事务中有效地同步重新计算它们的值。
图9:声明验证规则、公式字段和上卷汇总字段是简单的配置步骤而非复杂的编码任务。
7.2 元数据和Web服务API
Force.com还提供了卓越的API来构建应用程序。这些API与基于SOAP的发展环境相兼容,包括Visual Studio.NET(C#)和Apache Axis(Java和C + +)。
应用程序可以利用Force.com的API与其他环境集成。例如,应用程序可以利用API访问其他系统的数据,建立来自多个数据源的信息整合的mashups,包括作为应用过程一部分的外部系统,或者建立胖客户端与Force.com平台数据库管理系统进行交互。
Force.com 的元数据API对于管理应用程序组件是有益的,创建并修改元数据对应自定义对象的定义,页面布局,工作流等。应用程序可以使用Force.com Web服务的API来创建,检索,更新或删除对象实例(数据行)。
要访问Force.com Web服务,开发者先下载一个Web服务描述语言(WSDL)文件。然后这个开发平台使用WSDL文件生成一个API来访问组织相应的Force.com Web服务(数据模型)。有两种类型的Force.com的WSDL文件。企业WSDL文件是为构建组织特定的应用的开发者提供的。一个企业WSDL文件是一个强类型,它代表一个组织的数据模,并提供了有关组织模式、数据类型、字段、开发环境等信息,允许组织与Force.com Web服务之间更紧密的整合。如果自定义字段或自定义对象从一个组织的应用模式中被添加、重命名或删除,那么这个企业WSDL将发生变化。相比之下,合作伙伴WSDL文件是为开发服务于多个组织的客户端应用程序的salesforce.com合作伙伴提供的。合作伙伴WSDL在Force.com对象模型中表现为弱类型,并提供了一个用于任何组织内访问数据的API。
7.3 批量处理的API调用
对于事务密集型应用,将重复性操作联合起来批量执行,可以减少开销,且执行效果更好。例如,应用加载一个对象的多个实例可能采用两种不同的方式。一个低效率的办法是使用一个例程循环插入单个对象实例,一个插入操作一个API调用。另一种更有效办法是建立一个对象实例数组并在一个API调用中执行插入。
应用型的Force.com Web服务API调用如create(),update()和delete()均支持批量操作。为了获得最大的效率,一个明确的批量操作所有相关的内部步骤实际上平台都是批量执行的,如图10。
图10:Force.com的批处理引擎将批量操作本身相关的每个内部步骤都作为批量操作执行,
同时有利于继续曾经异常的行操作。
图10也显示了Force.com批处理引擎的独特机制,可以考虑任何步骤中遇到的隔离故障。当批量操作在部分保存模式下启动,引擎识别出已知的开始状态,然后尝试执行过程的每个步骤(批量验证字段数据,批量火灾预触发器,批量保存记录等)。如果引擎检测到过程中任何一步发生错误,则回退违规的操作及其副作用,删除故障相关的行,并试图继续批量处理其余的行子集。这一过程在每一阶段迭代,直到该引擎没有任何错误地提交了一个行子集。应用程序可以检查返回的对象,以确定哪些行操作失败了以及它们提出的抛出了何种异常。
注:在谨慎的应用中批量操作也可以全有或全无的模式进行。此外,批量操作过程中触发器的执行受到内部工作量限制的制约。
7.4 删除,恢复删除和回收站
当有人从一个自定义对象删除单个对象实例(即记录)时,Force.com通过修改该对象实例的isDeleted字段(在数据表中)简单地标记其删除,从而有效地将对象放入回收站。Force.com允许用户在数据被永久将删除之前从回收站中查看和恢复达30天的对象实例。该平台基于组织许可的用户总数限制一个组织需要维护的记录总数。
当有人删除包含主从关系的父记录时,Force.com在确保不触犯任何参照完整性规则的前提下自动删除所有相关的子记录。例如,当用户删除一个SalesOrder,Force.com自动级联删除依赖的LineItems。只要有人随后从回收站中恢复父记录,该平台将同时自动恢复其所有的孩子对象实例。
相反,当有人删除包含查找关系的引用父记录时,Force.com自动将所有相关项设置为空。如果有人随后恢复父记录,Force.com自动恢复以前清空的查找关系,但对那些被重新分配关系的删除和还原操作除外。
回收站还存储删除的字段及其数据,直到它们被永久删除或已删除超过45天。在此之前,整个字段及其所有的数据都是可以恢复。
7.5 数据定义处理
某些类型的对象定义修改需要更多而不仅仅是简单的UDD元数据的更新。在这种情况下,Force.com使用有效的机制减少多租户应用对平台整体性能的影响。
例如,考虑当有人将某一列的数据类型由picklist修改为text,幕后究竟发生了什么。Force.com首先为列数据分配一个新的slot,将值批量复制到标记为picklist的列上。然后更改列的元数据,使它指向一个新的slot。当这些发生的时候,数据访问仍然正常,应用程序功能上也没有什么明显的影响。
再看一个例子,考虑当有人向表中添加一个上卷汇总字段(roll-up summary field)。在这种情况下,Force.com在后台使用高效的批量操作异步计算初始的汇总值。当进行后台计算的时候,这时用户查看这个新增字段,会收到一个提示说Force.com平台正在计算该字段的值。
8. 内部查询优化
大多数现代数据库系统使用基于成本的查询优化器来决定最优的查询执行计划,考虑与目标表和索引数据相关的统计信息。然而,传统的基于成本的优化器的统计数据是为单一租户的应用而设计的,而多租户环境中为特定用户执行的查询给出数据访问特性时就失效了。例如,查询某一种对象的大量数据时,对可见度高的用户(如可以看见所有对象实例的经理)和可见度低的用户(如只能看见与自己相关的行数据的销售人员)采用不同的执行路径更加有效。
为了提供足够的统计信息以确定多租户平台中最佳的查询执行计划,Force.com为每个虚拟的多租户对象维护了一套完整的优化器统计信息(tenant/group/user级别)。慎重考虑了整体的tenant-specific对象统计信息,以及更加细粒度的统计信息(一个特定权限的group或者最终用户潜在可访问的行数,等等),从而统计信息反映了一个特定查询潜在可访问的行数。
Force.com还维护了有助于特定查询的其他类型的统计信息。例如,对所有自定义索引的统计信息揭示了相应字段非空和唯一值和总数,picklist字段的直方图表明每个list值的势(cardinality)。
当已有的统计信息不合适或者帮助不大时,Force.com的优化器使用一些不同的策略来创建合理的最优查询。例如,当一个查询在对象的名称字段上过滤时,优化器可以使用FallbackIndex数据透视表来高效地找到请求对象实例。其他场合优化器在运行时动态地生成缺失的统计信息。
按照串联使用顺序,Force.com的优化器还依赖于内部的与安全性相关的表(Groups,Members,GroupBlowout和CustomShare),它们维护用户域安全性相关的信息,包括对给定用户组的成员定制访问对象的权利。
图11:当数据请求发生时,Force.com执行预查询(pre-queries),
平台的查询优化器使用该结果建立和执行最佳的数据库查询
图11所示的流程图描述了Force.com拦截一个对大型堆表(如数据表)的数据请求时所发生的事情。这个请求可能来自于任意资源,如来自应用框架应用程序的页面请求,或web服务API调用,或Apex脚本。平台首先根据多租户敏感的统计数据进行预查询(pre-query),然后根据其返回结果创建一个特定背景下的最优数据库查询以供执行。
表 1: Force.com查询执行的四种方式
如表1所示,根据提交查询的用户和查询过滤条件的选择度不同,Force.com对于同一查询可以有四种不同的执行方式。
9. Force.com 全文搜索引擎
基于web应用的用户开始期待交互式的搜索能力,通过扫描整个应用数据或者选择的一部分数据,及时返回有序的结果,所有这些将在次秒级的响应时间内完成。为了向平台应用提供如此健壮的功能性,Force.com使用一种基于架构的外部搜索引擎,如图12所示。
应用的文本型字段,如CLOBs,Name等,更新数据时,一个称为indexing servers的后台进程池,负责异步更新相应的indexes表,搜索引擎在核心数据库之外维护这些indexes。为了优化indexing过程,Force.com同步地将修改过的文本数据块复制到内部的“即将”索引的表中然后进行事务提交,因而提供了一个相对较小的数据源,减少了indexing servers必须从磁盘读取的数据量。搜索引擎为每个组织(即租户)自动维护单独的索引。
由于indexing servers的现行负载和使用率,文本索引的更新可能显著性地落后于真实的事务。为了避免失效索引导致的不可预期的搜索结果,Force.com还维护了一个最近更改对象的MRU缓存,应用服务器将用它来物化全文搜索结果。平台按照每位用户和每个租户的原则维护这个MRU缓存,高效地支持可能的搜索范围。
图12: Force.com使用外部搜索引擎为多租户应用提供快速文本检索
Force.com使用多种不同的方法在搜索结果范围内优化记录排序。例如,系统根据执行查询的用户的安全域及当前用户可访问的对象权重比较来确定排序。另外,考虑特定对象的修改历史,将较经常更改的对象至于那些相对静态的对象之前。用户可以选择搜索结果的期望权值,如突出最近修改的对象等。
10. Apex
Apex是一个强类型、面向对象的过程型编程语言,开发者可以声明程序变量和常量,执行传统的流控制语句(if-else,loops等),数据管理操作(insert,update,upsert,delete),以及事务控制操作(setSavepoint,rollback)。Apex在很多方面类似于Java 。开发者可以创建一个Apex例程,以向大部分应用事件添加自定义业务逻辑,包括按钮点击,数据更新,web服务请求,自定义批服务及其他。
开发者可以以两种形式建立Apex程序:一是需要时执行的单独匿名脚本,二是在特定数据库管理事件(insert,update,delete,undelete)发生之前或之后自动执行的触发器。无论哪种形式,Force.com都 将编译Apex代码并将其作为元数据存储在UDD中。当一个Apex例程在一个组织中第一次被调用,Force.com的运行时解释器就装载这个编译过的程序版本到该组织的MRU缓存。之后当同一组织的任何用户使用相同例程时,由于共享了一个已经存在于内存中的ready-to-run的程序,Force.com就节省了内存,且避免了重新编译程序的开销。
Apex远不止是另一种过程型语言。Apex是一个使得平台发布可靠的多租户应用的完整的Force.com组件。例如,Force.com通过Apex类自动验证所有内嵌Sforce Object Query Language(SOQL)和Sforce Object Search Language(SOSL)的语句,防止代码运行时失败。然后维护有效的Apex类相应的对象依赖性,并使用这一信息防止元数据的改变,这一改变会破坏相互依赖的应用。
许多Apex标准类和系统静态方法提供了底层平台特性的简单接口。例如,系统的静态DML方法如插入、修改和删除都有一个简单的布尔型参数,开发者用它来指示期望的批处理操作选项(all,nothing,partial save);这些方法也会返回一个调用例程的结果对象,该对象用于决定处理是否成功及失败原因。Apex和Force.com平台特性之间联系的其他直接的例子,简单列举下,如内嵌的Apex email类,HTTP(RESTful)服务类和XmlStream类等。
为了避免恶意或者非故意的共享的多租户平台资源的独占性,Force.com有一组可扩展的于Apex代码执行相关的管制和资源限制。例如,Force.com密切监控Apex脚本的执行,限制CPU时间和内存消耗,DML语句执行的查询数目,进行数学计算的数目,以及可能的web服务调用上限,等等。平台优化器认为单个查询执行时向调用者抛出一个运行时异常是相当高代价的。尽管这种限制可能听起来有点约束性,可是保护所有相关应用的共享平台的整体的扩展性和性能是非常必要的。从长远来看,这些指标有助于提升平台开发者更好的编码技能,并为每个人创建一个更好的用户体验。例如,一个开发者最初试图编写一个不太高效地一次一行地更新一千行数据的循环,由于资源限制得到一个运行时异常,并且开始使用Force.com的高效地批处理API调用。
为了进一步避免编写不良的应用程序导致的潜在的平台问题,新产品应用的部署是一个需要严格管理的过程。在一个组织新自定义的应用从开发阶段转化到产品阶段之前,Salesforce.com需要单元测试来验证应用的Apex例程的功能性。已提交的单元测试必须覆盖不少于75%的应用程序源代码。Salesforce.com在Force.com的沙箱环境中执行已提交的单元测试,以确保应用程序大体上不会对多租户的性能和扩展性造成不利影响。单个单元测试的结果暗示了一些基本信息,如执行的代码行数和测试中未被执行的代码的特定信息等。
一旦一个应用程序由Salesforce.com确定为产品,应用的开发过程便由一个单一的事务组成,这个事务将所有应用的元数据复制到一个Force.com产品实例,并返回一个相应的单元测试。如果这个过程中任何一部分失败了,Force.com则简单地回滚事务,并返回一个异常来帮助追踪问题所在。
注:Salesforce.com发布每个平台开发应用程序并返回单元测试,从而积极了解新平台的特性和增强功能是否破坏了现有的应用程序。
当有了一个产品应用程序以后,Force.com内嵌的性能分析器会自动分析并性管理者提供相关的反馈。性能分析报表包括慢查询、数据管理的信息,以及开发者可复审并用来优化应用程序功能的子例程。平台还使用了日志返回运行时异常的信息,有助于管理者调试它们的应用程序。
11. 历史统计数据
多年的经验使得Force.com已经转变成一个非常快速的、可扩展的、可靠地多租户互联网应用程序平台。图3展示了Force.com用于支持互联网规模应用的已经证明了的能力。需要特别注意的是,随着时间的推移,平均页面响应时间减少,或者当平均并发事务量增长(扩展性度量)时保持稳定(性能上度量)。
图13: 随着Force.com日渐成熟,每年平台的性能和扩展性都持续提高
对于更多的平台数据,如计划维护,事务量的历史信息,速度,等等,会访问trust.salesforce.com,它是Force.com社区主页上关于系统性能和安全性的实时信息。
12. 结论
平台即服务(PaaS的)和软件即服务(SaaS)都是当代应用软件开发和交付模式,越来越多的组织正在使用它们,改善其上市时间,减少资本开支,并在具有挑战性的全球经济中提高整体竞争力。基于因特网的共享的计算平台极具吸引力,因为它们让企业快速、按需地访问托管的、已管理的软件资产,同时完全避免了购买、安装、配置以及持续维护内部部署的数据中心和专用软硬件和相关的管理工作人员的复杂性与成本。
这种按需SaaS / PaaS的范式转变最成功的前沿公司就是salesforce.com,最近作为第一个按需软件厂商被加入S&P 500索引。走出salesforce.com的CRM SaaS应用程序的巨大成功,Force.com是一个广义互联网应用开发和交付平台,个别企业和服务供应商建立所有类型的自定义业务应用,包括供应链管理,计费,会计,规格跟踪,人力资源管理,及索赔处理的申请。该平台的元数据驱动架构使任何人都能够有效地建立和发布精细的、可定制的、关键的、互联网规模的多租户应用。使用基于标准的Web服务API和本地平台的开发工具,Force.com开发人员可以轻松建立基于Web的应用所有组件,包括应用程序的数据模型(表,关系等等),用户接口(数据输入表单,报表等),业务逻辑(工作流程,验证等),与其他应用程序的集成等。
过去的10年里,salesforce.com的工程师们已经为多租户优化了Force.com平台的所有层,让平台发布者前所未有地扩展其应用,达每天170万个事务。诸如大容量数据处理API,Apex编程语言,外部的全文搜索引擎,及其独特的查询优化器等功能,使多租户平台的应用变得高效率和可扩展性,而很少甚至没有考虑开发人员。
Salesforce.com对生产应用程序的部署的管理,保证了所有相关的应用程序一流的性能、可扩展性和可靠性。此外,salesforce.com不断监测和收集来自Force.com应用的业务信息,促进增量改进和立即有利于现有的和新应用的平台功能。