这段“对话”显然有诙谐的成分,但也映射出一个无法逃脱的现实——一个数据库包打天下的时代过去了。俗话说,“工欲善其事,必先利其器”,那么,我们到底需要怎样的数据架构?又该如何选择数据库?在亚马逊云科技首期 Build On《现代化数据架构思考与实践 -NoSQL 的前世今生解读及架构搭建》中,数据库产品专家吕琳、李君针对现代化数据架构这一话题展开分享并带领大家现场完成了非关系型数据库相关的两个动手实验。
在数据库技术的发展史上,1970 年是个巨大的转折点,这一年,埃德加·科德发表了《大型共享数据库数据的关系模型》一文。由此,关系型数据库一直占据着数据库生态圈的顶尖地位。科德本人也凭借这项成就获得了图灵奖。值得一体的是,仅关系型数据库这一个门类就前后诞生了四个图灵奖得主。
随着现代化应用的发展,开发者对性能、规模和可用性的要求更高。用户量动辄百万以上,数据量从 TB 增长至 PB,性能要求达到毫秒甚至微妙级别的延迟...... 与此同时开发者希望免去繁重、重复的运维和部署工作,将更多的精力投入到开发业务中去。单一数据库的模式已无法满足企业的需求。
2004 年,亚马逊电商发生过一次很严重的故障,致使用户连续几个小时无法完成交易。当时,亚马逊电商采用的是 Oracle 关系型数据库,但由于关系型数据库天然地在面对海量数据的高效率读写时,读写性性能较差,因此,尽管拥有上万套 Oracle 数据库,并对数据进行了分库分表处理,在业务量剧增的情况下,系统还是崩溃了。这时的亚马逊已然遇到了关系型数据库的扩展瓶颈。
在那次重大的事故后,亚马逊开始重新考量、构建自己的应用,并重新选择数据库。其实,当时作为 Oracle 全球最大的客户之一,亚马逊享受到的 license 折扣是极低的,但是,面向未来的爆炸式发展需求,让他们意识到当前数据架构的不完善。在谨慎调研与设计之后,亚马逊决定不再采用单一数据库模式,而是将其进行拆分,同时采用 Amazon Redshift、Amazon DynamoDB、 Amazon Aurora、 PostgreSQL 等多种类型的数据库。这样的做法避免了仅采用关系型数据库产生的因数据集增大而带来的性能下降问题。在海量数据集下依旧可以保持高并发请求和持续低响应延迟,且几乎没有扩展上限。如今,亚马逊电商系统在类似双 11 活动规模的 Prime Day 上,每秒可能会应对超过 8000 万次的调用,如果仅采用关系型数据库,几乎是不可能实现的。
不仅仅是在亚马逊,互联网行业、金融行业的很多巨头公司,都已同时采用多种数据库。如为全球旅行者和房东提供出租 / 租用的服务型网站 Airbnb,在关系型数据库上选择 MySQL 和 RDS,在非关系型数据库上选择 DynamoDB,同时采用 Amazon ElastiCache、Redis 进行前端的数据缓存。金融行业公司 Capital One 大量使用非关系型数据库 DynamoDB,而需要数据分析时则会用到 Amazon Redshift。
每一款数据库都有其历史背景,是特定时间、技术条件之下面向指定场景需求的产物,各有所长的同时也各有局限性。因此,不同的业务类型、乃至同一业务链路下的不同场景特性可以按需拆分为不同的数据库需求。并且,随着微服务拆分地越来越细,数据库也天然得有了拆分的保障,越来越多企业更适合、也更愿意根据其需求场景来选择专用数据库。
所以,今天我们为大家带来的是现代化数据架构的第一个也是最重要的一个概念——“专门构建,专库专用”
要说最眼花缭乱的,莫过于数据库服务的“大家族”了。在不同的数据库间如何根据自己的应用场景进行选择,才能让每个场景都获得极致的性能、可用性和扩展性?吕琳在分享中介绍了不同类型专用数据库的应用场景。
他首先从开发者们最为熟悉的关系型数据库讲起。比较常用的关系型数据库有 PostgreSQL、MySQL、MariaDB、Oracle Database 、SQL Server 等,亚马逊云科技的 RDS 也同时提供五种常用数据库引擎。为什么还要自创了 Amazon Aurora,吕琳说:“这其实源自客户的需求。”
客户反馈,Oracle、SQL Server 功能强大,提供企业级支持,但它们有苛刻的 License 许可机制和严重的绑定倾向,且费用昂贵。反之,MySQL、PostgreSQL 这样的开源数据库,虽然免费,但又少了功能、性能、高可用性及企业级支持。
如何才能鱼与熊掌兼得?2014 年,亚马逊云科技推出首款专为云打造的关系型数据库 Amazon Aurora。Amazon Aurora 完全兼容 MySQL 和 PostgreSQL,性能可以达到标准的 MySQL 的五倍,标准的 PostgreSQL 的三倍,且可按照使用量付费。在性能方面 Amazon Aurora 是一个高可用的典型案例。
但作为一款关系型数据库,Amazon Aurora 依旧逃脱不了关系型数据库的设计问题,即随着数据量的增长,索引效能一定会有所下降。当面对海量数据,又要保证索引效能,企业通常会采用两种办法。
其一,是对关系型数据库进行分库分表。分库分表能够提升性能,增加可用性,然而,这样的方式也会为开发者带来很多麻烦。比如,事务问题怎么解决?跨分辨查询怎么办?如何让冷热数据均匀散落在各个分库分表内?这些都需要开发者花时间去考虑。
第二种方法,就不得不谈到非关系型数据库了。非关系型数据库存储格式灵活、速度快、扩展性高、且成本相对较低。在很多特定场景下,表现强劲,比如海量写入,精准读取,高并发更新,对一致性要求不高等场景。亚马逊云科技最典型的非关系型数据库是 DynamoDB,它的扩展几乎没有上限,且能够避免数据集增大导致性能下降,海量数据集下依然可以保持毫秒甚至微秒级的响应时间。不仅如此,DynamoDB 还采用了无服务器架构无需硬件配置、软件补丁或升级就可以自动化扩展或缩减、连续不间断地备份数据。
除常见的关系型数据库和非关系型数据库,还存在一些其他类型的数据库,如内存数据库,文档数据库、图数据库、时序数据库等,也都拥有各自适合的应用场景。吕琳一一为大家进行介绍。
内存数据库:如 Amazon ElastiCache 或者 Amazon MemoryDB 等。这类数据库可以保证数据不丢失,通常来说,Redis 的复制技术是异步复制,可能会丢失一部分数据,但采用内存数据库 Amazon MemoryDB 则不存在数据丢失的情况。
文档数据库:如 MongoDB、Amazon DocumentDB 等。MongoDB 在中国区的接受度很高,很适合直接存储 JSON 数据,因此,游戏、直播等行业会天然地倾向采用它。但 MongoDB 免费版很难做到高可用,而收费版费用又很高,相比来说,Amazon DocumentDB 提供更强大的高可用和可扩展能力。
图数据库:如 Amazon Neptune,图数据库属于比较新兴的数据库,主要用以记载不同事物间的相互关系。在社交网络、知识图谱、生命科学等场景比较常用,此外在欺诈检测、疫情防控的背后,图数据库也发挥了重要的作用。
时序数据库:如 Amazon Timestream,时序数据库主要用于处理带有时间标签的数据,主要运用于保险、电力、化工等行业,进行各类实时检测、监测与分析。 Amazon Timestream 提供快速、可扩展、完全托管的服务,与关系数据库相比速度快 1,000 倍,成本仅为 1/10。
所谓尺有所短,寸有所长。因此,各种各样的数据库,只有在自己适合的场景,才能够发挥最大的价值。
虽然数据库的种类繁多,但大体一般可分为两类,一类是传统的 SQL,另一类是比较新兴的 NoSQL。吕琳强调,这两种数据库并非互相替代的关系。如果需要大量 joins 或者灵活的即席查询,那么 SQL 一定是不二的选择。但是,如果需要海量扩展、低可预期的延迟和灵活的 schema,那么 NoSQL 才是更优的选择。
在非关系型数据库中,吕琳着重介绍了 DynamoDB 的基础及最佳实践,后续的动手实验也是围绕这款数据库展开。
2007 年,亚马逊 Dynamo 论文的发表,为后来一系列 NoSQL 理论与产品的发展提供了启发,铺平了理论的道路,很多 NoSQL 产品都参考了 Dynamo 系统。2012 年,DynamoDB 正式诞生。这是一款完全托管的无服务器类型的 NoSQL 数据库。用以解决数据库管理、性能、可扩展性和可靠性等核心问题。具有很高的可扩展性、可用性和健壮性,适合存储大量数据并且同时要求低延迟的应用服务。DynamoDB 提供全托管服务且操作简单,以至于在开发者中流传着这样一句话“使用 DynamoDB 你什么也不用管,只需要记得付账单就可以了。”很多顶级企业都是 DynamoDB 的用户,国外有 Netflix,国内如华米、随锐。
DynamoDB 的核心组件是表、项目和属性。表是项目的合集,项目是属性的合集。DynamoDB 使用主键来表示表中的项目。分区键用来构建一个非排序的散列索引,使得表可以进行分区,从而满足扩展性的需求。在一个分区键决定的散列索引里,数据按照排序键进行排列,每个排序键所对应的数据行数没有上限,除非你有本地二级索引。
本地二级索引 (LSI) 可以选择与表不同的排序键,每个表分区对应一个索引分区。每个分区键可以存储最多 10 GB 的数据,包括表分区和索引分区的数据量。
除本地二级索引,另外一种索引方式是全局二级索引 (GSI)。全局二级索引可以选择与表不同的分区键以及排序键,且每个索引分区会对应所有的表分区。
GSI 和 LSI 该如何选择呢?对于 GSI 来说,索引尺寸没有上限,读写容量和表是独立的,只支持最终的一致性。而对于 LSI 来说,索引保存在表的分区中,每个分区键值的存储上限是 10GB,使用的是表上的 RCU 和 WCU。
使用 DynamoDB 除了需要指定主键、分区键和排序键外,用户只需确定访问次数,系统会根据访问次数预置容量。不仅如此,DynamoDB 还拥有独特的 Token Bucket 算法,可以将剩余的 RCU 存储下来,以应对突如其来的流量洪峰。
对于 NoSQL 来说,一个比较常见的问题是访问不均衡的问题,而 DynamoDB 特有自适应容量(Adaptive Capacity )功能,增加过热分区的吞吐量,对过热项目进行隔离。此外,DynamoDB 还提供预置容量自动伸缩和按需扩容等功能在保证容量的基础上,最大限度降低企业成本。
分享的最后,吕琳介绍了四个有关 DynamoDB 设计最佳实践,分别为:
● 慎重选择 Hash Key 以实现无限扩展
● 如何存储大项目
● 如何处理热点项目
● 使用 Time-Series 表格存储时序型数据
“纸上得来终觉浅,绝知此事要躬行”吕琳老师的分享让现场的开发者对现代化数据架构有了初步的认识。随后,开发者们在李君老师的带领下,开始了动手实验环节。本次 Build On 共设置两个动手实验。
动手实验一假设开发者正在构建一个用来上传照片的移动应用程序。用户将通过开发者开发的应用程序上传照片,其好友可以查看他们的照片。这个应用程序是一个社交应用程序,因此用户可能会查找和关注好友。关注好友后,用户将收到好友发布新照片的通知,并能够向好友发送消息。开发者设计的应用程序要能够满足用户使用爱心、笑脸、竖起大拇指、戴墨镜四种表情符号对照片做出表态的需求。
通过这个实验,开发者学习了如何对 DynamoDB 表进行建模以处理应用程序的所有访问模式,并了解了如何使用新的事务处理功能,从而快速高效地使用 DynamoDB。
除应用于社交场景外,DynamoDB 也是游戏场景颇受欢迎的数据库服务。动手实验二假设开发者正在构建一个有 50 名玩家同时在线的大逃杀游戏。游戏时间通常为 30 分钟左右,在游戏中,开发者必须更新某特定玩家的记录,以指明该玩家玩游戏的时长、创纪录的杀敌数量或者是否获胜。满足用户想查看他们玩过的游戏、游戏获胜者或者想观看每场游戏动作重播的需求。
通过该实验,开发者们进一步了解了一些核心数据建模的策略,以及如何在游戏及其类似场景中使用 DynamoDB 构建现代化数据架构。
你是不是也想试试呢?未能亲临现场参与本次活动,并对 DynamoDB 数据库感兴趣的开发者可扫描下方二维码注册账号并领取礼包,实操上述两个动手实验。
点击阅读原文即可下载本期 Build On 上手实操手册,快来亲自动手学习\复习课程内容吧~