Aerospike Helps Xinyi Internet Advertising Precisely Place Shared Playback

上周,新义互联全球高级架构师黄驰铭给我们分享了Aerospike 助力广告精准投放的案例。Aerospike在大数据领域能在提高效率的同时有效降低总体拥有成本,在互联网广告行业有着非常广阔的应用场景。有些朋友由于时间关系错过了分享,没有关系,我们有新鲜出炉的分享视频回放。

大家好,我今天讲一讲作为用户我们是怎么接触到Aerospike,怎么使用,Aerospike解决了哪些问题,我们的使用感受和思考。

新义互联是一家做在线广告的公司,专注于移动广告智能投放和移动媒体变现服务,支持全场景广告投放和变现。

今天的内容包括需求背景,我想讲一下当时的业务需求,让大家可以理解Aerospike应用场景。

第二个是技术选型,需求明确以后,我们会评估各种方案,看是否值得一试。相信大多数公司都不会只给自己留唯一一种方案。

第三点是生产环境验证,不同的方案需要在生产环境测试验证比较,从而选出最优方案。因为团队里面每个人都会有自己的偏好,有可能觉得自己的方案最好,所有要用真正的数据说话比较好。

第四点我想讲下我们使用Aerospike额外的收获,因为它不仅满足了我们当时特定的需求,还让我们有更大的想象空间,有更多时间去优化其他的业务,这里我想挑其中一个优化点来说。这个对做在线广告的用户有所启发。

需求背景

我们的需求非常简单,20亿的设备号,设备号是imei和Android ID。主要是安卓平台的设备号。Md5到明文的映射(20亿imei/android_id md5>明文映射需求)需求很简单,但做起来很难。

新义互联的主要业务是把媒体方的请求转化为广告主,广告主会根据用户的设备号决定是否响应广告,然后展示在媒体应用上面。从去年开始,很多媒体都因为政策原因,不再给我们发明文设备号,只能发送设备号的md5,但是广告主不管这些,他们只需要明文设备号来判断用户是否是目标用户,然后决定是否响应广告。

这意味着我们只是简单的将媒体方的请求转化给广告主,广告主是不会给我们响应广告,这样我们就不会有任何收入。

但这些请求肯定会耗费服务器资源,这些都是成本,所以我们需要做的是如何合理的把这些流量利用起来,把媒体和设备号md5-反查出明文的设备号,然后再转换给广告主,拿到广告。

但是我们知道md5是单向的,是不可能实时解码的,好在我们之前也积累了很多明文设备号,并且都保存起来,所以这件事情也不太难,我们只需要把这些设备号取出来,构建一个映射表,从md5映射到明文就可以了,无非是一个hash表格,只不过这个表格比较大,可能需要存到不同服务器,构成一个集群。这些很多KV数据库都可以做到,但是我们还有几个挑战:

1读取延迟要低于5毫秒,这个和我们业务有关,媒体发一个请求过来我们服务端处理时长要低于10毫秒。因为我们其他的处理时长很短,所以可以把这10毫秒全部留给imei和Android这两个设备号的反查。每个可以占用5毫秒。

2 我们数据量很大,当时我们积累了20多亿设备号,到今天已经32亿了。

3 成本不能太高,成本肯定不能比收入高。

技术选型

接下来讲技术选型初选,前面讲过很多KV数据库都可以实现需求,这是真的。我这里只列出了5个,其实这个列表可以很长,但是我们没有那么多精力。

可以看到Redis,Cassandra,Memcached都是内存方案,数据存在内存。由于我所在的技术团队不大,大部分会使用云服务,恰好我们使用的阿里云服务是有Redis集群的,所以阿里云提供的Redis集群是我们的首选方案。

SSDB是一个兼容Redis协议(这个很友好),数据可以保存在磁盘上,但是内存占用比较低,可以降低我们的成本,但是我仔细看了他的官方文档,感觉他还处于Redis很早期的那种集群架构年代,没有一个像样的高可用方案。大家都是采用master-slave架构,通过replication把主节点上面的数据复制到从服务器上面,而且配置繁琐,后期运维成本很高,我们也没有太多时间,所以把他排除。

Aerospike同样把所有数据保存在磁盘上,可以降低成本。Aerospike对于很多用户来说非常简单,架构很漂亮,这背后肯定是Aerospike内部技术实现复杂度的提升,复杂的东西自己做,简单的接口给用户,这是非常不容易的事。

我们可以看看Aerospike的架构:他是无共享架构,而且不依赖任何其他服务,比如Zookeeper,ETCD之类,他使用Gossip算法组建集群,然后去选primary或者replica这种节点,使得数据均匀的,随机分配在所有节点上,不会有数据热点,这个对运维和部署来说非常友好。

我自己总结了Aerospike在架构上的几个优点:

1 每个节点都是一样的,没有多种节点类型。很多开源产品不会考虑那么多,会有很多种节点类型,这个会造成部署和运维的复杂。但是Aerospike每个节点都一样。

2 没有单点故障,不需要负载均衡,不需要代理。

3 可以很轻松的横向扩展,非常简单,加一个机器上线就行,不需要执行任何命令。

4 一次网路调用就能拿到数据,因为有网络开销,所有一次肯定比两次好,能省则省。

以上四个优点每一个单独拿出来,都觉得没什么特别,但是同时具备这4点就很厉害。

所以我们最后技术选型就是阿里云Redis集群和Aerospike企业版。

Aerospike是需要购买License的,不便宜,为什么选企业版,而不是社区版?我最开始以为社区版支持全闪存,即所有数据都保存在SSD里,后来部署才发现社区版不支持。当时准备放弃,因为之前没有用过企业版软件的经验,但已经投入了一周时间看文档和评估,再加上另外三个原因:

1, 阿里云Redis集群价格实在太贵,当我评估Aerospike企业版的时候,阿里云Redis集群已经上线,但价格贵,说不定可以优化。

2,企业版7x24技术支持很有必要。我们可以直接和原厂工程师沟通,比如肖工。他们会合理的帮我们规划业务和集群,出问题也可以直接找工程师解决,这个很有必要。

3,企业版支持快速重启,利用共享内存可以在几十秒内重启完毕。但是社区版重启不一样,他需要从SSD重建索引,几百G数据重启一次需要几个小时,这个很难接受,对我们业务影响很大。

所以我联系Aerospike 销售要了报价和企业试用版,部署企业版很快,1到2天就完成,但是部署前我已经花了一周来看文档。

生产环境验证

接下来要到生产环境去验证。我所在的技术团队不大,选择阿里云Redis集群,当时用了2个256G的集群,每个月是38,400元人民币,他确实可以满足我们的需求,读取延迟只有2.5毫秒,这个价格和成本是可以接受的。

但当我测试了Aerospike以后就立刻把阿里云Redis集群给放弃了,因为Aerospike读取延迟太低,只需要500微秒,就是0.5毫秒,而且阿里云Redis里面用了360G内存,这个360G内存存的可能只是一份数据,我觉得磁盘可能还存有一些数据,所以算起来空间占用应该是700G左右,但是阿里云Redis监控我们看不到磁盘占用,所以这是我的猜测。

我部署Aerospike的时候设置的replication factor是2,所以数据存的是2份,但是这里的Aerospike的空间占用只有290G,这个大大低于Redis接近700G,这个空间占用对我们非常重要,因为这都是成本。因为Aerospike是按数据量大小来收费,到今天我们的数据是450G,加上其他业务数据已经有700G了,而且一直在增长。

Aerospike非常快,是阿里云Redis集群的5倍,这个大大超出我们的期望。如果我们未来有其他相同映射的需求,我们还可以多查询几次,至少10次没问题。

但是Redis的2.5毫秒,基本就限制了我们只能查2-3次,当然我们现在还不需要查10次,Redis还是能满足需求,但有一天我们真的需要查10次的时候,Redis就无法满足。

关于成本,我这里写的50%,Aerospike是按年度订阅,价格算起来和阿里云Redis集群差不多,但是Aerospike在同样价格条件下存储的数据是Redis的两倍,甚至更多,随着我们业务量的提升,成本只有阿里云Redis的一半甚至更低。每个人都有自己的计算方式,有的人会说我就用这么多为什么要去买1T的license,所以这里仅表达个人观点。

关于稳定性,我这里用了问号,因为部署上线后我就没管过他,一直没问题,我不清楚未来一年是否会出问题,我希望没有问题。前段时间我们做了一次整个集群的升级和迁移,因为之前我们是部署在的是阿里云的VM里面,现在是升级到4.9并且迁移到K8s上面,迁移非常顺利,这是我同事努力的结果。

我认为整个集群迁移到K8s都没问题的话,稳定性应该是非常好的。最近618我们没去动它,因为618期间是我们公司业务比较大的时候,我们打算过几天再升级到5.0,可以享受更好的性能。

再说下Aerospike技术支持,我之前发过几次邮件问问题,响应非常及时,也很专业,几分钟就得到回复。当然对用户的要求也很高,需要很仔细的看各种文档和资源。每次沟通都有新的收获,能学到很多知识。

额外收获

接下来我想说下额外的收获,当我们的基础设施成本高的时候,很多业务优化我是不会去想的,想了也不会去做。因为投入时间和精力去优化,往往发现成本比收入还高。我不知道有多少观众是做在线广告的,无论是广告主还是媒体,接下来我讲的都会对大家有帮助。

大家可以看下我们的上报链接,上面是优化之前的,下面是优化之后的。为什么要优化上报链接?有三个原因:

1,有些媒体不能接受上报链接里面有imei或者Android等关键字

2,有些媒体对上报链接长度有限制,比如广点通限制长度是1024字符,但是上面的链接包含了快两千个字符。

3, 有些媒体还会对上报链接进行解码和编码操作,导致链接错误,双方数据有差异,这个时候我们需要花很多时间去排查问题,以前这个问题很让我头痛,但现在已经没有任何问题。

接下来说说怎么优化,非常简单,只需要借助Redis或Aerospike做存储,Key是request ID,value值是链接里面的这些信息,媒体请求我们的时候我们再根据这个request ID去放,所有的数据查出来就可以了。

优化之后的上报链接大家可以看到只有80多个字符,可以满足所有特殊媒体的人以及特殊要求,再也不用担心媒体处理这个上报链接,从根本上消除这个问题,为我们节省很多时间。

我当时看到这个功能也用了Redis和Aerospike,但是测试结果是这样的:同样一天的数据,128G,Redis存不下,而Aerospike只用了85G。读写速度也是Redis的5-10倍,利用Aerospike开发这个功能代码甚至还会更少,大概只有二分之一。

几点思考

接下来我想给大家一个思考题,为什么Redis所有数据都存在内存里面,Aerospike存在SSD上,从存储介质的角度来看,内存是要比SSD快10倍的,但为什么Redis的表现会更差一点?这个问题我现在也没有答案,但我会一直去探索。

我有些自己的想法想和大家一起探讨:

1,阿里云的Redis集群是proxy架构,一个proxy后面有几十个Redis节点,每个节点只有2-4个CPU, Aerospike服务器是16核的,并且频率更高一点,也许你会说这么比较不公平,但是就算把Redis部署到同样的机器上,可能也没有用,因为Redis支持多线程比较差,它现在发布的6.0也许会好点,但是我没有去测试。

2,Aerospike做了很多SSD的读写优化,无论是直接读写裸设备,还是读写文件系统,当他读文件系统他会利用page cach技术去加速对磁盘的访问。总结就是Aerospike对多线程的支持很好,无论一个机器多好,有多少个CPU核心,他都可以完全利用上,而Redis不一定。Aerospike对SSD的读写做了很多优化,当系统资源充足的时候,读写SSD的速度是可以媲美内存的。

3,Aerospike有很多学习资源都是公开的,关于SSD的优化专利和白皮书。

这是我要分享的内容,最后请大家关注我们的公众号,我们不定期会有相关文章分享。

最后总结,Aerospike大大超出我的预期,我前面说的不是他的全部,Aerospike还有很多高级功能我们还没用上,比如之前提到的XDR(跨数据中心复制),还有Rack awareness(机架感知),这个功能是可以把数据存到不同的机架上面,有这两个功能他可以把同一份数据保存到不同的机架,同步到不同的数据中心,就算一个机架发生物理毁灭,数据也不会丢失,客户端可以通过配置优先读取当前机房数据,这个延迟非常低。

我希望我们的业务量会不断增长,数据量提升数倍,这样我们就能用到这两个功能。感谢大家!

Leave a Reply