数据库超体:程序员撩妹神器

digoal(德哥) 2017-05-22 10:47:21

 

本文根据digoal(德哥)在〖2017 Gdevops全球敏捷运维峰会成都站〗现场演讲内容整理而成。

 

(点击底部 链接 获取德哥演讲完整PPT)

 

讲师介绍

digoal(德哥),现任职于阿里云数据库内核技术架构组。PostgreSQL中国社区发起人之一、常委、兼任社区大学校长,PostgreSQL中国社区杭州分会会长,PostgreSQL中国社区大学发起人之一。14项已授权专利。乐于分享,撰写技术类文章几千余篇,狂热技术分子,致力于PostgreSQL数据库在中国的技术推广与人才教育。

 

“超体”这个例子来源于一部电影,电影中探讨当人的脑细胞被开发到100%的时候会达到一个什么样的现象。同样的,今天我们以PostgreSQL为例,看看当数据库被开发至100%会产生什么,是不是可以解放程序猿的双手,节约50%的开发时间去撩妹?(¬∀¬)σ

 

20%

 

 

 

1、物联网、金融、日志、运营商网管、行为轨迹类数据

 

20%的时候会是什么样子的?先来看一个场景,现在非常流行物联网的场景,包括金融、运营商网关,还有电商,然后很多的一些O2O的平台采集用户的信息。因为每一次手机上的操作,点击都会记录下来,以便后面做一些用户行为挖掘的动作。那么这些数据有什么样的特征?

 

 

行为数据的特征包括追加写,不停地写入,同时在时间和维度上跟你的堆存储存在一定的线性关系。行为数据的数据量是很大的,一个业务的日记录数以亿到百亿记。

 

查询需求方面,需求方可能需要查一个群体性数据在某一个时间点发生的行为,这是时间区间查询的需求。第二个查询需求可能是分析需求,比如群体性的特征分析,这么大一个数据量的情况下,会要求插入快,因为插入慢的话就有丢数据的风险(就像网络丢包一样,可能导致重传和拥塞,影响用户体验)。

 

存储的要求,要支持压缩,比如说我插的数据这么大的量不能压缩,在成本上可能是扛不住的,业务方想保留一年的数据,压缩与不压缩成本可能相差好几倍。

 

数据种类的需求。随着物联网的发展,终端采集的数据越来越多样化,传统的数字、字符串、时间是比较常见的,现在可能还会加入更多的类型,比如定位的信息,而且事件的发生有时间和空间的维度在里面,越来越多的用户需要支持更多的数据类型。

 

2、PostgreSQL块级别索引– BRIN

 

 

我们看一下检索,假设一天产生几十个G的数据,用户想找到12点前后五分钟的数据在哪里,但想一想一天几百个GB的数据,索引有多大呢,那么什么方法可以减少索引的大小?

 

在这里可以使用块级存储,比如一个数据块是一兆,这一兆的数据里面覆盖了某个字段从几点到几点的信息,块级索引只需要存储边界值、COUNT、SUM等信息,所以块级索引会变得很小很小。使用了块级别索引后你耗费的空间相比原来下降几百倍,如果一个数据块可以存两百条记录的话,你的索引会变成是原来两百分之一那么小,而检索的速度是没有受到影响的(前提是被索引的字段数据的逻辑顺序与对存储的物理顺序有线性相关性)。

 

 

从图上看单步插入的速度,比原来使用快了很多。

 

 

接下来我们看一下看压缩的需求。压缩这一块,其实有很多的算法,有有损压缩(旋转门压缩)和无损压缩(列存储:瓦片式/内置/FDW/IMCS)。比如说旋转门的压缩,这个是来自于一个做电力的监控系统:

 

 

一个发电厂有很多的传感器,这些传感器每十毫秒就上传一个数据,数据量是非常庞大的。这里有一个旋转门压缩转盘,在这个数据库里面可以写一个UDF实现一个同样的功能。刚刚讲的这个功能,有一个非常典型的应用就是在阿里的菜鸟中有一个跟踪系统有用到这个产品里面的特性。

 

第二个场景为搜索类、多维度交互类的场景。比如说淘宝前端的页面,我们在做一些搜索的时候,我要找销量大于多少的,还是按照店铺名称找,还是按照商品名找,或者是按照商品的地区搜索等等。我们在搜索时有很多选择,但表设计好之后有几十个字段,每个字段都有可能是客户选择的选项,如果是针对每一个字段建索引的话,虽然你满足了用户的需求,但是会带来很大性能的插入和更新性能的损耗。同时用户可能是按照某一个字段做模糊的搜索。

 

 

在PostgreSQL数据库里面可以帮你做这件事情,它的原理非常简单,就是通过这种倒排的方法做索引(GIN),还有其它的方法比如通过空间索引(GiST),通过这种方法可以实现任意字段的检索。

 

现在许多开发者会使用JSON存取数据,当设计之初,也许无法固定结构设计,那么可以用到PostgreSQL的JSON的数据类型,JSON内容的检索与普通字段的检索方法一样,同样支持模糊查询。

 

典型的用户:在阿里里面一个是淘系用户,这个任意字段检索的特性用得比较多。还有万网和阿里云的官网。最后一个是相似的搜索,比如说一篇文章里面涉及到一百个商品,别人写的文章里面涉及50多个商品,你跟他有40个是重叠的,怎么搜出来?这个是通过相似索引搜出来的,它达到的效果也是很高的,可以在几个毫秒之内就在上亿的数据里面帮你搜索出与你提供的数据相似的数据。

 

3、高效率范围查询

 

再看看第三个场景——范围数据。范围数据出现最多的地方是物联网。在物联网里面它的传感器要不停上报数据,但是比如说一些温度传感器,或者是湿度等等指标的传感器,它的范围波动是很小的。像电压的波动,可能一直就在220左右波动的,假如一个小时上来的数据全部在这个范围内波动,实际上在后台根本没必要每一个值都存下来,我可以直接存一个范围,假设你的偏差精确到99.9%在业务上是可以容忍的,这时候我完全不需要把每一个精确的值存下来。

 

 

存取范围,涉及到范围类型,也是一个比较有趣的特性,比如说1到2,这种数值经常做什么样的检索呢?今天所有的传感器上报的数据里面,哪些是100-200之间的数据,按照原来的设计两个字段索引做搜索,是可以实现的,但是效率比较差,如果使用范围索引来做的话,实测性能提升20多倍。GiST对范围数据做聚类划分,搜索时可以快速定位到需要搜索的范围。

 

范围数据类型,典型应用场景是物联网,以及智能DNS。智能DNS会根据你IP的来源落到某一个范围里,再去索引你到最近的库里面去。

 

接下来讲一个比较有意思的场景,求数据差集,用到数据库的递归查询特性。比如说一张表是一亿数据的,用车辆ID这个场景说明。业务背景是商用车辆的轨迹跟踪,在一家企业里面,假设有一百万辆商用的车辆,一天可能上传几亿的轨迹数据上来,但用户想查今天没有出勤的车辆,怎么查?使用递归的方法可以做到0.几毫秒,也是非常有意思的事情。而传统的方法,使用left join,需要几秒。

 

递归查询,典型的用户比如说区块链,还有ERP系统里面有很多的关系,特别是一个大数据,小数据的清洗。

 

40%

 

 

 

当数据库发挥到40%功能的时候看一下是什么样的。

 

1、数据库端编程

 

我们用传统的方法去写一个应用时,肯定就是让数据库做该做的东西,我要的时候告诉你要查出什么样的数据,但是一来一回,耗费在网络上的开销就变得特别大。特别是在银行这种系统里面,开户一开就是1个小时过去了,里面可能跟数据库交互多少次,那如果说这个时候你把这个程序逻辑写到数据库里面去的话,实际很多场景里面也在用的,特别是银行这些事务处理非常复杂,同时要求数据可靠性、一致性很高的场景用得比较多。所以实际上存储过程在银行、运营商用得比较多。

 

一种方法是在外面用程序做,跟数据库交互若干次,另一种方法是跟数据库交互很少的次数,就是你把逻辑放到数据库中,我们来看一下可以达到什么样的效果?

 

 

我们测试过万兆网的场景,做事物的处理,20条Query使用交互式的方式,还有使用逻辑全部放在数据库这一端做的,他们出来的差别可以看一下,使用逻辑数据库可以达到100万的QBS,如果把数据库放到云端的不同主机的话,数据库延迟可能更大,所以如果业务对延迟响应苛刻、并且业务逻辑允许的情况下,建议你放到数据库里面。

 

 

2、异步消息

 

问大家一个问题,当你要监控上万台,或者几十万台设备时,你后端需要多少个数据库?也是跟互联网的传感器一样,你有若干个监控指标,每一个设备每一秒可能会产生上千个指标,传到你的数据库里面去,当数据有异常的情况,通知服务端,这就是异步消息所在。数据不停往数据库里面插,发现有异常的时候,就通过异步消息告诉程序有异常,通过这种方法可以做到百万的NVPS,这是一个数据库可以做到的。然后硬件的话实际上也是用普通的X86场景。后面会详细的讲这个流式计算的功能。

 

 

这个是基于地理位置放了很多的传感器,这些传感器不停地上报数据,这些数据发生异常时,就告诉你这里发生异常了,通过异步的方式来实现。

 

3、数据泵

 

 

数据泵也是有意思的场景,特别是在一些历史悠久的企业里面,各种数据库都有,这么多的数据库或者数据产品,他们要共享数据怎么办?最开始我的数据往关系数据库里写的,但是如果要共享给其它的平台,怎么样实时地分享?那就用数据泵,这个东西就是数据库内置的一个消息队列的插件,通过REDO的结合实时对外分享数据。

 

4、天文、地理

 

另外一个是现在需用到非常多数据的,特别是像O2O的产品,或者是基于位置的产品,商用车的管理、危化品车管理等。比如说一个综合体里面可能每一层都会有商铺,实际上有很多的产品是有这个定位功能的,但是他现在只有高度,我在手机上搜索的时候,能告诉你所在层有哪一些商铺。PostGIS是一个空间数据管理插件,可以高效的存储多维度数据。

 

 

比如基于这个位置附近搜人,最近我们菜鸟做性能跟踪时,最后压出来的结果让我们很惊讶,PostGIS压出来的性能比Redis好400%。但它差在什么地方呢?它就差在索引的效率上面,所以最后菜鸟选择了使用这个来做轨迹系统。

 

除了民用场景,在军工和科研方面,还要存三格数据等等一系列的数据。许多从互联网发展起来的数据库产品不会考虑这些场景,但是PostGIS来自高校的,有比较深的科研背景,因此这一块应用非常的广泛。几乎全球的宇航局、导航系统、气象系统、天文研究、军工方面涉及空间数据的场景,都在使用PostGIS。

 

 

这个是十二生肖的3D数据,实际上给一个物品做3D的扫描,3D扫描之后除了每一个位置信息之外,还有属性如材质、颜色等,这里面存的不仅仅是位置信息,还有其它的属性在里面,通过pgpointcloud可以把这些扫描值存到一个对象里面。

 

最后还有一个特别重要的功能就是路由的功能,从A到B怎么样提供最优的路径出来,在行进过程中不断优化你的路径。典型的应用场景,比如说物流等。

 

 

60%

 

 

 

1、流式处理

 

 

流式处理的话,刚刚提到了是监控的场景。流式处理每一条上报的监控 ,如果有异常的话,通过异步消息的方式来通知我们的应用程序。另一个非常有趣的例子,就在近日,三体高层架构发起的一次PCC性能大赛,场景是涉及到Facebook的关系,Like的场景,可以查到某一篇文章被Like的次数,或者是查出某一篇文章Like的好友中哪些是我的好友。这个关系说很绕,比赛的设计的目标是30万的请求被Like的次数,还有被哪些人Like。使用流计算的话,查到某一篇文章被Like的次数,查被哪些人Like,均可以达到100万的QPS,查出某一篇文章Like的好友中哪些是我的好友可以达到70万的QPS,超出设计目标,而仅仅使用了PostgreSQL的一个流计算功能。

 

2、Zabbix

 

流计算与异步消息结合,可以达到什么样的效果呢?如果拿Zabbix来做流式监控的话就可以用这种方法。Zabbix原生是主动的询问方式来了解是否发生了异常,很浪费资源。使用这种异步机制,仅仅在真正有问题的时候,才会通知客户端,大大减少了主动问询的无用功开销。

 

 

3、网状关系搜索应用、金融风控、公安刑侦、社会关系、人脉分析

 

 

这里提到了一个关系的图示查询,这个的话之前也写过一篇这样的文章,写得比较详细,就是使用PostgreSQL怎么样做图式搜索。我测了一个一千亿的关系,一亿的用户,每个人有一千条边关系,达到的性能是什么样的,查两个人最短关系路径的时候,要看关系路径有多远,比如说4级以内的话在秒级以内响应,查询N度人脉则可以做到毫秒级的响应。

 

4、相似内容判定、按标签圈人

 

再看一下相似判断,场景是导购平台。现在我有上亿的导购的文章,每一篇文章对应一些导购的商品,当有新的用户发导购文章的话,我得确保他没有盗文,也就是说必须找有没有相似的导购文章,这个事情通过PostgreSQL来解决。

 

 

 

5、图像识别、AR红包

 

 

图象识别比较有意思,你只要把图像的特征传入到数据库里面,数据库就可以帮你做这件事情。只要实现GIN或GIST索引里面特定的几个接口就可以使用索引来检索相似的图片,包括图像相似挖掘也是这样的。这个效率也很高,我有测过大概是五千万的图片,查询相似的图片可以做到毫秒级的响应。

 

这个应用场景是比较有意思的,特别是现在兴起的图搜,在看电视剧时发现包包挺好看的,拍下来搜一下,这个搜一下的过程就是采集这张图片,然后把它的特征值根据数据库反馈给我,告诉哪一个店在卖这个产品。

 

6、Real Sharding(无限制Sharding)

 

 

很多数据库支持Sharding,但是并不是特别的完美,Sharding后的使用体验与单机版本会不一样。这也不能,那也不能,就像你原来的数据库被阉割了一样,对很多人来说很不爽。原来做什么都可以,现在Sharding是不能这样干的,而PostgreSQL 10推出之后,在Sharding这一块有特别多的增强。10做了几件事情,一个是pushdown,就是在下面的数据库里面计算,所以可以干跟原来一样的事情,跨节点交易也是可以做的,包括一致性备份等等。

 

 

另外是多副本,基于事务这个级别,比如说A事务涉及到用户的账目信息,要保证两个副本才可以告诉写成功。而如果你这个事物是日志型的,要求RT比较低的,这时候你只要告诉他落到本地就可以的,这时候只需要写一个副本。这个多副本的功能设计得非常灵活,可以满足混合场景的需求。

 

80%

 

 

 

1、机器学习库(MADlib)

 

再往后80%可以做机器学习,MADlib这个库是MIT与Pivotal共同研发并开源的一个机器学习库,使用起来是SQL的接口。你需要告诉它(UDF)训练集表是哪个,输出训练结果到哪里,使用什么算法等。比如说做数据的分析,关健词的分析等等都可以做。

 

 

2、基因数据处理(存、取、检索;类型、索引、操作符、函数、UDF)

 

接下来还有一些比较奇特的,比如说在数据库里面存基因,基因的数据有比较单一的属性(TOKEN),不同的DNA串,体系了不一样的连接的顺序。使用这个postbis存的话,可以做基因相似的查询等等这样的一些操作,所以也比较有意思。

 

 

 

化学物品也可以存储在数据库中,在数据库中可以模拟化学品的合成,化学品的分析,约束等。

 

3、融合

 

 

融合是指将不同的数据源打通,PostgreSQL的FDW接口,可以访问世界上几乎任何一种的数据源,只要建立一个外部表就可以访问外部数据了,访问接口依旧是SQL接口。

 

FDW在云端有什么样的用处?云端很多的数据是以很多其他的形式存在的,比如说阿里有一个对象的存储OSS,把历史的数据用来做分析,不需要每时每刻查,这些数据做的操作全部是分析型的操作,我们把这种数据存到OSS里面,这时候数据库本身的存储可以缩小,可以压缩你的成本。

 

 

100%

 

 

 

最后100%这里要表达的意思是你可以想象的功能都可以拓展出来。最后几页PPT是阿里云的一些比较大的客户经典的应用场景。比如说这个场景是做网络轨迹分析的,它的数据量达到几百T,有大量数据存在OSS对象存储里面,RDSPostgreSQL与HybridDB PostgreSQL连接OSS的通道是并行的,比如说HybridDB PostgreSQL有一百个节点,每一个节点都可以访问OSS,在做分析处理的时候,吞吐可以做到非常大。做到了计算与存储的分离。

 

 

上面蓝色和灰色的方框是说这个数据库的计算能力有哪一些,能干什么事情,下面是数据库的计算单元,再下面就是你外部存储,你数据可以存在计算单元里面,也可以存储在OSS对象存储里面,取决于数据的热度。当分析好之后,数据可以回流到OLTP数据库中。

 

计算与分离,除了成本上的优势,另一个好处是扩容显得更加从容,因为不再需要move数据了。

 

 

最后这张图表示,数据的入库通道,对应的带宽和时延,用户可以根据实际的需求选择数据的通道。

 

 

Q&A
 

 

Q1:比如说我自拍一个再找相似度,是不存在的,会如何?

A1:关于图片相似度的查询,查询条件中可以设置相似度的阈值,如果你拍的图片根本不存在的话,通过阈值就可以排除,也就是说查询不到结果。不管有没有结果,都是走索引的,所以效率非常高。

    

Q2:把逻辑存放在数据里面,数据库服务器的负载有时候并发量大的时候,负载是不是承受不起?

A2:不管逻辑放在数据库里面还是外面,负载取决于业务量,而业务的增长是可以预估的,不会说突然就暴涨(除了搞活动,但是也能预估),我们回到逻辑放到库里面的那张图,达到的TPS实际上是更高的,如果逻辑在数据库外面10万的成本达到30万TPS,同样的成本放到数据库里面可以达到100万的TPS,实际上放在外面时引入了更多的损耗,所以你怎么看待这个问题呢?10万块钱已经帮你做了30多万的事情。

PPT下载链接:http://pan.baidu.com/s/1jIHqqDw

最新评论
访客 2023年08月20日

230721

访客 2023年08月16日

1、导入Mongo Monitor监控工具表结构(mongo_monitor…

访客 2023年08月04日

上面提到: 在问题描述的架构图中我们可以看到,Click…

访客 2023年07月19日

PMM不香吗?

访客 2023年06月20日

如今看都很棒

活动预告