作者:phoenixxliu,腾讯TEG后台开发工程师目录:简介一、背景二、竞品分析三、需求与挑战四、架构与解决方案五、总结与展望简介小程序云开发(腾讯云基地)具有易接入、高性能、高可用等特点。其中,云数据库是核心组件之一,可有效降低运维成本,帮助开发者实现业务快速上线和迭代。本文将简要介绍如何使用TEG云架构平台部的高性能分布式NoSQL数据库,为近百万小程序云开发用户提供完整的原生云数据库能力支持。一、背景要了解小程序云开发,不妨从字面上拆解成小程序和云开发两部分。在本节中,我们也将尝试从这两个方面对相关背景知识进行简要梳理。1.1云开发从软件工程的角度来看,软件开发经历了以下三个阶段:传统开发-->敏捷迭代-->Serverless。传统开发模式和敏捷开发模式除了需要开发人员编写核心业务逻辑外,不可避免地需要对后端基础设施进行管理、控制和优化。例如,一个应用的逻辑可以很简单,但是一旦涉及到应用的发布和部署,开发者就需要花费大量的精力在服务器、数据库、网络等基础设施的应用和建设上,这些后端基础设施的稳定性也必须考虑性能、可用??性和监控指标。这一切都是费时费力,与产品的核心功能无关。对于需要快速开发和试错的产品,传统模式开发速度慢,部署和运维成本高。发展趋势随着Serverless概念的流行,越来越多的开发者开始转向Serverless架构。“Serverless”并不是说后端没有服务器,而是后端服务器和相关的运维操作对上层应用开发者变得不可见和透明。用户无需关心后端基础设施,直接通过云API访问云函数、云数据库、云存储,获得算力、数据库、存储等后端基础能力。这种on-the-go的开发模式,不仅可以让开发者更专注于自己的业务逻辑,还具有成本低、开发速度快、免运维等诸多优势。1.2小程序小程序不宜过多介绍。相信每个使用智能手机的人,在日常生活中或多或少都用过各种小程序:点餐、外卖、打车、购物等等。为了严谨起见,我们按照张小龙朋友圈的介绍,给出一个简单的定义:小程序是一种无需下载安装即可使用的应用,它实现了“触手可及的应用”梦想。进行搜索以打开应用程序。也体现了“用完就走”的理念,用户无需关心是否安装了太多应用。应用程序将无处不在,随时可用,但无需安装或卸载。自从2017年1月9日微信发布小程序(恰好是十年前乔布斯发布第一款iPhone,据媒体解读,这是张小龙的致敬,也是他野心的体现),小程序已经形成在过去的几年里。随着完整生态系统的建立,用户数量和小程序数量也有了长足的进步和发展。其他主流互联网公司也开始布局小程序平台,如支付宝小程序、百度小程序、抖音小程序、今日头条小程序等。根据微信提供的数据,2019年,微信小程序全球交易额超过8000亿,同比增长160%,日活跃用户超过3亿。截至目前,微信小程序已上线超过100万个,用户超过150万。开发者、8200多家第三方平台、电商小程序、零售行业同比爆发式增长。到2020年微信公开课PRO(也是1月9日),全网小程序数量已突破450万。可以说,我们已经进入了一个“全民小程序”的时代。今年受新冠疫情影响,由于小程序开发比APP开发更轻、门槛更低,覆盖面更广,各类健康码、申报单、信息核验等多采用小程序。表格在线。同样,随着线下实体店客流受阻,越来越多的商家和门店将销售转移到线上,以确保疫情期间的现金流。小程序也是这种场景的最佳选择。小程序越来越多元化、越来越受欢迎,意味着越来越多的小程序开发者将进入市场。如何基于小程序生态服务这些开发者,成为一个挑战。一件必须解决的事情。于是小程序云开发就出来了。可以说小程序需求+serverless概念=小程序云开发。小程序云开发依托微信作为小程序的前端运行,同时通过接入云函数、云数据库、云端等云服务实现“开箱即用”的后端基础设施贮存。这些特性可以大大解放小程序开发者的生产力,大大降低开发成本和难度。2、竞品分析其实,互联网巨头们早就看中了这个市场。以google为例,自2014年10月收购filebase以来,google将现有的云服务和工具整合到filebase中,使其成为一站式BaaS(Backendasaservice,后来的TerminalasaService)产品,涵盖四大领域开发、质量、分析开发等主要模块,提供鉴权、数据库、存储、云函数、机器学习等一系列性能和数据分析工具等服务。filebase-cloudfilestore如果你专注于它的数据库产品,filebase提供了两种选择:CloudFilestore和实时数据库。虽然都是NoSQL数据库,但官方还是推荐前者,因为它可以提供高性能、良好的扩展性,以及其他更高级的特性。参考官网??介绍,cloudfilestore的主要功能如下:Flexibility——支持灵活的分层数据结构、文档类型;表达式查询——支持过滤/排序等功能,自动首页索引,查询性能与结果集大小成正比(而不是整个数据集的大小);实时更新——支持实时数据同步;离线支持——缓存离线写入、读取、查询,并在恢复在线时同步本地更改;可扩展的涉及——基础设施支持自动多区域数据复制、强一致性保证、原子批操作和事务支持;另外,filestore支持按需付费,可以支持数据存储、流量、文件读(查询)、写(插入/更新)、删除(删除)操作次数计费。并提供多种开发语言版本的客户端和SDK。其他著名的BaaS产品包括Parse,它首先被Facebook合并,但很快就停止运行了。目前以开源产品的形式运行在github上,开发者需要自己下载源码部署维护,已经失去了BaaS的意义。同样,国内也有很多提供一站式后端服务(BaaS)的产品,包括:LeanCloud、Bmob、willddog野狗云服务、知晓云等。腾讯云推出的小程序云开发(TencentCloudBase,TCB)也是属于同一个赛道的产品,即采用serverless架构的一体化后端云服务。3.需求与挑战那么,小程序云端开发对数据库有哪些基本要求呢?挑战是什么?我们认为应该有以下五个要求:安全性:对于数据库来说,数据安全是第一位的;易用性:类似于小程序的特性,“开箱即用,用完即走”,简单易用,免运维;成本低:按量收费,精细化成本控制;高性能:Nosql,支持高并发读写;灵活性:无固定数据库表模式(no-schema),支持弹性伸缩;显然,最大的挑战是如何利用现有的技术同时满足这五个需求,并实现它们的良好权衡。毕竟,在大多数情况下,我们并不是提出一个新的架构,而是在多个解决方案和组件之间进行选择。就像分布式系统中著名的CAP理论一样,你只能做到一致性/可用性/分区容错。选择其中两个。下面会先介绍一下我们使用的架构,然后说明在这样的架构下遇到的挑战以及我们采用的相应的解决方案。(不一定是最优方案,读者可以自己思考一下,我们如何取舍)4.架构与方案针对上述5个主要需求,我们从架构的角度来分析云开发设计等方面。对数据库进行了相应的修改和优化,其架构图如下:云数据库架构v2的顶部是小程序的访问客户端,中间是访问层,底层是存储层数据库。当然还有外设控制、报警、备份、元数据管理等模块。通过云开发提供的SDK,开发者可以在微信小程序和QQ小程序中一键获取云数据库的登录状态,然后向接入层发送数据读写请求。接入层收到用户的读写请求后,由keeper和agent这两个无状态模块处理接入读写请求。其中keeper主要负责请求鉴权、鉴权缓存、读写请求数的统计。是云数据库权限校验、负载均衡、计费功能的核心模块。代理模块主要有以下功能:1)维护从接入层到底层数据库实例的连接池,通过复用已建立的连接减少请求认证和连接创建的耗时;2)统计并发请求数,平滑处理读写请求的QPS,避免短期的毛刺影响数据库性能和可用性;3)热迁移切换数据库实例时,暂停请求,切换后恢复请求,实现热迁移过程。整个过程是无意识的。最后,读写请求经过访问层,到达存储层读写数据库实例。由于本文的重点主要放在数据库层面,我们将尝试从四个方面进行描述。为避免本文篇幅过长,部分内容将不给出具体实现,仅作简要分析。有兴趣的读者可以留言或找我们讨论。4.1访问控制权限控制首先,用户只能访问自己的数据库,不能访问其他用户的数据库。不同用户的数据库是相互隔离的,所有的连接也必须经过认证。默认情况下,用户对数据库具有读写权限,也支持创建多个对数据库具有不同权限的账户(如只读账户)。在小程序云开发场景下,利用微信的全链路免认证特性,用户无需过多关心认证相关问题。访问控制和连接数控制之后是连接数控制。我们会分两层进行控制:1)客户端连接控制在接入层进行,初始化时根据实例类型(免费/付费等)进行不同的初始化限制。如果超过限制,会提示相应的用户;2)接入层到存储层的连接数也有相应的控制,会把链接池化到后端数据库的所有主从节点,避免链接过多导致的数据库性能问题.Traffic&QPScontrol最后就是机器级别的进出流量控制和资源使用限制。原理类似于连接数控制。所有的用户请求都会经过接入层,所以可以在接入层控制QPS,实现后续的按量付费功能。QPS超过阈值后,可以在接入层提示或排队。这里可能有人会质疑,云开发数据库不是弹性伸缩的吗?为什么有qps限制?不应该是我的qps越来越高,后端的数据库资源也在不断的膨胀吗?答:可以,默认配置下会有一定的弹性扩展空间,但是会有限制。当然,这里的具体限制与产品策略有关。4.2数据安全数据安全是数据库最重要的特性之一。毕竟,存在数据丢失风险的数据库是无法在激烈的市场竞争中生存的。那么云数据库是如何保证数据安全的呢?数据冗余要解决数据丢失问题,首先要避免数据库的单点问题,即要有数据冗余。一般来说,业界认为最安全的备份数是三个。所以云数据库默认是三副本分布式存储,即一份数据会分三份存储在不同的机器上,机器也应该分布在不同的机房。节点区分主从状态,主节点可以接受读写请求,从节点只能接受读请求。副本集中的存储节点使用raft-like副本集协议实现三份数据的最终一致性。高可用当一台机器出现故障时,副本集中的数据节点会自动切换(FailOver),从节点会成为主节点继续提供服务,从而最大限度地减少对业务的影响。数据安全备份归档云数据库备份对用户完全透明,后台根据数据库状态自动选择性地进行全量和增量备份。具体来说,用户写入速度越快,后台备份频率就会越高。这样做的目的是减少文件回滚时需要回放的数据,提高文件回滚性能。支持7天内随时文件回滚,您可以选择只回滚单表,进一步减少文件回滚所需时间。另外,如果节点故障需要在副本集中添加新节点,可以选择从备份文件中恢复,从而减少对源集群的入侵。基于冷备恢复,多可用区容灾云数据库默认跨三个机房(AZ,AvailabilityZone)部署,对用户也是透明的。任何机房出现故障,都不会对服务产生任何影响;它还可以支持多个区域。两地三中心等模式。比如北京、上海、深圳各有一个节点,业务采用就近访问方式,减少业务访问云数据库的延迟。两地三中心此外,所有与数据库的连接都必须经过身份验证,所有数据都经过加密和压缩存储。这两点保证了数据链路安全和存储安全。4.3弹性伸缩在很多情况下,业务的访问方式会呈现出明显的周期性或不均匀性特征。例如,外卖业务的高峰期出现在就餐时段,其他时间段的客流量较少;游戏业务的高峰期出现在晚上或周末,工作时间较少;还有一些特殊时间点(双十一、618等)的电商业务高峰期。如果周期律按照传统的数据库运维模型,需要提前预估量级,然后运维扩容,活动结束后再缩容(否则成本是个问题).那么在小程序的场景下,由于用户应该是感知不到后端服务的,所以应该感受不到资源的膨胀和收缩。基于这个出发点,我们实现了云数据库的弹性伸缩。依托管控系统的负载监控模块,我们可以根据数据库的实时负载动态调整数据库的资源,并自动调整敏感度,从而有效应对突然增加的数据库资源。数据库负载,也可以在负载低的时候分配资源。版本可供其他更需要它们的实例使用。其次,为了避免单个大查询带来的频繁调整,我们设置了滑动窗口和“去毛刺”机制,以保证弹性伸缩尽可能顺利进行。数据库热迁移当实例的状态发生变化时(如免费-->付费,冷-->热),可能需要进行数据迁移,比如从性能较差的机器迁移到性能较好的机器。在接入层的配合下,我们实现了用户不感知的数据库热迁移,可以将用户数据从一个数据库迁移到另一个数据库而不丢失服务。整体来说,数据库热迁移主要分为数据同步(DataSync)、割接(Cutover)和状态变更(StatusChange)三个部分。第一阶段,高性能数据同步能力完全由底层数据库支撑。需要先同步全量数据,然后在全量阶段同步新产生的操作日志(operationlog),然后不断循环这个过程,直到源数据库和目标数据库之间的差距非常大小的。实现方式和副本集中的主从同步非常相似。在此阶段,源数据库是可读可写的。第二阶段,即当双方数据库差距很小时,热迁移的割接过程会导致源数据库不可读不可写,接入层暂时hold住用户的请求,不返回错误;数据同步在目标数据库完成所有操作记录并验证两边数据完全一致后,进行割接,包括用户的副本和一系列的元数据变化。第三阶段,割接完成后,目标集群变为可用,之前被接入层阻塞的请求可以释放,继续执行。由于切换过程非常快(秒),这些请求不会返回超时等失败。当然,这里只考虑最一般的情况。当某个环节出现异常时,需要考虑相应部分的回滚和响应逻辑,这就涉及到状态机的变化。这个比较复杂,这里不再赘述。我们认为数据热迁移应该是用户完全感知不到的,主要有以下难点:集群变化的强一致性感知;高性能割接;割接状态持久化和超时控制;临时处理用户请求;在架构上,底层数据库提供了高性能数据同步的基础能力;由于接入层agent的存在,可以很方便的实现agent之间的强一致性感知和用户请求的临时处理(比如blockliving);引入分布式KV存储系统etcd实现持久化和超时割接状态的控制,如下图所示:热迁移状态转移图已经在线上环境中进行了测试。当数据库排序并保持在3k左右的QPS(100%写入)时,热迁移就成功了。从前端来看,迁移过程中用户请求的成功率一直保持在100%,这意味着热迁移对用户是完全透明的。我们不妨举个例子来说明一下数据库热迁移的应用。微信阅读业务采用小程序云开发,微信阅读小程序中的“每日一答”模块完全采用云数据库作为底层支撑。“问答PK”、“每日一答”和不同类型的问题存储在不同的表中。峰值(晚上0:00左右)QPS接近10k,业务上线后一直平稳运行。有一段时间,我们发现共享资源池中某个用户的访问次数有明显增加的趋势。弹性缩放后,仍然不能完全满足其需求。为了避免对微信阅读实例造成影响,我们决定通过热迁移的方式来迁移整个数据库实例。移动到我们的热资源池的方法。由于数据量不大(10G),仅几分钟就完成了数据迁移割接(二级)工作。整个过程对用户是完全透明的,当然对微信阅读实例没有任何影响。4.4智能DBA智能DBA是一个很大的话题,涉及方方面面。从层次上讲主要包括以下三层:应用层、处理层和采集层。采集层负责从多个数据源采集需要的数据和指标;处理层对采集到的数据进行预处理和分析,并生成相应的决策和建议;应用层根据不同的应用场景进行不同的处理,比如自动运维模块需要处理异常,而巡检模块只需要进行巡检和告警。智能DBA自动化运维为了进一步减少后台的运维操作,我们实现了自动化运维平台。通过在运行时监控存储节点的状态,对每个节点进行检测和故障判断,然后决策中心根据故障统计结果进行相应的自动化运维操作(例如磁盘是否只读),master被强制裁剪)同时也会提醒运维人员,确保自动化运维的结果是正确的。自动化运维平台针对一些自动化运维无法覆盖的问题,在各个层次、各个维度(机器、实例、节点等)进行了全套的秒级监控。总共有69+个指标,后台可以实时感知数据库的状态;尽快发现问题处理。索引优化索引是数据库中一个非常重要的概念,用来加快数据库的查找速度。在小程序场景下,我们希望尽可能减少用户对后台数据库的感知。所以实现了一系列的查询优化功能,比如自动建立索引。当我们的访问层和存储层发现用户查询较多,后端是全表扫描时,会根据用户查询的具体字段添加相应的索引。建立索引后,用户可以直接享受优化后的查询结果。重要的是,用户在这个过程中也是无法察觉的。我们认为自动索引需要考虑以下几个主要问题,才能让用户完全不知情:同步VS。异步?索引过程应该是异步的,否则来自用户的正常请求将被阻塞。如何控制指数化的风险?主要有两个方向:1)首先要控制自动索引的频率。编制索引是一项消耗CPU的任务。如果数据库一直在建立索引的过程中,显然是不能接受的;2)其次,需要控制自动分度的数量,使其保持在一个相对合理的范围内。一般的表没有问题,但是如果数据库中的一个表包含多个字段,用户会根据这些字段进行不同的查询,那么无限索引就会导致索引特别多,严重影响用户的性能。更新效率(因为更新除了更新数据外,还会更新相应的索引)。如何动态更新索引?用户查询不是静态的。随着业务的发展或转型,对同一张表的查询很可能会发生变化。那么之前自动创建的索引也需要自动删除,否则长此以往会成为数据库的负担和瓶颈。需要根据用户查询条件的变化动态更新已有的索引。索引的最左匹配原则在这里也值得考虑。如何做到对用户透明?不仅在索引时不影响用户的正常请求,还需要让用户直接感受到查询和索引的速度。当表的数据量比较大时,一个索引的改变操作(比如改变复合索引字段的顺序)可能会导致用户同一次查询出现明显的耗时差距。除了向用户解释之外,我们还可以考虑将索引修改得更平滑,并提供一系列的查询优化建议。这样可以帮助用户更好的使用数据库。自动索引功能上线后,数据库实例请求的平均耗时明显下降,整个小程序云开发数据库的平均耗时也减少了50%以上,如下图所示。自动索引上线后的效果确实自动索引还是有一定的局限性的,比如在使用不等于、正则匹配等复杂的查询方式时。这时候就需要其他的方法了,比如在前台提示用户如何优化查询语句;或者根据云数据库提供的慢日志分析工具对慢日志进行分析,给出针对性的解决方案。五、总结与展望小程序云开发可以极大地解放小程序开发人员的生产力,降低开发成本和难度。其中,云数据库起到了举足轻重的作用。针对小程序云开发对云数据库提出的五大需求:安全、易用、低成本、高性能、灵活,我们在数据库架构设计方面进行了多次修改和优化,使云数据库可以更适合小程序的使用场景。面向未来,我们还将在云数据库的管控层提供更细粒度的监控(当然是供我们自己查看,用户无需关注),更智能的DBA,更高效的弹性扩展能力(如基于k8s的云数据库);在云数据库的核心层,我们会封装更多底层的存储引擎能力暴露给API层,根据小程序的使用场景进行定制化开发(比如研究发现很多小程序都是相关的)来回答问题,然后我们可以提供更好的中文文本索引能力),进一步提高事务性能等。我们有理由相信,云开发数据库将在serverless理念的指导下不断完善自身,发展得越来越好连同小程序。参考资料FilebaseFilebasepricingCloudFilestoreIntroducingCloudFilestorertdv-vs-filestoreParseLeanCloudBmob智之云腾讯CloudBase
