快捷搜索:

数据偏移、分区陷阱…我们这样避开DynamoDB的5个

择要:本文主要先容作者所在团队在详细营业中所碰到的寻衅,基于这些寻衅为何终极选型应用Amazon DynamoDB,在实践中碰到了哪些问题以及又是若何办理的。文中不会具体评论争论Amazon DynamoDB的技巧细节,也不会涵盖Amazon DynamoDB的整个特点。

DynamoDB是Amazon基于《Dynamo: Amazon’s Highly Available Key-value Store》实现的NoSQL数据库办事。它可以满意数据库无缝的扩展,可以包管数据的持久性以及高可用性。开拓职员不必劳神关注DynamoDB的掩护、扩展、机能等一系列问题,它由Amazon完全托管,开拓职员可以将更多的精力放到架构和营业层面上。

背景与寻衅

TalkingData移动广告效果监测产品(TalkingData Ad Tracking)作为广告主与媒体之间的一个广告投放监测平台,天天必要接管大年夜量的推广样本信息和实际效果信息,并终极将实际的效果归因到推广样本上。

举个例子,我们经由过程手机某新闻类APP浏览信息,会在信息流中看到穿插的广告,广告可能是翰墨形式、图片形式、视频形式的,而不管是哪种形式的广告它们都是可以和用户交互的。

假如广告推送对照精准,刚好是用户感兴趣的内容,用户可能会去点击这个广告来懂得更多的信息。一旦点击了广告,监测平台会收到这一次用户触发的点击事故,我们将这个点击事故携带的所有信息称为样本信息,此中可能包孕点击的广告滥觞、点击广告的光阴等等。平日,点击了广告后会向导用户进行相关操作,比如下载广告保举的APP,当用户下载并打开APP后,移动广告监测平台会收到这个APP发来的效果信息。到此为止,对付广告投放来说就算做一次成功转化。

移动广告监测平台必要接管源源赓续的样本信息和效果信息,并反复、不绝的实时处置惩罚一次又一次转化。对付监测平台来讲,它的责任重大年夜,不能多记录,也不能少记录,假如转化数据记多了广告主必要多付广告费给媒体,记少了媒体会有吃亏。这样就为平台带来了几大年夜寻衅:

数据量大年夜

有的媒体为了利益最大年夜化可能会采取非正常手段制造假的样本,孕育发生“虚假流量”,以是广告监测平台除了会收到真实用户样本外,也会收到大年夜量造假的样本,影响正常的监测和归因。在最“猖狂”的时刻,我们的平台会在一天内收到40亿+的点击样本事故哀求。要知道,这些点击样本事故是要保留下来作为后续效果归因用的,而且样本有效期大年夜不相同,从最短12小时到最长90天不等。

数据量弗成预知

对付广告主的大年夜推、利用市廛竞价排名等一系列的推广,会导致突发大年夜量样本数据流入。面对这些流量弗成预知的环境,我们仍要包管系统的精确、稳定、实时。

实时处置惩罚

广告主依附广告监测平台实时处置惩罚的结果来调剂广告推广策略。是以广告监测平台必要支持数据实时处置惩罚,才能为广告主更快的优化推广策略供给有力支撑。与此同时,广告监测平台的处置惩罚结果也要实时回传给媒体方以及广告主。可以看到,准确性和实时性是系统必须要满意的基础前提。

样本存储

我们的营业最核心的功能便是归因,我们要明确例如用户下载打开APP的这个转化效果是由哪一个推广活动样本带来的——也便是上图中的第7步,当用户安装APP后,监测平台要对应找到第1步中样本所在推广活动,这个是一个查询匹配的历程。

对付宏大年夜的归因样本数据,有效期又各不相同,我们应该如何存储样本才能让系统快速归因,不影响实时结果,这也是一个很大年夜的寻衅。

最初形态

在2017年6月前我们的营业处置惩罚办事支配在机房,应用Redis Version 2.8存储所有样本数据。Redis应用多节点分区,每个分区以主从要领支配。在最开始我们Redis支配了多个节点,分成多个分区,每个分区一主一从。刚开始这种要领还没有呈现什么问题,但跟着用户设置的样本有效期加长、监测样本增多,当时的节点数量徐徐已经不敷支撑营业存储量级了。假如用户监测推广量一旦暴增,我们系统存储将面临崩溃,营业也会瘫痪。于是我们进行了第一次扩容。

因为之前的支配要领我们只能将Redis的多个节点翻倍扩容,这统统都必要工资手动操作,并且在此时代我们想尽各类法子来保护用户的样本数据。

这种支配要领跟着监丈量的增长以及用户设定有效期变长会越来越不堪重负,当呈现弗成预知的突发量时就会孕育发生严重的后果。而且,手动扩容的要领轻易掉足,及时性低,资源也是翻倍的增长。在当时因为机械资本有限,不仅Redis必要扩容,广告监测平台的一系列办事和集群也必要进行扩容。

化解寻衅

颠末评论争论和评估,我们抉择将样本处置惩罚等办事迁移到云端处置惩罚,同时对存储要领从新选型为Amazon DynamoDB,它能够满意我们的绝大年夜部分营业需求。颠末布局调剂后系统大年夜概是下图的样子:

应对数据量大年夜且弗成预知

我们的平台必要吸收推广监测连接哀求,并进行持久化用于后续的数据归因处置惩罚。理论上来说系统进来若干广告监测数据哀求,DynamoDB就能存若干数据,只必要一张表就可以存储随意率性数量级的数据。不用关心DynamoDB扩容问题,在系统运行时我们感知不到存储正在扩容。这也是Amazon官方传播鼓吹的完全托管、无缝扩展。

高可用

Amazon DynamoDB作为存储办事供给了极高的可用性,对付写入DynamoDB的整个数据都邑存储到固态硬盘中,并且自动同步到AWS多个可用区,以达到数据的高可用。这些事情同样完全由Amazon DynamoDB办事托管,应用者可以将精力放到营业架构及编码上。

实时处置惩罚

Amazon DynamoDB供给了极高的吞吐机能,并且支持按秒维度设置设置设备摆设摆设随意率性级其余吞吐量。对付写多读少的利用可以将每秒写入数据的数量调剂成1000以致更高,将每秒读取的数量低落到10以致更少。

吞吐量支持应用者随意率性设定,在设定吞吐量时除了可以随时在Web治理后台调剂外,还可以经由过程DynamoDB供给的客户端动态调剂。比如系统在运行时写入能力不够了,我们可以选择到Web治理后台手动上调或在代码中经由过程调用客户端API的要领实现自动上调。应用客户端动态调剂的要领会让系统具备较高的紧缩能力,同时还可以包管数据的实时处置惩罚,系统数据流量变高了就动态调剂上去,数据流量变低了再动态调剂下来。比拟手动调剂来看,动态调剂的要领更为机动。

基于以上几点,我们觉得Amazon DynamoDB可以很轻松的支撑系统的核心营业能力。对付营业侧必要做的便是,收拾好营业逻辑把数据写到DynamoDB就可以了,剩下的就交给DynamoDB去做。

此外还有:

TTL

我们使用了Amazon DynamoDB供给的TTL特点治理那些有生命周期的数据。TTL是对表中要过时的数据设置特准光阴戳的一种机制,一旦光阴戳过时DynamoDB在后台会删除过时的数据,类似于Redis中的TTL观点。借助TTL的能力,我们削减了很多营业上不需要的逻辑鉴定,同时还低落了因存储量带来的资源。

在我们的营业中没有启用流来捕获表的动作,但我们觉得DynamoDB流是一个异常好的特点,当存储在DynamoDB表中的数据发生变化(新增、改动、删除)时,看护到相关的办事/法度榜样。比如我们改动了一笔记录的某个字段,DynamoDB可以捕获到这个字段的变化,并将变化前后的结果编写成一条流记录。

实践出真知

我们在应用一些开源框架或办事时总会碰到一些“坑”,这些“坑”着实也可以理解为没有很好的理解和应对它们的一些应用规则。DynamoDB和所有办事一样,也有着它自己的应用规则。在这里主要分享我们在实际应用历程中碰到的问题以及办理法子。

数据偏移

在DynamoDB中创建表时必要指定表的主键,这主要为了数据的独一性、能够快速索引、增添并行度。主键有两种类型,「零丁应用分区键」作为主键和「应用分区键+排序键」作为主键,后者可以理解为组合主键(索引),它由两个字段独一确定/检索一条数据。DynamoDB底层根据主键的值对数据进行分区存储,这样可以负载均衡,减轻零丁分区压力,同时DynamoDB也会对主键值考试测验做“合理的”分区。

在开始我们没有对主键值做任何处置惩罚,由于DynamoDB会将分区键值作为内部散列函数的输入,其输出会抉择命据存储到详细的分区。但跟着运行,我们发明数据开始呈现写入偏移了,而且异常严重,带来的后果便是导致DynamoDB表的读写机能下降,详细缘故原由在后面会做具体评论争论。发明这类问题之后,我们斟酌了两种办理法子:

以是我们选择了第二种措施,调剂营业代码,在写入时将主键值做哈希,查询时将主键前提做哈希进行查询。

自动扩容潜规则

在办理了数据偏移之后读/写机能规复了,然则运行了一段光阴之后读写机能却再次下降。查询了数据写入并不偏移,当时我们将写入机能提升到了6万+/秒,但没起到任何感化,实际写入速率也就在2万+/秒。着末发明是我们的分区数量太多了,DynamoDB在后台自动掩护的分区数量已经达到了200+个,严重影响了DynamoDB表的读写机能。

DynamoDB自动扩容、支持用户随意率性设定的吞吐量,这些都是基于它的两个自动扩容规则:单分区大年夜小限定和读写机能限定。

单分区大年夜小限定

DynamoDB会自动掩护数据存储分区,但每个分区大年夜小上限为10GB,一旦跨越该限定会导致DynamoDB拆分区。这也恰是数据偏移带来的影响,当数据严重偏移时,DynamoDB会默默为你的偏移分区拆分区。我们可以根据下面的公式谋略分区数量:

数据总大年夜小 / 10GB 再向上取整 = 分区总数

比如表里数据总量为15GB,15 / 10 = 1.5,向上取整 = 2,分区数为2,假如数据不偏移平均分配的话两个分区每个存储7.5GB数据。

读写机能限定

DynamoDB为什么要拆分区呢?由于它要包管用户预设的读/写机能。怎么包管呢?寄托将每个分区数据节制在10G以内。另一个前提便是当分区不能满意预设吞吐量时,DynamoDB也会将分区进行扩充。DynamoDB对付每个分区读写容量定义如下:

写入容量单位

写入容量单位(WCU:write capacity units),以每条数据最大年夜1KB谋略,最大年夜每秒写入1000条。

读取容量单位

读取容量单位(RCU:read capacity units),以每条数据最大年夜4KB谋略,最大年夜每秒读取3000条。

也便是说,一个分区的最大年夜写入容量单位和读取容量单位是固定的,跨越了分区最大年夜容量单位就会拆分区。是以我们可以根据下面的公式谋略分区数量:

(预设读容量/3000)+(预设写容量/1000)再向上取整 = 分区总数

比如预设的读取容量为500,写入容量为5000,(500 / 3000) + (5000 / 1000) = 5.1,再向上取整 = 6,分区数为6。

必要留意的是,对付单分区跨越10G拆分后的新分区是共享原分区读写容量的,并不是每个表零丁的读写容量。

由于预设的读写容量抉择了分区数量,但因为单分区数据量达到上限而拆出两个新的分区。

以是当数据偏移严重时,读写机能会急剧下降。

冷热数据

孕育发生上面的问题是因为我们一开始是单表操作。这样就算数据不偏移,但跟着光阴推移数据量越来越多,自然拆出的分区也越来越多。

是以,我们根据营业做了合理的拆表、设定了冷热数据表。这样做有两大年夜好处:

提升机能

这一点根据上面的规则显而易见,热表中数据量不会持续无限增长,是以分区也稳定在必然数量级内,包管了读写机能。

低落资源

无谓的为单表增添读写机能不仅效果不显着,而且用度也会急剧增高,应用资源的增添对付谁都是无法吸收的。DynamoDB存储也是必要资源的,以是可以将冷表数据存储到S3或其他持久化办事中,将DynamoDB的表删除,也是低落资源的一种要领。

表限定

表对付数据的大年夜小以及数量并没有限定,可以无限定的往一张表里写入数据。但对付AWS的一个账户,每个DynamoDB应用区域的限定为256张表。对付一个公司来说,假如共用同一个账号的话可能会存在创建表受限的风险。以是假如启用了冷热表策略,除了删冷表低落资源外,也是对256张表限定的一种办理法子。

属性名长度

上面提到了写入单位每条数据最大年夜1KB、读取单位每条最大年夜4KB的限定。单条数据的大年夜小除了字段值占用字节外,属性名也会占用字节,是以在包管可读性的条件下应只管即便缩减表中的属性名。

总结

DynamoDB的应用也是存在资源的,主要体现在写入和读取的用度。我们自己研发了一套按照实际流量实时调剂读、写上限的策略。跟着成长DynamoDB也推出了Auto Scaling功能,它实现了自定义策略动态调剂写入与读取上限的能力,对付开拓者来说又可以省去了不少研发精力。今朝我们也有部分营业应用了Auto Scaling功能,但因为该功能的限定,实际应用上动态调剂的实时性略显欠缺。

作者:TalkingData 史天舒

您可能还会对下面的文章感兴趣: