云原生数据库海山(He3DB)PostgreSQL版核心设计理念

本期深入解析云原生数据库海山PostgreSQL版(以下简称“He3DB”)的设计理念,探讨在设计云原生数据库过程中遇到的工程挑战,并展示He3DB如何有效地解决这些问题。

He3DB是移动云受到 Amazon Aurora 论文启发而独立自主设计的云原生数据库产品,它与 Aurora 以及其他云厂商的同类竞品共享一些核心设计理念,特别是计算与存储分离、日志即数据库(Log is Database)、以及共享存储。这些理念构成了现代云原生数据库的技术基础,目的是为了提高可扩展性、可靠性和性能。

为了方便大家更进一步的了解 He3DB ,下面我也将逐一解析这几个核心设计理念,并探讨 He3DB 在工程实现或产品核心设计上与 Aurora 及其竞品的不同之处。

云原生数据库核心设计理念

1.计算与存储分离:

这一理念意味着数据库的计算层和存储层在物理上是独立的。这种分离使得两者可以独立地扩展,提高了资源利用率,同时也简化了数据的备份和恢复过程。

2.日志即数据库(Log is Database):

在这种设计下,所有的数据库修改操作首先被记录到日志中,这个日志之后被用作构建和更新数据库状态的唯一来源。这种方法把所有的写转化为日志写,给予我们更多的方法提升写性能以及跨AZ的高可用能力。

3.共享存储:

使用共享存储架构意味着所有的计算节点可以访问同一个存储系统,这样可以实现数据的高可用性和容错性,同时简化了数据管理。

现在即便许多云原生数据库产品在设计上追求解决类似的问题,但在工程实现和产品能力上依然存在显著差异。这些差异导致了性能、高可用性、容量支持以及成本效益等方面的不同。

其实也很好理解,例如,某些产品通过使用高性能硬件提高了性能,但相应地也增加了成本。另一些产品则在底层存储设计上天然支持跨 AZ,从而在高可用性方面表现更佳。

目前许多云服务提供商在推广其云原生数据库产品时强调了它们在多个方面相对于RDS的优势,但从市场接受度来看,RDS依然占据主导地位。这主要是因为云数据库的主要客户群体是中小型企业,这些企业对数据库的负载和存储容量需求相对较低,而RDS的功能和性能已经足够满足他们的业务需求。但由于云原生数据库的架构设计导致其成本相对较高,且在处理小规模数据和低负载场景时,其性能并不总是能超越RDS。所以业内同类竞品在宣传时,往往更强调它们产品能力上限。

而He3DB产品的研发初期,我们除了需要保证它的上限处于业内主流水平 ,其实更关注的是它的下限表现,因为我们期望最终实现的不仅是在能力上全面超越RDS,同时在全场景使用下,成本也要明显优于RDS。为此,我们分别从“性能”“成本”这两个方面设定了以下研发目标:

1.性能目标

l  适应性能:确保在低容量和低负载的场景下,He3DB的性能能与RDS相匹配。

l  优越性能:在面对高负载和高容量的情况时,He3DB的性能要比RDS高出2到3倍。

l  性能指标:实现写入吞吐量(TPS)超过10万,读取吞吐量(QPS)超过100万。

2.成本目标

l  成本效益:任意业务场景负载下,He3DB的成本不高于RDS。

l  成本竞争力:竞品相比,He3DB能够实现至少30%的成本降低。

通过制定这些明确的研发目标,He3DB计划在性能提升成本控制方面实现突破,从而解决市场推广过程中遇到的主要问题,并为用户提供更优的数据库解决方案。

接下来,我将重点介绍He3DB的架构设计,从而解释我们如何实现设计目标,并使它在成本控制上优于传统的关系数据库服务(RDS)以及同类竞品。

3.He3DB设计目标:

l  支持一主15备,能够满足企业对扩展性的需求。

l  支持高达100TB的数据存储能力,适应大规模数据处理需求。

l  主备节点共享存储,这意味着增加备机不会造成存储成本的增加,从而实现了成本效优

l  性能方面,He3DB能够达到读取查询处理速率(QPS)100万次、写入事务处理速率(TPS)10万次的高性能标准。

下面我将从技术角度一一解释He3DB如何实现这些目标。

一、如何支持一主15备:

在PostgreSQL中,随着备机数量的增加,流复制会导致主服务器的性能下降,因为主服务器需要将写操作(WAL)复制到每个备机。在复制过程中,主服务器会遇到瓶颈,尤其是当备机的数量增加到5个以上时。He3DB 需要解决的问题是如何有效地同步和分发日志,以支持一主多备(至少15备)的架构,而不会对主服务器的性能造成显著影响。为此,He3DB采取以下设计:

1.   专用的WAL服务

提供一个专用的WAL日志服务,该服务负责接收主服务器的WAL日志,持久化存储,并将其分发给所有的备机。这样,主服务器只需发送一份WAL日志到WAL服务,由WAL服务来负责分发给各个备机,极大地减少了主服务器的负担。

2.   异步复制

采用异步复制机制,主服务器在写入WAL后不必等待所有备份确认,可以立即继续处理新的事务,这有助于提高主服务器的性能。

3.   批量发送和压缩

WAL服务可以将日志更改批量发送,并在传输前对其进行压缩,以减少网络传输的数据量。

4.   负载均衡和缓存

WAL服务可以使用负载均衡技术来平衡对不同备机的日志分发,同时使用缓存机制来存储热数据,以便快速分发给备机。

5.   多副本一致性算法

采用一致性算法来确保WAL服务的高可用和数据一致性,即使在WAL服务节点故障的情况下也能正常运行。

通过这样的设计,He3DB才能够确保即使在多达15个备机的情况下,主服务器的性能也不会受到明显影响,同时保持数据的高可用性和一致性。这种设计是在主数据库和备机之间引入了一个中间层,来协调日志的持久化和分发过程。关于这个模块的设计我以后会专门出一期再跟大家进行详细介绍。

二、如何支持100T 容量:

He3DB采用计算与存储分离的架构,并利用S3作为底层的持久存储层,这种设计具有多方面的优势:

1.   存储容量和弹性

S3提供了几乎无限的存储容量和良好的弹性。它可以根据需要自动扩展,用户无需预先分配存储空间,也无需担心空间不足的问题。

2.   高可用性和耐久性

S3提供了数据服务的高可用性以及高可靠性,这意味着数据丢失的风险极低。

3.   成本效益

相比于高性能硬件解决方案,S3提供了成本效益更高的存储服务。由于其按使用量计费和无需前期投资的特性,用户可以在控制成本的同时享受高质量的存储服务。

4.   性能优化

通过在S3上层增加数据缓存服务层,可以解决访问S3时遇到的高延迟问题。这层缓存可以用于存储数据,提高访问速度。

5.   自动化扩展和缩容

数据缓存服务层(DS)支持多节点,并且可以根据业务负载自动扩缩容,对外提供透明服务。这允许He3DB动态地调整资源,以应对不同的负载需求。

6.   数据分层

通过将数据按热度进行分层,冷数据(低频访问数据)可以在S3中进行极限压缩,以降低存储成本。热数据则存储在更快速的缓存层中,以提供更佳的性能。

总的来说,He3DB通过将S3作为持久层的选择,结合数据缓存服务层的设计,提出了一个既能满足大规模数据存储需求,又具有成本效益,同时能够提供必要性能保障的解决方案。这种架构特别适合云原生数据库的需求,可以有效地支持数据的扩展性、弹性和成本控制。

三、如何实现共享存储:

在He3DB这样的一主多备架构中,数据的一致性是通过日志同步机制来保证的。主节点和备节点之间通过WAL(Write-Ahead Logging)日志来同步数据变更。

为了帮助大家更好地理解共享存储设计,我再简单介绍一些背景知识:

1.   数据写入和一致性

l  在主节点上持久化写入数据后,由于备节点的数据同步存在延迟,它们读取的数据可能不会立即反映最新的更改,导致主备节点间的数据不一致。

2.   日志顺序号(LSN)和数据同步

l  PostgreSQL在主备节点间同步数据状态是通过日志顺序号(LSN)来标识的。每当主节点上发生数据更改,都会生成一个新的WAL日志条目,并分配一个唯一的LSN。

l  主节点的WAL日志LSN始终是最新的。备节点不断地处理这些WAL日志来追赶主节点的状态。但在WAL日志负载较高的情况下,主备节点可能会在同一时刻对应不同的LSN,从而导致它们所见的数据状态有所差异。

3.   数据PAGE多版本维护

l  虽然大部分时间内主备节点看到的数据状态是一致的,某些数据可能会因为WAL日志同步的延迟而出现版本差异。为了确保数据的一致性和准确性,数据库本身需要管理数据的多个版本。

l  多版本数据管理机制防止在查询操作中访问到还未同步的“未来”数据版本,或者已经被覆盖的“过去”数据版本。

通过实现多版本数据管理,He3DB确保了即使在高负载情况下,数据最终也能达到一致性,同时避免了因为访问错误版本的数据而导致的正确性问题。

在业界,一些数据库产品在处理数据PAGE版本差异时,选择在计算引擎或存储引擎层面进行设计。通常做法是记录一个基础数据页面(PAGE),然后通过链表记录与该PAGE相关的WAL日志条目,以此来异步回放并实现多版本的数据页面读取。

He3DB最初的设计也采用了这种方法。然而,这种设计在性能达到理想状态方面存在挑战,并且会占用较多的内存资源,因为需要在内存中管理元数据。此外,一旦出现问题,问题定位过程比较复杂。

为了解决这些问题,He3DB进行了设计上的改进,实现了所谓的“分布式多版本数据PAGE控制”:

1.单一数据版本维护:

l  数据存储服务(DS)仅维护单一版本的数据。DS控制WAL日志的回放节奏,确保DS是最慢WAL回放节点。这种设计实质上意味着DS主要负责维护主备节点读取一致的数据部分,而由于WAL同步的差异影响到的数据通常很少。

2.本地盘缓存模块:

在每个计算节点,He3DB引入了一个本地盘缓存模块,专门用于缓存和维护主备节点之间的差异数据版本。例如,如果主节点的当前LSN是100,备机1的LSN是30,备机2的LSN是60,而DS的回放LSN是25,那么:

l  主节点的本地盘缓存模块会维护从LSN 25到100之间变更的数据页面。

l  备机1会缓存从LSN 25到30之间变更的数据页面。

l  备机2会缓存从LSN 30到60之间变更的数据页面。

随着每个节点的WAL日志的不断推进,计算节点能够迅速回收相关的缓存页面数据,从而有效释放存储空间。

看到这里可能有人会问,如果出现本地缓存数据的问题怎么办。这一点我们也有考虑到。

He3DB会基于DS重新生成备份节点,并将其加入集群中,而不会影响数据的准确性。这种新的设计不仅提高了性能,减少了内存的使用,还简化了问题定位和故障恢复的流程,从而大幅提高了数据库的可维护性和稳定性。

四、如何保证高性能以及控制波动率:

He3DB在不引入任何高性能硬件的情况下实现了高性能和控制性能波动的策略。下面我将从写和读两个场景分析性能表现:

1.写性能

He3DB的设计理念是“日志即是数据库”(log is database),这意味着所有的写操作都被转换为日志写入。通过将日志写操作外包给专门的WAL服务(wal service),HE3DB能够借助WAL服务的高吞吐量来提升写性能。这个设计允许系统将数据写入操作并行化和分布化,从而提升整体的写入速度。

2.读性能

He3DB采用了计算存储双缓存设计,该设计通过冷热数据分层来保证性能的可控性:

l  热数据:存放在计算节点本地盘,这些是频繁访问的数据。

l  中数据:存放在DS,支持数据分片,对用户透明。

l  冷数据:存放在S3存储中,通过压缩能够进一步降低存储成本。

计算节点的本地盘缓存的热数据源自databuffer的淘汰数据。在业务初始阶段,He3DB会积极缓存所有数据,以保证访问性能稳定,这时候读性能可以与传统的关系数据库服务(如RDS)持平。

随着业务周期的推进和更多统计信息的收集,He3DB会开始进行数据回收,即从本地盘删除部分数据以优化存储。为了降低S3在性能波动上的影响,DS层在初期会尽量缓存所有数据,只有在确认某些数据是不是高频访问数据后,才会将其迁移到S3。

五、控制波动率和成本

冷热数据的策略设计对于控制性能波动和成本至关重要。He3DB遵循的原则是确保高频访问的数据一定能在FC(本地盘缓存)命中,对于不能确定是否为冷数据的,则绝不会直接通过访问S3访问。如果FC的当前容量无法覆盖所有高频数据,He3DB将触发动态的扩容操作而不是简单地将数据淘汰到DS层。

通过这种机制,He3DB能够在没有高性能硬件支持的情况下,通过软件层面的优化实现性能上的提升,同时保持成本的可控和性能的稳定性。这样的设计也允许系统在面对不同的工作负载和数据访问模式时,能够灵活调整资源分配,以适应业务需求的变化。

后续He3DB将采用智能预测和用户知识结合的方法来管理冷热数据。这种策略不仅提高了数据存储的效率,还有助于实现成本的优化。以下是一些实施该策略时可以考虑的要点和可能的扩展:

1.智能数据分层:

利用机器学习模型以及业务访问统计信息预测数据的访问模式,自动将数据分为冷热中三层。

2.用户参与:

用户可以标注特定数据或模式,指导He3DB更好地识别冷热数据。

3.动态定价模型:

根据冷热数据管理策略,设计一个灵活的定价模型。用户可以根据他们的实际使用情况选择不同的价格计划。

4.性能与成本权衡:

通过用户界面允许客户根据业务需求调整性能和成本的平衡,例如,允许客户指定对于特定数据集的最大响应时间。

5.透明度和控制:

提供仪表板和工具,让用户可以看到数据的冷热状态,预估成本,并能够手动调整数据层级。

6.自动化策略调整:

系统可以根据历史数据和预测结果自动调整数据的冷热分层策略,以适应数据访问模式的变化。

7.可扩展性和弹性:

设计系统时要考虑到未来数据量的增长,确保系统能够水平扩展,同时保持性能和成本效率。

8.反馈循环:

建立定期的反馈机制,持续监控和优化冷热数据预测模型的准确性。

通过这些综合的策略,He3DB可以为用户提供一个自动化、高效且成本可控的数据管理系统。用户可以根据自己的业务需求和成本敏感度,调整系统的配置以达到最佳的性能和成本平衡。这种灵活性和自适应性使得He3DB能够在激烈的市场竞争中为用户提供显著的价值。

在产品稳定性设计方面,我们的团队坚守一个核心原则——追求简洁性和控制复杂度。我们相信,只有通过简化设计和控制复杂性,我们才能确保产品的稳定性和可靠性,这也是我们对客户的责任。

这一原则不仅指导着我们的整体设计思路,也直接影响我们在架构设计过程中的决策:

1.PG(PostgreSQL)改造策略:

l  我们决定采用插件化的方法来开发PG的改造部分。这样做可以最小化对PG内核的影响,确保改动是可控的,并将自研代码封装在独立模块中,实现模块的高内聚和低耦合。

l  插件化还有助于我们在未来快速兼容PG不同的内核版本。

2.存储层选择:

l  我们选择了S3来作为我们的技术存储层,而不是开发一个专用的数据库存储系统。这种做法最大限度地利用了现有的云基础设施,避免了不必要的开发工作,同时也能够享受云服务提供的稳定性和可扩展性。

3.数据页的多版本设计:

l  我们将数据页的设计从集中式转变为分布式多版本,这样可以简化整体架构,并使风险更加可控。分布式设计提高了系统的伸缩性和容错能力,同时也简化了数据管理。

总而言之,我们的设计哲学是通过简化和模块化来增强产品的稳定性。我们通过插件化来保护核心系统不受破坏,通过利用成熟的云服务来降低开发难度,以及通过采用分布式数据缓存服务提高系统的可靠性和伸缩性。这些决策共同构成了我们对客户负责任的设计承诺。

今年我们还计划孵化若干新技术以验证我们的创新理念。这些创新成果将逐步以专利申请或学术论文的形式公开,具体创新包括:

1.增量快照技术:

我们正在开发一种增量快照技术,用于高效管理数据页(PAGE)多版本,这有望提升数据处理的灵活性和效率。

2.数据快照设计:

借助创新的数据快照设计,He3DB将能够在无需传统备份的情况下,实现一定时间周期内任意时间点的数据恢复能力。

这些技术进步不仅将增强He3DB的市场竞争力,还将为我们的客户提供更加稳定、可靠且易于管理的数据库解决方案。

六、作者介绍

薛港,移动云高级研发工程师,负责云原生数据库海山PostgreSQL版架构设计。拥有逾十年数据库内核开发经验,在云计算基础设施与数据库整合领域具备丰富的实践知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel---一个工作簿中的多个sheet合并成一个PDF

0 Preface/Foreword 1 操作方法 1.1 方法一 文件》 导出 》创建PDF/XPS 》 选项 》发布内容 》“整个工作簿” 1.2 方法二 文件》 打印》 打印机选项中,选择一种PDF阅读器 》设置选项中,选择打印整个工作簿。

三步就能在OpenHarmony中实现车牌识别

介绍 本车牌识别项目是基于开源项目 EasyPR(Easy to do Plate Recognition)实现。EasyPR 是一个开源的中文车牌识别系统,基于 OpenCV 开源库开发。 本项目使用润和 HiSpark Taurus AI Camera(Hi3516DV300) 摄像头开发板套件(以下简称 Hi351…

对拍器/对数器 赛前抱佛脚

“对拍器/对数器的使用前提是该题你会暴力解法,如果不会,那么对拍器/对数器也没啥用。” 对拍器/对数器 应用背景 你有一个绝对对的暴力cpp代码,但时间会T,只适用于小范围的数据。所以你写了一个聪明的非暴力cpp代码&#xff0c…

【ctf.show】获得百分之百的快乐

1.打开靶场 2.根据页面代码,get请求值只能小于4位数,否则会回显hack! 尝试后确实是这样的: 请求值小于4位数,页面无变化: 发送请求值ls查看内容 3.根据2返回的值,发送值为?1>nl 创建一个nl…

vivado 使用基本触发器模式

使用基本触发器模式 基本触发器模式用于描述触发条件 , 即由参与其中的调试探针比较器组成的全局布尔公式。当“触发器模式 (Trigger Mode) ”设置为 BASIC_ONLY 或 BASIC_OR_TRIG_IN 时 , 即启用基本触发器模式。使用“基本触发器设置 (Basic Trig…

【面试题】细说mysql中的各种锁

前言 作为一名IT从业人员,无论你是开发,测试还是运维,在面试的过程中,我们经常会被数据库,数据库中最经常被问到就是MySql。当面试官问MySql的时候经常会问道一个问题,”MySQL中有哪些锁?“当我…

数据结构-----Lambda表达式

文章目录 1 背景1.1 Lambda表达式的语法1.2 函数式接口 2 Lambda表达式的基本使用2.1 语法精简 3 变量捕获3.1 匿名内部类3.2 匿名内部类的变量捕获3.3 Lambda的变量捕获 4 Lambda在集合当中的使用4.1 Collection接口4.2 List接口4.3 Map接口 HashMap 的 forEach() 5 总结 1 背…

第十三届蓝桥杯真题:x进制减法,数组切分,gcd,青蛙过河

目录 x进制减法 数组切分 gcd 青蛙过河 x进制减法 其实就是一道观察规律的题。你发现如果a这个位置上的数x&#xff0c;b这个位置上的数是y&#xff0c;那么此位置至少是max(x,y)1进制。一定要把位置找对啊 #include <bits/stdc.h> using namespace std; typedef l…

如何卸载干净 IDEA(图文讲解)

更新时间 2022-12-20 11:一则或许对你有用的小广告 星球 内第一个项目&#xff1a;全栈前后端分离博客项目&#xff0c;演示地址&#xff1a;Weblog 前后端分离博客, 1.0 版本已经更新完毕&#xff0c;正在更新 2.0 版本。采用技术栈 Spring Boot Mybatis Plus Vue 3.x Vit…

如何开辟动态二维数组(C语言)

1. 开辟动态二维数组 C语言标准库中并没有可以直接开辟动态二维数组的函数&#xff0c;但我们可以通过动态一维数组来模拟动态二维数组。 二维数组其实可以看作是一个存着"DataType []"类型数据的一维数组&#xff0c;也就是存放着一维数组地址的一维数组。 所以&…

【C++成长记】C++入门 | 命名空间、输入输出、缺省参数

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C​​​​​​​❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、C和C语言的区别和联系 二、命名空间 1、命名空间定义 2、命名空间使用 三、C输…

基于yolov9来训练人脸检测

YOLOv9是一个在目标检测领域内具有突破性进展的深度学习模型&#xff0c;尤其以其在实时性与准确性上的优秀表现而受到广泛关注。针对人脸检测这一特定任务&#xff0c;YOLOv9通过其架构创新和算法优化提供了强大的支持。 YOLOv9在继承了YOLO系列&#xff08;如YOLOv7、YOLOv8&…

二叉树--相同的树

给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&#xff1a;true 思路 一、…

JavaEE 初阶篇-深入了解 CAS 机制与12种锁的特征(如乐观锁和悲观锁、轻量级锁与重量级锁、自旋锁与挂起等待锁、可重入锁与不可重入锁等等)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 乐观锁与悲观锁概述 1.1 悲观锁&#xff08;Pessimistic Locking&#xff09; 1.2 乐观锁&#xff08;Optimistic Locking&#xff09; 1.3 区别与适用场景 2.0 轻…

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程 1.1、operator()的引入 现在需要完成这样一个需求&#xff1a;有一个函数每次调用返回的结果不一样。例如&#xff1a;两次调用的返回值都不一样那么就可以达到这种目的 1.1.1、简单点的写法 可以给一个全局的变量&#xff08;静态变量&#xff09;&#xff…

深入理解JVM垃圾收集器

相关系列 深入理解JVM垃圾收集算法-CSDN博客 目前市面常见的垃圾收集器有Serial、ParNew、Parallel、CMS、Serial Old、Parallel Old、G1、ZGC以及有二种不常见的Epsilon、Shenandoah的&#xff0c;从上图可以看到有连线的的垃圾收集器是可以组合使用&#xff0c;是年轻代老年代…

Input DropDown 拼接成 select组件(基于antd和react)

前言&#xff1a;为什么不直接用select&#xff0c;还要舍近求远搞inputdropdown这种缝合怪&#xff0c;是因为antd的select不支持选中项再编辑&#xff0c;效果如图 比如&#xff1a;选中的lucy文案变成了placeholder不能再编辑了 封装此组件虽然比较简单&#xff0c;但还是有…

PLC互连全攻略:Profinet和EthernetIP实操演示

在今日的技术分享中&#xff0c;将详细探讨实现Profinet和Ethernet/IP的通信配置&#xff0c;以连接西门子PLC&#xff08;Profinet&#xff09;和罗克韦尔PLC&#xff08;Ethernet/IP&#xff09;。本篇将重点介绍专为通信而设计的Profinet转Ethernet/IP网关&#xff0c;在联接…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件&#xff0c;它遵循JMS1.1规范&#xff08;Java Message Service&#xff09;&#xff0c;是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高…

【R语言从0到精通】-3-R统计分析(列联表、独立性检验、相关性检验、t检验)

上两次教程集中学习了R语言的基本知识&#xff0c;那么我们很多时候使用R语言是进行统计分析&#xff0c;因此对于生物信息学和统计科学来说&#xff0c;R语言提供了简单优雅的方式进行统计分析。教程参考《Rlearning》 3.1 描述性统计分析 3.1.1 载入数据集及summary函数 我…