高并发大容量NoSQL解决方案探索

大数据时代,企业对于DBA也提出更高的需求。同时,NoSQL做为近几年新崛起的一门技术,也受到愈来愈多的关注。本文将基于个推SRA孟显耀先生所负责的DBA工做,和大数据运维相关经验,分享两大方向内容:1、公司在KV存储上的架构演进以及运维须要解决的问题;2、对NoSQL如何选型以及将来发展的一些思考。web

据官方统计,截止目前(2018年4月20日)NoSQL有225个解决方案,具体到每一个公司,使用的都是其中很小的一个子集,下图中蓝色标注的产品是当前个推正在使用的。后端

NoSQL的由来缓存

1946年,第一台通用计算机诞生。但一直到1970年RDMBS的出现,你们才找到通用的数据存储方案。到21世纪,DT时代让数据容量成为最棘手的问题,对此谷歌和亚马逊分别提出了本身的NoSQL解决方案,好比谷歌于2006年提出了Bigtable。2009年的一次技术大会上,NoSQL一词被正式提出,到如今共有225种解决方案。服务器

NoSQL与RDMBS的区别主要在两点:第一,它提供了无模式的灵活性,支持很灵活的模式变动;第二,可伸缩性,原生的RDBMS只适用于单机和小集群。而NoSQL一开始就是分布式的,解决了读写和容量扩展性问题。以上两点,也是NoSQL产生的根本缘由。网络

实现分布式主要有两种手段:副本(Replication)和分片(Sharding)。Replication能解决读的扩展性问题和HA(高可用),可是没法解决读和容量的扩展性。而Sharding能够解决读写和容量的扩展性。通常NoSQL解决方案都是将两者组合起来。架构

Sharding主要解决数据的划分问题,主要有基于区间划分(如Hbase的Rowkey划分)和基于哈希的划分。为了解决哈希分布式的单调性和平衡性问题,目前业内主要使用虚拟节点。后文所述的Codis也是用虚拟节点。虚拟节点至关于在数据分片和托管服务器之间创建了一层虚拟映射的关系。运维

目前,你们主要根据数据模型和访问方式进行NoSQL分类。tcp

个推经常使用的几种NoSQL解决方案分布式

个推Redis系统规模以下图。下面介绍一下运维过程遇到的几个问题。函数

首先是技术架构演进过程。个推以面向APP开发者提供消息推送服务起家,在2012年以前,个推的业务量相对较小,当时咱们用Redis作缓存,用MySQL作持久化。在2012-2016年,随着个推业务的高速发展,单节点已经没法解决问题。在MySQL没法解决高QPS、TPS的状况下,咱们自研了Redis分片方案。此外,咱们还自研了Redis客户端,用它来实现基本的集群功能,支持自定义读写比例,同时对故障节点的监测和隔离、慢监控以及每一个节点健康性进行检查。但这种架构没有过多考虑运维效率的问题,缺乏运维工具。

当咱们计划完善运维工具的时候,发现豌豆荚团队将Codis开源,给咱们提供了一个不错的选项。


个推Codis+的优点

Codis是proxy-based架构,支持原生客户端,支持基于web的集群操做和监控,而且也集成了Redis Sentinel。能够提升咱们运维的工做效率,且HA也更容易落地。

可是在使用过程当中,咱们也发现一些局限。所以咱们提出了Codis+,即对Codis作一些功能加强。

第1、 采用2N+1副本方案,解决故障期间Master单点的问题。

第2、Redis准半同步。设置一个阈值,好比slave仅在5秒钟以内可读。

第3、资源池化。能经过相似HBase增长RegionServer的方式去进行资源扩容。


此外,还有机架感知功能和跨IDC的功能。Redis自己是为了单机房而设置的,没有考虑到这些问题。

那么,为何咱们不用原生的rRedis cluster?这里有三个缘由:1、原生的集群,它把路由转发的功能和实际上的数据管理功能耦合在一个功能里,若是一个功能出问题就会致使数据有问题;2、在大集群时,P2P的架构达到一致性状态的过程比较耗时,codis是树型架构,不存在这个问题。3、集群没有通过大平台的背书。

此外,关于Redis,咱们最近还在看一个新的NoSQL方案Aerospike,咱们对它的定位是替换部分集群Redis。Redis的问题在于数据常驻内存,成本很高。咱们指望利用Aerospike减小TCO成本。Aerospike有以下特性:

1、Aerospike数据能够放内存,也能够放SSD,并对SSD作了优化。

2、资源池化,运维成本继续下降。

3、支持机架感知和跨IDC的同步,但这属于企业级版本功能。

目前咱们内部如今有两个业务在使用Aerospike,实测下来,发现单台物理机搭载单块Inter SSD 4600,能够达到接近10w的QPS。对于容量较大,但QPS要求不高的业务,能够选择Aerospike方案节省TCO。


在NoSQL演进的过程当中,咱们也遇到一些运维方面的问题。


标准化安装

咱们共分了三个部分:OS标准化、Redis文件和目录标准、Redis参数标准化,所有用saltstack + cmdb实现;

扩容和缩容

在技术架构不断演进过程当中,扩容和缩容的难度也在变低,缘由之一在于codis缓解了一部分问题。固然,若是选择Aerospike,相关操做就会很是轻松。

作好监控,下降运维成本

大部分的运维同窗都应该认真阅读《SRE:Google运维揭秘》,它在理论层面和实践层面提出了不少很是有价值的方法论,强烈推荐。

个推Redis监控复杂性

三种集群架构:自研、codis2和codis3,这三种架构采集数据的方式并不相同。

三类监控对象:集群、实例、主机,须要有元数据维护逻辑关系,并在全局作聚合。

三种个性化配置:个推的Redis集群,有的集群须要有多副本,有的不须要。有的节点容许满作缓存,有的节点不容许满。还有持久化策略,有的不作持久化,有的作持久化,有的作持久化+异地备份,这些业务特色对咱们监控灵活性提出很高的要求。

Zabbix是一个很是完备的监控系统,约三年多的时间里,我都把它做为主要的监控系统平台。可是它有两个缺陷:一是它使用MySQL做为后端存储,TPS有上限;二是不够灵活。好比:一个集群放在一百台机器上,要作聚合指标,就很困难。

小米的open-falcon解决了这个问题,可是也会产生一些新问题。好比告警函数不多,不支持字符串,有时候会增长手工的操做等等。后来咱们对它进行功能性补充,便没有遇到大的问题。

下图是个推运维平台。

第一个是IT硬件资源平台,主要维护主机维度的物理信息。好比说主机在哪一个机架上接的哪一个交换机,在哪一个机房的哪个楼层等等,这是作机架感知和跨IDC等等的基础。

第二个是CMDB,这个是维护主机上的软件信息,主机上装了哪些实例,实例属于哪些集群,咱们用了哪些端口,这些集群有什么个性化的参数配置,包括告警机制不同,全是经过CMDB实现。CMDB的数据消费方包含grafana监控系统和监控采集程序,采集程序由咱们本身开发。这样CMDB数据会活起来。若是只是一个静态数据没有消费方,数据就会不一致。


grafana监控系统聚合了多个IDC数据,咱们运维天天只需看一下大屏就够了。


Slatstack,用于实现自动化发布,实现标准化并提升工做效率。


采集程序是咱们自行研发的,针对公司的业务特色定制化程度很高。还有ELK(不用logstach,用filebeat)作日志中心。


经过以上这些,咱们搭建出个推整个监控体系。

下面讲一下搭建过程当中遇到的几个坑。

1、主从重置,会致使主机节点压力爆增,主节点没法提供服务。

主从重置有不少缘由。

Redis版本低,主从重置的几率很高。Redis3主从重置的几率比Redis2大大减小,Redis4支持节点重启之后也能增量同步,这是Redis自己进行了不少改进。

咱们如今主要使用的是2.8.20,属于比较容易能产生主从重置。

Redis的主从重置通常是触发了以下条件中的一个。

一、repl-backlog-size过小,默认是1M,若是你有大量的写入,很容易击穿这个缓冲区;二、repl-timeout,Redis主从默认每十秒钟ping一次,60秒钟ping不推就会主从重置,缘由多是网络抖动、总节点压力过大,没法响应这个包等;三、tcp-baklog,默认是511。操做系统的默认是限制到128,这个能够适度提升,咱们提升到2048,这个能对网络丢包现象进行必定容错。

以上都是致使主从重置的缘由,主从重置的后果很严重。Master压力爆增没法提供服务,业务就把这个节点定为不可用。响应时间变长 Master所在全部主机的节点都会受到影响。

2、节点过大,部分是人为缘由形成的。第一是拆分节点的效率较低,远远慢于公司业务量的增加。此外,分片太少。咱们的分片是500个,codis是1024,codis原生是16384个,分片太少也是个问题。若是作自研的分布式方案,你们必定要把分片数量,稍微设大一点,避免业务发展超过你预期的状况。节点过大以后,会致使持久化的时间增加。咱们30G的节点要持久化,主机剩余内存要大于30G,若是没有,你用Swap致使主机持久化时间大幅增加。一个30G的节点持久化可能要4个小时。负载太高也会致使主从重置,引发连锁反应。

关于咱们遇到的坑,接下来分享几个实际的案例。

第一个案例是一次主从重置。这个状况是在春节前两天出现的,春节前属于消息推送业务高峰期。咱们简单还原一下故障场景。首先是大规模的消息下发致使负载增长;而后,Redis Master压力增大,TCP包积压,OS产生丢包现象,丢包把Redis主从ping的包给丢了,触发了repl-timeout 60秒的阈值,主从就重置了。同时因为节点过大,致使Swap和IO饱和度接近100%。解决的方法很简单,咱们先把主从断开。故障缘由首先是参数不合理,大都是默认值,其次是节点过大让故障效果进行放大。

第二个案例是codis最近遇到的一个问题。这是一个典型的故障场景。一台主机挂掉后,codis开启了主从切换,主从切换后业务没有受影响,可是咱们去从新接主从时发现接不上,接不上就报了错。这个错也不难查,其实就是参数设置太小,也是因为默认值致使。Slave从主节点拉数据的过程当中,新增数据留在Master缓冲区,若是Slave还没拉完,Master缓冲区就超过上限,就会致使主从重置,进入一个死循环。


基于这些案例,咱们整理了一份最佳实践。

1、配置CPU亲和。Redis是单机点的结构,不亲和会影响CPU的效率。

2、节点大小控制在10G。

3、主机剩余内存最好大于最大节点大小+10G。主从重置须要有同等大小的内存,这个必定要留够,若是不留够,用了Swap,就很难重置成功。

4、尽可能不要用Swap。500毫秒响应一个请求还不如挂掉。

5、tcp-backlog、repl-backlog-size、repl-timeout适度增大。

6、Master不作持久化,Slave作AOF+定时重置。

最后是我的的一些思考和建议。选择适合本身的NoSQL,选择原则有五点:

一、业务逻辑。首先要了解自身业务特色,好比是KV型就在KV里面找;若是是图型就在图型里找,这样范围一下会减小70%-80%。

二、负载特色,QPS、TPS和响应时间。在选择NoSQL方案时,能够从这些指标去衡量,单机在必定配置下的性能指标能达到多少?Redis在主机足够剩余状况下,单台的QPS40-50万是彻底OK的。

三、数据规模。数据规模越大,须要考虑的问题就越多,选择性就越小。到了几百个TB或者PB级别,几乎没太多选择,就是Hadoop体系。

四、运维成本和可不可监控,可否方便地进行扩容、缩容。

五、其它。好比有没有成功案例,有没有完善的文档和社区,有没有官方或者企业支持。可让别人把坑踩过以后咱们平滑过去,毕竟本身踩坑的成本仍是蛮高的。

结语:关于NoSQL的释义,网络上曾有一个段子:从1980年的know SQL,到2005年的Not only SQL,再到今日的No SQL!互联网的发展伴随着技术概念的更新与相关功能的完善。而技术进步的背后,则是每一位技术人的持续的学习、周密的思考与不懈的尝试。

相关文章
相关标签/搜索