主要结论
- FaunaDB 的主要功能包括:无服务器、对象关系型、图形(Graph)、全球复制、ACID、时间(Temporal)、支持联接(Join)、外键、企业安全性等。
- 事务中可进行数据库查询操作,并可由无服务器函数或客户端在边缘位置直接提交。
- 对象级访问控制帮助开发者省略设置身份验证上下文的任务,并可使用纵深防御技术增强安全性。
- 本文对比了 DynamoDB 和 FaunaDB,展示了如何将数据从前者移植至后者。
今年春季,Fauna 发布了 FaunaDB 无服务器云(Serverless Cloud):首个专为无服务器应用程序设计的数据库。与传统的云端数据库即服务产品不同,该产品提供的基本功能可以帮助开发者安全地构建并运行无服务器应用程序,而无须配置或运维基础架构。
Fauna 最初于四年前开始开发 FaunaDB,远远早于“无服务器”架构的诞生。在体会到管理服务器和数据库基础架构的痛苦后,Fauna 团队决定解决这个问题。他们开发的这个数据库为无服务器应用程序提供了完美支持,这其实是一个趋同进化的问题。诞生于 2016 年的无服务器技术作为一种应用程序架构进一证实了 Fauna 所采取方法的有效性。
FaunaDB 无服务器云是 FaunaDB 的托管版本,而 FaunaDB 是首个可自适应的运维数据库。FaunaDB 是一种对象关系型、全球复制、强一致的时间数据库。该产品在多个方面进行了适当的取舍,以一种 NoSQL 的方式对 JSON 提供了良好支持,但同时也支持联接、外键、唯一索引,以及其他必要关键功能,但并不像 SQL 那么复杂或不安全。该产品还可原生支持分布式图形和图形函数,尤其适合存储包含数十亿节点和边缘,高度聚集的图形,实现其他系统无法实现的工作负载。所有功能均具备 ACID 一致性和企业级安全性,因此该产品适合极为广泛的用例,从社交网络映射到将变更引入应用,再到实现需要分类账和全球分布的重要金融应用,均可得到妥善支持。
无服务器
无服务器架构正在对需要通过现代化开发实践协调数据库基础架构的开发者展现出越来越强的吸引力。虽然很多人依然在忙于将应用程序解耦成微服务,并逐渐迎合持续交付等趋势和原则,但数据库依然固守在单体(Monolithic)应用的模式,而应用程序栈的其他层已经变得更简单、更便宜、更易用。逆流而上的数据库基础架构依然昂贵、脆弱、难以运维。随着应用程序开发工作变得更加高效,数据库方面遭遇的痛点也愈加严重。
对很多人来说,无服务器数据库这一概念与无服务器这一原则是背道而驰的。无服务器架构被称之为“函数即服务”(FaaS),即事件驱动的架构。开发者只需要简单地编写函数并将其部署至基础架构即可。基础架构会在函数被调用时开始执行。其余时间里,函数处于休眠状态,不耗费任何资源。如果将这一特性应用于无服务器数据库,似乎会产生一种悖论:无服务器函数是暂存的,而按照定义,数据层应该是持久的。
最大的问题在于,目前现有数据库主要是面向传统应用程序构建的,需要在一个地理位置通过一系列固定的服务器持续运行。为了恰当地使用这些数据库,应用程序开发者需要知道大量有关数据库配置的信息。在最糟糕的情况下,高可用和性能完全取决于开发者对数据库内部机制的了解。开发者需要了解并配置诸如区域、地域、数据量、内存、软件版本、CPU 等信息。团队需要花费大量时间考虑容量规划、配置、切片、备份、性能调优、监视等问题。当你 80% 的时间用于配置和运维数据库,仅仅是为了向无服务器函数提供支持时,你会发现一定有什么东西被忽略了。虽然 AWS Lambda 和无服务器架构提高了计算层弹性,但如果你需要存储数据,持久存储层并不能从这样的弹性中获益。
逃离配置工作中的陷阱
FaunaDB 无服务器云通过下列方式解决了这些问题:
- 无需配置
- 真正弹性伸缩(无需运维介入)
- 按用量付费的“微记账”
在使用 FaunaDB 无服务器云构建和运行应用时,开发者无需了解有关基础架构的任何细节,例如节点规模、内存,或存储。AWS Lambda 正是通过同样的方式提出了按照每一个函数的调用进行收费的举措,FaunaDB 无服务器云的消耗则是通过“Fauna 点数”的方式衡量的。Fauna 点数是对不同工作负载所消耗计算和存储资源进行的量化体现,而这也正是无服务器数据库的精髓:用户绝对不会为闲置的容量付费。数据库用量主要可通过函数的调用和工作负载来体现,仅此而已。
对于标准化 DBaaS 产品,只能通过超量配置的方式应对流量激增。FaunaDB 按用量付费的定价方式可防止浪费的超量配置,因为 FaunaDB 可在无需用户介入的情况下进行弹性伸缩,开发者可随时使用而无需预先规划容量。应用程序总是能获得足够的容量,不会因为限制容量无谓地产生成本。FaunaDB 的使用成本可以随着用量一起伸缩,用户永远无需为未使用的容量付费。
与无服务器数据库的交互
FaunaDB 提供了极具表现力的查询语言,非常适合无服务器环境。无需学习新语法,用户即可将 FaunaDB 查询写入自己使用的任何语言中。
下文列举了一个使用 Javascript 的 FaunaDB 查询范例。在这个查询中,我们首先检索用户,随后返回了用户全名组成的字符串:
var faunadb = require('faunadb'), q = faunadb.query;
q.Let( { user: q.Get(q.Ref(q.Class("users"), "279364341312414")) }, q.Concat( [ q.Select(["data", "first_name"], q.Var("user")), q.Select(["data", "last_name"], q.Var("user")) ], " " ) )
其他语言中的表达同样简单。Fauna 提供了适用于 Android、Swift、JavaScript、Ruby、Java、Scala、C#、Python,以及 Go 的驱动。
FaunaDB 查询语言的完整文档请参阅这里。
大部分NoSQL 查询语言通常只能针对数据提供CRUD 操作,因此往往很难在SQL 中编写复杂的业务规则。但FaunaDB 的查询语言更类似于常规用途的通用编程语言。我们可以用熟悉的功能以直观的方式编写应用程序逻辑,例如if 语句、变量赋值,以及Map、Foreach、Filter 等丰富的函数化编程工具。此外由于FaunaDB 查询是自动事务型的,用户永远无需担心代码在查询过程中崩溃导致数据处于不完整(Half-written)状态。
下文列举了一个功能更强大的例子,可以按照地区显示伍德赛德市(Woodside)犯罪追踪报告中的变化情况,但会排除调用者自身所在的地区。该范例展示了图形查询、多级联接、索引,以及时间等特性,所有这些特性可用在一个查询中。
q.Map( q.Paginate( q.Join( q.Intersect( q.Join( q.Difference( q.Match(q.Index("districts_by_city"), "Woodside"), q.Ref("classes/districts/1")), q.Index("users_by_district")), q.Match(q.Index("users_by_group"), "Crime Watch")), q.Index("reports_by_user")), { events: true, after: q.Date("2017-1-1") } ), function(event), { return q.Get(q.Select("ref", event)) } )
无服务器安全模型
FaunaDB 一个最重要的独有特性在于其无服务器安全模型。FaunaDB 固有的安全性意味着用户无需通过中间件执行任何身份验证或授权检查。这样开发者就不需要编写多余,并且非常易于出错的样板功能(Bilerplate function),例如用于设置身份验证上下文或管理应用一致性的代码。举例来说,用户的无服务器 FaunaDB 数据库可以知道谁撰写了某篇博客文章,随后限制其他用户只具备读取的权限。
下列查询可创建一篇博客文章。所有人均可读取该文章,但我们希望只有作者可以编辑。为此可做如下设置:
q.Create(q.Class("posts"), { data: { text: "..." }, permissions: { read: "public", write: q.Ref(q.Class("users"), 123) } })
用户向 FaunaDB 发起的后续请求可以假定用户身份,FaunaDB 会强制实施事先配置的权限:只有本文作者可以修改,所有其他人只能读取。Lambda 本身无需了解具体所有权,自然也不会产生安全漏洞。由于业务规则已建模在数据库中,因此系统面对可能导致对数据进行未经授权访问的 Bug 可获得额外的保护。这种方式更简单也更安全,同时大幅减轻了无服务器应用的负担。最棒的地方在于,如果使用 API 网关,网关可以将用户的数据库访问令牌传递给 Lambda 函数,这样函数即可透明地以用户身份与 FaunaDB 交互。
Serverless 框架
如果打算在诸如 AWS Lambda 这样的云平台上运行函数,此时可以使用 Serverless 框架。Serverless 框架已成为市场主流,提供了一种简洁的系统,可以帮助我们配置、编写、部署无服务器应用程序代码到不同的云基础架构。
下文的范例展示了将无服务器架构的存储从 DynamoDB 移植到 FaunaDB 的过程。借此可直观对比 FaunaDB 与 DynamoDB 查询,同时还可以看出设置使用 FaunaDB 作为持久层的无服务器环境,整个过程到底有多简单。
该应用是一个简单的 REST API,可创建、更新、删除“todo”项。此外还可列出所有“todo”的次数。所有代码和相关说明已发布至 GitHub 。
Serverless 框架提供了一种格式化的 serverless.yml,该文件定义了服务,并将函数链接至事件处理程序。
readAll 的函数定义如下:
functions: readAll: handler: handler.readAll events: - http: path: todos method: get cors: true
该配置意味着 handler.js 中的 readAll 函数会在 todos 路径收到 HTTP GET 后调用,该函数会链接至 handler.js。
module.exports.readAll = (event, context, callback) => { todosReadAll(event, (error, result) => { const response = { statusCode: 200, headers: { "Access-Control-Allow-Origin" : "*" }, body: JSON.stringify(result), }; context.succeed(response); }); };
Handler.js 中的所有内容只需考虑 HTTP 的管理,因此每个函数的实际逻辑可从模块中导入。本例中的模块是 todos-read-all.js。这正是 FaunaDB 的用途所在。
'use strict'; const faunadb = require('faunadb'); const q = faunadb.query; const client = new faunadb.Client({ secret: process.env.FAUNADB_SECRET }); module.exports = (event, callback) => { return client.query(q.Paginate(q.Match(q.Ref("indexes/all_todos")))) .then((response) => { callback(false, response); }).catch((error) => { callback(error) }) };
通过这样的配置,我们便可以轻松地使用通过 serverless.yml 配置传递的 FaunaDB 秘密(Secret),为所有 todo 项运行查询。这个例子远比完整的对象级访问控制所能实现的功能简单。若要进一步了解 FaunaDB 的访问控制,可参阅 Chris Anderson 在 Serverless.com 发表的,有关身份验证和授权的博客文章。FaunaDB 查询会使用 HTTP,因此无需担心要在不同模块或调用之间共享连接。
DynamoDB 和 FaunaDB 版本之间的主要差异在于,下列语句:
return dynamoDb.scan({TableName: 'todos'}, (error, data) => { … })
变成了:
return client.query(q.Paginate(q.Match(q.Ref("indexes/all_todos"))))
## 结论:FaunaDB 何以如此与众不同?
FaunaDB 无服务器云是唯一针对无服务器应用设计的数据库。该数据库只需要最少量时间进行设置,不会造成费用负担。对于企业来说,无服务器架构可以帮您随时对业务进行伸缩,同时可真正降低成本。相比其他数据库,该技术的配置步骤少,无需运维介入,管理负担更轻。独特的定价方式意味着您的基础架构成本只取决于实际的资源消耗情况。
尽管无服务器架构是一种新概念,但 FaunaDB 技术本身已经获得了证实。该技术的开发完全围绕现实世界中的运维工作负载,很多客户已经在生产环境中运行该技术超过一年的时间。目前全球有上千万用户正在使用,这也意味着您可以放心地通过无服务器数据库构建您的无服务器应用。
在这里注册免费试用,您将免费获得1,000,000 个Fauna 点数。
关于本文作者
Matt Freels是 Fauna 的 CTO 兼共同创始人。Matt 曾担任 Twitter 数据库团队的技术主管,在 Twitter 任职时,Matt 曾与同是 Fauna 共同创始人的 Evan Weaver 合作负责面对爆发性增长过程中服务的伸缩工作。在加入 Twitter 之前,Matt 曾帮助社交游戏公司 Serious Business 处理伸缩问题,该公司的伸缩规模一度甚至超过了 Twitter。Matt 主要关注设计编程语言和分布式系统的构建,他住在伯克利,喜欢演奏贝司和攀岩。
作者: Matt Freels ,阅读英文原文: Introducing FaunaDB Serverless Cloud
评论