应用实战:从Redis到Aerospike,咱们踩了这些坑

个推专一为开发者们提供消息推送服务多年。经过个推SDK,手机终端与服务器创建长链接,维持在线状态。然而在网络异常等状况下,消息没法实时送达到终端用户,于是推送服务器创建了一份离线消息列表,以待用户从新登陆时,进行消息的下发。这部分数据存储在个推Redis集群,整个集群包括主从共百余个实例,key的数量在10亿级别,存储空间在T级别,带来了必定的维护成本和运维挑战。做为个推的后端开发工程师,咱们也一直在寻找高性价比的方案。html

个推整个集群的QPS在百万级别,若选择使用Aerospike,对比实测下来,咱们发现单台搭载单块Inter SSD 4600的物理机,能够达到接近10w的QPS,即几十台机器就能够知足现有的需求,并可以支撑将来较长一段时间的业务需求。数据库

Aerospike的优点后端

Aerospike是一个高性能、可扩展、可靠性强的NoSQL解决方案,支持RAM和SSD做为存储介质,并专门针对SSD特殊优化,普遍应用于实时竞价等实时计算领域。官方保证99%的操做在1ms内完成,并提供集群数据自动Rebalance、集群感知客户端等功能,且支持超大规模数据集(100T级别)的存储。服务器

做为KV存储,Aerospike提供多种数据类型,其操做方式和Redis比较相似。除基础功能以外,Aerospike还支持AMC控制台、API等多种监控方式,有集群QPS、健康度、负载等多项监控指标,对运维比较友好。支持集群内数据的自动Rebalance,和Redis集群方案相比,维护成本降低很多。网络

本文主要作一些Aerospike灰度部署、使用方面的经验分享,但愿对正在调研或者已经准备使用Aerospike的读者提供一些参考。此外,灰度的理念并不限于Aerospike自己,对其余基础组件的迁移和规划,也可以带来必定的借鉴意义。并发

数据模型说明运维

 

Aerospike采用无模式存储,数据模型相似RDBMS,于是在理解与使用上相对亲切:异步

每一个namespace包含多个set,每一个set包含多条record,每一个record包含多个bin(数据库列),可经过索引key来查询record。不一样的业务可使用同一个集群的不一样namespace来做作资源隔离,从而实现资源池化、最大化利用资源的目的。ide

 

灰度上线流程性能

个推在离线消息列表存储这项业务中使用了较大规模的Redis集群。咱们前后调研了ssdb、pika等支持Redis协议的磁盘存储,总体计算下来,Aerospike的性价比最高。

前期咱们结合线上场景模拟实际读写比例(分析线上业务,咱们发现写和读大体比例在1:1 ~ 1:2之间)进行压测,对可行性进行评估和验证,而后进行投产规划。

线上业务比较庞杂,直接全量切到Aerospike不太现实,风险也比较大。测试网模拟验证难以暴露出生产环境下可能出现的问题,所以咱们将整个上线流程划分为观察阶段和灰度阶段。观察阶段顾名思义,原Redis集群仍然承担线上读写业务,只是将一样的流量复制一份导入Aerospike,来进行真实压力验证; 灰度阶段将线上业务逐步切到Aerospike集群,扩大灰度保证集群稳定运行至业务彻底切到Aerospike。两个阶段具体操做以下:

观察阶段: Redis操做成功后,对Redis的读写操做以异步方式同步到Aerospike,Aerospike不承担具体业务。下一步是数据双写Redis和Aerospike。该阶段主要观察两边数据是否一致,Aerospike压力等。同时观察阶段能够进行节点重启、集群扩容等运维操做,评估运维成本,优化配置等。这里可以使用AMC页面控制台、监控API来监控集群状态,客户端调用部分记录必要日志和监控信息。

 

灰度阶段: Aerospike开始承担部分应用和任务的离线消息列表存储。灰度阶段Redis和Aerospike数据双写双清,保持热备状态,直至Redis数据彻底切换到Aerospike并稳定运行一段时间。

 

观察阶段很是重要,基本上是对整个方案可行性进行线上评估。这个阶段观察点分为客户端(AS-Client)和服务端(AS-Server)两部分。客户端主要观察:

1.使用metrics监控客户端请求响应耗时,利用一段时间内的请求耗时百分比分布(50%, 90%, 99%, 99.9%),评估系统SLA。

2.监控读写成功、失败等状况的计数。

3.将慢日志阈值设定为50ms,统计高峰期和日常时段的慢日志状况。

4.异步写Aerospike队列监控,合理调整队列大小。

服务端主要观察:

1.集群的健康度。

2.磁盘和内存占用状况,内存空间/磁盘空间比例。

 

3.机器IO负载、CPU负载、磁盘碎片化程度等信息。

4.集群吞吐量,读写TPS是否能与线上Redis集群至关。

 

5.数据一致性检查。如何检查观察阶段和灰度阶段两份数据的一致状况?逐key比对差别在性能上难以知足要求。考虑数据彻底一致状况下Redis查出的数据应该和Aerospike查出来的数据彻底相同,因此抽样记录Redis和Aerospike的数据查询结果记录到日志,对比分析1分钟、5分钟、30分钟、1小时内不一致数据占比。若是线上Key的数量在10亿级别,即使只检查出万分之一的差别,那么不一致的状况也很显著了。这种状况下,就须要排查引起不一致状况的缘由并解决。

维护性方面主要考虑到集群数据自动Rebalance会带来必定的性能降低,可能对用户体验有较大影响,结合咱们的经验,模拟了一些典型的运维场景:

1.模拟单节点故障致使的集群Rebalance对系统性能的影响。

2.模拟集群扩容致使的集群Rebalance对系统性能的影响。

3.根据对线上业务的影响,计算白天和晚上集群的Rebalance速度,同时支持cron job更新。

4.节点重启。

5.增长SSD挂载。

6.相关配置的优化等。

总结一下,完整的上线流程分为如下几步:

 

0.模拟线上环境压测,进行可行性验证。

1.将Aerospike客户端封装成类Redis的接口,添加必要日志、监控项,对Bin的有效性检查等。

2.消息服务集成Aerospike客户端,须要的功能包括: Aerospike异步读写,业务数据源切换,流量过滤等。

3.QA功能验证。

4.申请资源,线上部署Aerospike集群。

5.集成Aerospike功能的消息服务上线。

6.观察阶段验证经过后,进入灰度阶段,直至最终上线或中途撤回。

经验总结

在Aerospike使用过程当中,咱们遇到了一些问题和挑战,总结为下面几点:

1.Aerospike开启single-bin的模式会节省占用空间。

2.Aerospike不会存储原始key,实际索引的是原始key的一个20字节hash值,若是业务须要使用原始key则必须另外设置bin存储。即使key和value值的字节数较少,但key自己占据20个字节,于是实际占用的空间会比较大。

3.Aerospike在节点宕机或是增减节点时会Rebalance数据,这个过程会影响对外服务质量。但Rebalance速度能够控制,于是须要在保证服务质量和集群快速恢复两者间作权衡。

4.社区版本集群每次重启都要重建索引,而后加载到内存,这会致使速度比较慢。namespace须要在配置文件中指定,于是最好能按业务划分,预先分配好未来可能用到的namespace,减小没必要要的重启。

5.由于SSD自己存在碎片和写入放大的问题,实际使用中,咱们发现若磁盘空间使用量在50%左右,性能降低会比较严重。故能够结合实际业务优化碎片整理相关参数。

6.Aerospike对HotKey有限制,于是频繁对一个key读写时,会返回HotKey错误(errorcode 14) 。服务端能够经过增大 transaction-pending-limit配置来提升对同一个key操做的并发量,它的默认为20,值为0时表示不限。增大该配置可能会下降必定性能。客户端可能须要对该异常增长重试处理,但重试可能会进一步增大HotKey的风险。

7.这种基础组件的更迭必定要尽量使用线上流量作压力检验,从而尽早暴露潜在问题。

8.观察阶段也要评估运维成本,避免从一个坑跳进另外一个坑。

9.使用过程当中还须要注意Aerospike的一些固有限制,如一个namespace最多有1023个set 、bin名字长度最多14个单字节字符 、一个namespace最多支持64块SSD 等等,具体可参考:aerospike_known_limitations

结语

Aerospike做为一个大容量的NoSql解决方案,并未在国内厂中普遍商使用。它适合对容量要求比较大,QPS相对低一些的场景,必定程度上能够节省TCO。支持命令上,Aerospike和Redis比较相像,业务迁移过来也比较容易。它自然地支持集群部署,对监控和运维支持比较友好。尽管拥有这么多优良特性,但技术选型时仍是要持审慎态度,预先评估是否符合本身的业务场景,性能和成本是否可以知足要求等。在官方的某些测试场景下,它的性能比Redis还要高,实际上由于SSD自己的限制,大部分状况下,它在QPS方面与Redis差距较大。最后,上线前务必通过线上流量验证,用灰度方式处理实际线上业务,最小化影响用户体验。

相关文章
相关标签/搜索