有关mongoDB数据库简单介绍,毕竟是一支怎么样的

2019-09-16 12:18栏目:区块链
TAG:

随着加密货币及区块链技术日益火爆,区块链的可扩展性逐渐成为制约其应用落地的痛点之一,2017年引爆加密世界的加密猫游戏就曾让以太坊网络濒临瘫痪。

图片 1

可伸缩性是一种对软件系统计算处理能力的设计指标,高可伸缩性代表一种弹性,在系统扩展成长的过程中,软件能够保证旺盛的生命力,通过很少的改动甚至只是硬件设置的添置,就能实现整个系统能力的线性增长,实现高吞吐量和低延迟性能。

原标题:车联网上云最佳实践(一)

关于mongoDB数据库简要介绍

MongoDB是一个基于分布式文件存储的数据库,由C 语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

mongoDB数据库的特点:

高性能、易部署、易使用,存储数据非常方便。主要功能特性有:

*面向集合存储,易存储对象类型的数据。

所谓"面向集合"(Collection-Oriented),意思是数据被分组存储在数据集中,被称为一个集合(Collection)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。Nytro MegaRAID技术中的闪存高速缓存算法,能够快速识别数据库内大数据集中的热数据,提供一致的性能改进。

*模式自由(schema-free)。

采用无模式结构存储,意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。采用无模式存储数据是集合区别于RDBMS 中的表的一个重要特征。

*支持动态查询。

*支持完全索引,包含内部对象。

可以在任意属性上建立索引,包含内部对象。MongoDB的索引和RDBMS 的索引基本一样,可以在指定属性、内部对象上创建索引以提高查询的速度。除此之外,MongoDB 还提供创建基于地理空间的索引的能力。

*支持查询。

MongoDB 支持丰富的查询操作,MongoDB 几乎支持SQL中的大部分查询。

*支持复制和故障恢复。

MongoDB 支持主从复制机制,可以实现数据备份、故障恢复、读扩展等功能。而基于副本集的复制机制提供了自动故障恢复的功能,确保了集群数据不会丢失。

*使用高效的二进制数据存储,包括大型对象(如视频等)。

使用二进制格式存储,可以保存任何类型的数据对象。

*自动处理碎片,以支持云计算层次的扩展性。

*支持RUBY,PYTHON,JAVA,C ,PHP,C#,Perl,JavaScript等多种语言。

MongoDB 提供了当前所有主流开发语言的数据库驱动包,开发人员使用任何一种主流开发语言都可以轻松编程,实现访问MongoDB 数据库。

*文件存储格式为BSON(一种JSON的扩展)。

BSON 是对二进制格式的JSON 的简称,BSON 支持文档和数组的嵌套。

*可通过网络访问。

可以通过网络远程访问MongoDB 数据库。

*强大的聚合工具

MongoDB 除了提供丰富的查询功能外,还提供强大的聚合工具,如count、group 等,支持使用MapReduce 完成复杂的聚合任务。

MongoDB 除了提供丰富的查询功能外,还提供强大的聚合工具,如count、group 等,支持使用MapReduce 完成复杂的聚合任务。

MongoDB 主要应用场景有:

(1)网站实时数据处理。它非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。

(2)缓存。由于性能很高,它适合作为信息基础设施的缓存层。在系统重启之后,由它搭建的持久化缓存层可以避免下层的数据源过载。

(3)高伸缩性的场景。非常适合由数十或数百台服务器组成的数据库,它的路线图中已经包含对MapReduce引擎的内置支持。

(4)大尺寸、低价值的数据,使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。

不适用的场景如下:

(1)要求高度事务性的系统,例如,银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。

(2)传统的商业智能应用,例如针对特定问题的BI 数据库会产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。

(3)复杂的跨文档(表)级联查询。

尽管目前各行各业的去中心化应用如雨后春笋一般持续涌现,但其性能问题一直是未能突破的瓶颈,仍然存在应用场景受限、可扩展性不强等问题。当下,就连V神也是三句话离不开可扩展性话题。

随着企业服务窗口的不断增加,业务中断对很多企业意味着毁灭性的灾难,因此,跨多个数据中心的应用部署成为了当下最热门的话题之一。

  • 可伸缩性是高性能、低成本和可维护性等诸多因素的综合考量和平衡,可伸缩性讲究平滑线性的性能提升,更侧重于系统的水平伸缩,通过廉价的服务器实现分布式计算;

  • 而普通性能优化只是单台机器的性能指标优化。他们共同点都是根据应用系统特点在吞吐量和延迟之间进行一个侧重选择,当水平伸缩分区后会带来CAP定理约束

摘要: 最近两年车联网发展受到政府部门、科研院以及各大互联网巨头的广泛关注和积极推动。从应用来看,主要包括两种模式:一是前装模式(即车辆出厂前安装),是乘用车厂主导或者与有相关能力的公司合作,例如上汽和阿里巴巴的合作。

您可能感兴趣的文章

  • 合理使用MySQL数据库索引以使数据库高效运行
  • 忘记PHPnow的MySQL数据库密码的解决办法
  • yii 数据库添加,修改,删除相关操作总结
  • windows环境下mysql数据库的主从同步备份步骤
  • 关于mysql数据库大小写敏感的问题
  • 如何定位,排除和避免MySQL数据库性能问题
  • 关于修改mysql数据库字符集的方法
  • 帝国cms数据库配置文件在那里

MongoDB是一个基于分布式文件存储的数据库,由C 语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案...

而与之相对的中心化机构 Coinbase 交易所,虽然在2017年也曾受平台扩展性瓶颈影响而导致大规模故障停机,但自此以后,尽管数字货币交易人群不断暴增、交易请求数量呈指数增长,但 Coinbase 平台貌似并没有再受扩展性问题的影响,持续、稳定地运行着,令人差异,他们是如何做到的?

如今,在跨多个数据中心的应用部署最佳实践中,数据库通常负责处理多个地理区域的读取和写入,对数据变更的复制,并提供尽可能高的可用性、一致性和持久性。

软件的可扩展性设计非常重要,但又比较难以掌握,业界试图通过云计算或高并发语言等方式节省开发者精力,但是,无论采用什么技术,如果应用系统内部是铁板一块,例如 严重依赖数据库, 系统达到一定访问规模,负载都集中到一两台数据库服务器上,这是进行分区扩展伸缩就比较困难。

一、车联网行业特性讲解

近日,Coinbase 的大牛工程师 Luke Demi 发文总结了平台去年故障停机的经验与教训,并详细介绍了其平台的可扩展性解决方案。

但是,并非所有的技术在选择上都是平等的。例如,一种数据库技术可以提供更高的可用性保证,却同时只能提供比另一种技术更低的数据一致性和持久性保证。

关系数据库是最不可扩展的。

最近两年车联网发展受到政府部门、科研院以及各大互联网巨头的广泛关注和积极推动。从应用来看,主要包括两种模式:一是前装模式(即车辆出厂前安装),是乘用车厂主导或者与有相关能力的公司合作,例如上汽和阿里巴巴的合作。另一种就是后装模式(通常是将车机设备安装在汽车的OBD接口上例如各类汽车盒子等等。原理是利用智能终端(即车机)采集汽车OBD接口CAN总线上的所有原始数据进行诊断,数据分析,记录行车信息,并将数据解析出其具体意义(汽车内部电控系统的各项传感器数值)后通过串口输出,供用户读取、解析、开发等使用。将读取到的汽车内部运行数据通过手机APP软件直观展现。

图片 2

本文先分析了在现代多数据中心中应用对于数据库架构的需求。随后探讨了数据库架构的种类及优缺点,最后专门研究 MongoDB 如何适用于这些类别,并最终实现双活的应用架构。

  • 什么是性能问题?如果你的系统对于一个用户访问还很慢,那就是性能问题。

  • 什么是扩展性问题?如果你的系统对于一个用户来说很快的,但是在用户不断增长的高访问量下就慢了。

首先大致梳理下车联网行业的特性有哪些:

那么,Coinbase 团队是如何应对2017年突增的平台交易量?之后又是如何逐步扩展平台容纳量、持续稳定运行呢?其扩展性解决方案在去中心化应用领域是否有借鉴意义?接下来,听 Luke Demi 讲述 Coinbase 平台背后的故事!

双活的需求

延迟和吞吐量是衡量可扩展性的一对指标,我们希望获得低延迟高吞吐量的系统架构。所谓低延迟,也就是用户能感受到的系统响应时间,比如一个网页在几秒内打开,越短表示延迟越低,而吞吐量表示同时有多少用户能够享受到这种低延迟,如果并发用户量很大时,用户感觉网页的打开速度很慢,这意味着系统架构的吞吐量有待提高。

1、 月活非常高,在线时间长

2017年,加密货币市场经历了井喷式增长,整个加密货币生态系统的总市值从200亿美元跃升至6000亿美元。

当组织考虑在多个跨数据中心部署应用时,他们通常会希望使用“双活”的架构,即所有数据中心的应用服务器同时处理所有的请求。

扩展性的目标是用可接受的延迟获得最大的吞吐量。可靠性目标:用可接受的延迟获得数据更新的一致性

车联网行业用户的月活是非常高的,这个很好理解,因为汽车现在人们出行的必备交通工具,基本上只要一出门就会用车,一用车设备就上线并采集数据上报到平台;每天3小时的平均在线时长,因城市拥堵程度不同而不同。

在此期间,在中心化交易所 Coinbase 平台之上,几乎所有技术组件都经历了残酷的实战考验。

图片 3

缓存层的伸缩性,最简单粗暴的方式是什么呢?

2、 早晚出行高峰比较固定

实践证明,在保障平台的安全性之外,其可靠性和可扩展性也是不容忽视的。

图 1:“双活”应用架构

趁着半夜量比较低的时候,把整个缓存层全部下线,然后上线新的缓存层。新的缓存层启动起来之后,再等这些缓存慢慢预热。当然这里一个要求,你的数据库能抗住低估期的请求量。如果扛不住呢?取决于缓存类型,下面我们先可以将缓存的类型区分一下。

车联网行业一个比较有规律的特点是早晚出行高峰比较集中。早高峰集中在早上6点至9点3个小时,晚高峰集中在17点至20点的3个小时里。这样会导致每天必须有6个小时左右的流量高峰。如何以较低成本应对早晚高峰是个比较现实的问题。

在2018年的 MongoDB 社区大会中,包括 Luke Demi 在内的 Coinbase 工程师都谈到了2017年的经验和教训,以及此后如何增加平台扩展性的解决方案。

如图 1 所示,该架构可以实现如下目标:

  • 强一致性缓存:无法接受从缓存拿到错误的数据 (比如用户余额,或者会被下游继续缓存这种情形)

  • 弱一致性缓存:能接受在一段时间内从缓存拿到错误的数据 。

  • 不变型缓存:缓存key对应的value不会变更 (比如从SHA1推出来的密码, 或者其他复杂公式的计算结果)

3、 节假日高峰流量难预测

2017年的经验教训

通过提供本地处理,为来自全球的请求提供服务。

那什么缓存类型伸缩性比较好呢?

现在国家法定节假日期间,由于高速公路在此期间免费的政策,导致越来越多的人们开始选择驾车出行或出游,所以每当节假日来临时必然导致车联网用户暴增,这个洪峰流量来临的时间和流量是不确定的。如何能准确做好每次节假日出行高峰预测是个问题。

2016年,也就是加密货币市场井喷的前一年,Coinbase平台的交易量基本恒定。

即使出现整个区域性的宕机,也能始终保持高可用性。

  • 弱一致性和不变型缓存的扩容很方便,用一致性Hash即可;

  • 使用一致性Hash,而不用简单Hash的原因是缓存的失效率。如果缓存从9台扩容到10台,简单Hash 情况下90%的缓存会马上失效,而如果使用一致性Hash情况,只有10%的缓存会失效。

4、 高并发,高容量,场景复杂

在2017年首次爆发之前,Coinbase 团队就用表示四到五倍平台每日最大交易量的红线来标示出预计的平台交易量,即每分钟大约100000个后端API请求。

通过对多个数据中心里服务器资源的并行使用,来处理各类应用请求,并达到最佳的平台资源利用率。

强一致性缓存会有什么问题?

车联网行业的用户月活很高,早晚高峰比较集中的特性导致用户并发非常高,每天平均长达3小时的车辆在线时长会导致采集数据量非常大,这也直接导致在数据采集场景下基本都是写多读少,但在群组社交,朋友圈,用车报告等场景下是写少读多的。这样复杂的应用场景对应用架构有很高要求。

图片 42016年以太币价格飙升之前平台每分钟后端API请求的数量

“双活”架构的替代方案是由一个主数据中心和多个灾备区域所组成的主-DR架构。

  • 第一个问题是,缓存客户端的配置更新时间会有微小的差异,在这个时间窗内有可能会拿到过期的数据。

  • 第二个问题是,如果扩容之后再裁撤节点,会拿到脏数据。比如 a 这个key之前在机器1,扩容后在机器2,数据更新了,但裁撤节点后key回到机器1,这时候就会拿到脏数据。

5、 汽车技术更新频率快

然而,在2017年5月和6月,随着以太币价格的飙升,平台的交易量也随之猛涨并超越了红线。

图片 5

要解决问题二比较简单,要么保持永不减少节点,要么节点调整间隔大于数据的有效时间。

如今汽车技术更新越来越快,汽车厂商越来越多,厂商发布的新车型的频率也越来越高,车联网企业对这汽车行业的新技术必须保持非常高度关注,必须加快版本迭代,提高研发效率才能及时应对汽车市场的变化,才能在第一时间解决和满足市场和用户的需求。

在此期间,平台的交易量持续超越了事先预定的红线,导致 Coinbase 平台出现了一段时间的故障停机。

图 2:主-DR 架构

问题一可以用如下的步骤来解决:

目前创业公司一开始就选择了自建IDC机房,起初用户不多,只用几台服务器,后来随着产品越做越好,用户高速增长,不到2年用户规模达到了百万级别,IDC机房的服务器也达到了几百台物理机,几千台虚拟机的规模。但是问题随之也就越来越多。研究规划下一代应用架构和基础设施成了迫在眉睫的事情了,新的应用架构必须满足快速增长的用户量和爆发式的流量访问,用户体验要好;并且基础设施要做到可靠性高,稳定性高,安全性高,成本要低。传统自建IDC方案是很难做到,即便做到成本也是非常的昂贵的。相比之下云计算的各方面能力比较适合用来解决这些问题,所以上云便是最佳选择了。但是云计算厂商有很多,国内有阿里云,腾讯云,金山云等等,国外的有亚马逊,微软,谷歌等。如何选择适合自己业务场景的云计算厂家呢? 我们做了大量的调查分析和对比,最终选择了阿里云。近几年阿里云的发展势头很猛,口碑也越来越好,产品功能丰富性在国内甚至是亚洲是最强的。上云就上阿里云,感觉很接地气。

图片 6在2017年的交易量开始井喷的早期,每分钟平台后端API请求的数量

在正常运行条件下,主数据中心处理请求,而 DR 站点处于空闲状态。如果主数据中心发生故障,DR 站点立即开始处理请求。

1、两套hash配置都更新到客户端,但仍然使用旧配置;2、逐个客户端改为只有两台Hash结果一致的情况下会适用缓存,其余情况从数据库读,但写入缓存;3、逐个客户端通知使用新配置;

如果有对如何选择云计算厂家感兴趣的朋友可以参考下面这篇文章,我觉得写的不错很客观。文章链接:

为了快速解决 Coinbase 平台的可扩展性问题,工程师团队先从平台环境中常规的、容易实现的技术点进行了改进。

一般情况下,数据会从主数据中心复制到 DR 站点,以便在主数据中心出现故障时,能够迅速实施接管。

Memcache 设计得比较早,导致在伸缩性高可用方面的考虑得不太周到。Redis 在这方面有不少改进,特别是 @ngaut 团队基于 redis 开发了 codis 这个软件,一次性地解决了缓存层的绝大部分问题。推荐大家考察一下。

言归正传公司决定选择阿里云作为基础设施,下一步就是如何将业务迁到云上,于是有了这篇文章。该文章篇幅较长,部分引用可能忘记标出来源。

团队对平台进行垂直扩展,为改进其性能及优化检索过程升级数据库版本,此外,还将热点数据库集群拆分为单独数据库集群等。

如今,对于双活架构的定义尚未得到业界的普遍认同,上述主-DR 的应用架构有时也被算作“双活”。

八、缓存穿透,缓存雪崩
  • 缓存穿透:查询一个必然不存在的数据。比如文字表,查询一个不存在的id,每次都会访问DB,如果有人恶意破坏,很可能直接对DB造成影响。解决办法:对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合直接丢弃

  • 缓存失效:如果缓存在一段时间内失效,DB的压力凸显。这个没有完美的解决办法,但可以分析用户行为,尽量让失效时间点均匀分布。

  • 缓存雪崩:当发生大量的缓存穿透,例如对某个失效的缓存的大并发访问就造成了缓存雪崩。比如前端的Cache挂掉,或者比较极端的整个机房断电了,那么在机器重启后,原来Cache机器在内存中的缓存会全部清空,在客户端访问过程中,会百分之百的不命中,这样数据库会在瞬间接受巨大的读压力。

试想如果一个64GB的缓存失效了,在其重建时,假设与数据库连接的千兆网卡,假设其以极限速度100M每秒从数据库取数据过来重建缓存,那么也需要10分钟才能建完。更何况这是理想情况,对于客户端触发式的随机缓存重建,可能会花掉更长的时间。这还是在数据库能提供100M每秒的数据读请求的前提下。

我们经常看到一些网站挂掉后又恢复,恢复后又挂掉,如此反复几次才能真正恢复,原因就在于其第一次Cache倒了,数据库无法承受相应的读压力,在缓存重建了一小部分后被压死。相当于数据库每重启一次,可以恢复部分缓存,直到缓存的非命中率到达数据库可承受的压力时,才能够真正恢复服务。

第一种方式

概述: 做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

oschina首页使用了缓存,假设我们前面举的例子中所使用的缓存region,设置了自动失效时间为5分钟,相等于说每5分钟就会发现首页很卡。因此引入第二个缓存region,这个缓存的对象不会自动失效,也就说该区域的数据长期有效。

引入了第二个长效的region后,数据的读取流程这样的:

  1. 从 region1 读取数据,有则直接返回

  2. region1 没数据则启动数据更新线程,然后从 region2 读数据,有则返回

  3. region2 也没有数据

针对第3种,这种情况属于系统刚刚启动,缓存还没有填充数据的情况,没办法,这时候肯定会卡,或者你应该在系统启动的时候,自行填充一下数据,很简单,我一般在tomcat启动后,用命令访问下首页就有了缓存数据。

这样做的目的是为了正常的缓存失效后,无需等待重新从数据库中获取数据,而是直接在 region2 中获取数据并返回。因此对用户来讲,不会感觉请求被堵塞。

就这么简单,其实也可以工作,但会有一个问题:假设缓存失效的时候,同时来了100个请求,那么这100个请求会同时启动100个数据更新线程,这100个数据更新线程会到数据库执行同样的SQL语句获得同样的结果,因此这种做法对数据库的压力并没有降低。

所以缓存失效的情况下,保证有且只有一个线程去更新缓存数据。

其他方式

  • 对查询结果为空的情况也进行缓存,缓存时间设置短一些,或者该key对应的数据insert了之后清理缓存。

  • 不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀

  • 可以用一些可以提供持久化功能的缓存来实现,比如Redis,在未开启aof的情况下,其定期dump出来的rdb文件出能自动恢复出绝大部分数据,当然,在有的时候这可能导致缓存和数据库数据不一致的情况,需要根据应用场景选择性的使用。

上面是对分布式Cache的问题,而对于很多数据库存储,实际上也几乎都是将热数据尽量放在内存中的。但很多数据库在实现上是自己在内存中实现了Cache机制,这样在数据库重启时,这些Cache可能也就随之被清空了,对于数据库来说,也需要重建缓存,而数据库这时所有的操作可能都落在磁盘IO上,带来了同样的问题。

而MongoDB与上面的方式不太一样,MongoDB采用mmap来将数据文件映射到内存中,所以当MongoDB重启时,这些映射的内存并不会清掉,因为它们是由操作系统维护的(所以当操作系统重启时,MongoDB才会有相同问题)。相对于其它一些自己维护Cache的数据库,MongoDB在重启后并不需要进行缓存重建与预热。

另外,新浪微博的timyang也曾经提出过一种缓存重建加锁的方式,也能部分解决此问题。简单来说就是缓存重建时,当多个客户端对同一个缓存数据发起请求时,会在客户端采用加锁等待的方式,对同一个Cache的重建需要获取到相应的锁才行只有一个客户端能拿到锁,并且只有拿到锁的客户端才能访问数据库重建缓存,其它的客户端都需要等待这个拿到锁的客户端重建好缓存后直接读缓存,其结果是对同一个缓存数据,只进行一次数据库重建访问。但是如果访问分散比较严重,还是会瞬间对数据库造成非常大的压力。

下面是几点比较实用的知识:

  1. 无论使用哪个存储,都最好先搞清楚其缓存重建的过程,如果一次重启就可能导致数据库崩溃,还是小心为好,最好把重启时间选在访问量比较小的时候

  2. 重启MongoDB不会导致MongoDB的缓存失效

  3. 当你重新mount磁盘时,文件系统的缓存会失效,这和重启机器时一样,MongoDB也无法避免

  4. 一个使用MongoDB的小技巧,当MongoDB服务器刚启动时,你可以将其所有文件copy到/dev/null中,这会触发操作系统对这些文件的读操作,从而在内存允许的条件下,会将尽可能多的MongoDB数据文件映射到物理内存中。当然,如果在MongoDB运行过程中,你能够判断哪些文件保存的数据是热数据,也可以将这些文件copy到/dev/null 来为其争取更多的物理内存。

  1. 缓存系统与底层数据的一致性。这点在底层系统是“可读可写”时,写得尤为重要。

  2. 有继承关系的缓存之间一致性。为了尽量提高缓存命中率,缓存也是分层:全局缓存,二级缓存。他们是存在继承关系的。全局缓存可以有二级缓存来组成。

  3. 多个缓存副本之间的一致性。为了保证系统的高可用,缓存系统背后往往会接两套存储系统(如memcache,redis等)

  1. 定时去清理过期的缓存。

  2. 当有用户请求过来时,在判断这个请求所用到的缓存是佛过期,过期的话就去底层得到新数据并更新缓存。

两者各有优劣:第一种的缺点是维护大量缓存的key是比较麻烦的第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂,具体哪种方案,大家可以根据自己的应用场景来权衡。

缓存淘汰的几种会用到的技巧

  1. 预估失效时间。

  2. 版本号(必须单调递增,时间戳是最好的选择)。

  3. 提供手动清理缓存的接口。

衡量架构伸缩性的主要标准就是是否可以用多台服务器构建集群,是否容易向集群中添加新的服务器。加入新的服务器后是否可以提供和原来的服务器无差异的服务。集群中可容纳的总的服务器数量是否有限制。

对于应用服务器集群,只要服务器上不保存数据,所有服务器都是对等的,通过使用合适的负载均衡设备就可以向集群中不断加入服务器。

对于缓存服务器集群,加入新的服务器可能会导致缓存路由失效,进而导致集群中大部分缓存数据都无法访问。虽然缓存的数据可以通过数据库重新加载,但是如果应用已经严重依赖缓存,可能会导致整个网站崩溃。需要改进缓存路由算法保证缓存数据的可访问性。

关系型数据库虽然支持数据复制,主从热备机制,但是很难做到大规模集群的可伸缩性,因此关系数据库的集群伸缩性方案必须在数据库之外实现,通过路由分区等手段将部署有多个数据库的服务器组成一个集群。

至于大部分NoSQL数据库产品,由于其先天就是为海量数据而生,因此其对伸缩性的支持通常都非常好,可以做到在较少运维参与的情况下实现集群规模的线性绳索。

《大型网站技术架构核心原理与案例分析》

1. 缓存均匀分布,均匀失效。

2. 二级缓存解决缓存雪崩

3. 缓存很重要,但是数据库的查询优化也很重要

4. 情况允许,扩大MySQL临时表的空间,以防缓存雪崩瞬间巨大访问,导致MySQL崩溃

5. 需要在流量少的情况下,切换缓存,切换完毕之后。需要缓存预热

6. 多看书,多试验

参考

oschina 上的一种双缓存思路名词解释“缓存穿透”与“缓存雪崩”高可用可伸缩架构实用经验谈大型网站技术架构核心原理与案例分析缓存穿透与缓存雪崩不可忽略的缓存重建

二、传统IDC架构介绍及技术详解

经过以上方法改进,Coinbase 平台压力暂时得以缓解,但随着时间流逝,交易量总在持续攀升,平台断断续续出现了很多次故障。

区别在于从主站到 DR 站点的故障转移速度是否够快,并且是否能够自动化。在这样的解释中,双活体系架构意味着应用停机时间接近于零。

俗话说知己知彼百战不殆,我们要上云首先要充分了解自己业务和应用架构。然后在充分了解云上产品的特性,看看哪些产品可以直接被我们使用,哪些是需要我们的应用或架构做出调整的。下面我们来分析下智能车联网平台的相关架构。

每次故障停机的模式都是相同的:主监控平台会显示100倍的延迟峰值,Ruby 和 MongoDB 延迟时间各是50倍。

有一种常见的误解,认为双活的应用架构需要有多主数据库。这样理解是错误的,因为它曲解了多个主数据库对于数据一致性和持久性的把握。

1、 业务架构

作为 Coinbase 的主要数据存储区,MongoDB 在数据流量大的时候会出现高延迟,而 Ruby 延迟时间并没有增加。

一致性确保了能读取到先前写入的结果,而数据持久性则确保了提交的写入数据能够被永久保存,不会产生冲突写入;或是由于节点故障所产生的数据丢失。

下图为公司业务架构图。分为三大业务平台,其中核心是车联网平台,其次是能力资源平台和第三方合作平台。

图片 7

双活应用的数据库需求

图片 8

在早期的监控系统中,这就是“幽灵”出现的方式

在设计双活的应用架构时,数据库层必须满足如下四个方面的架构需求(当然,也要具备标准数据库的功能,如具有:丰富的二级索引能力的查询语言,低延迟地访问数据,本地驱动程序,全面的操作工具等):

车联网核心平台:主要包含应用层、支持层、物理层等功能,其中应用层包含功能有用户注册,用户登录,导航功能,车友功能,车辆检测功能,轨迹查询功能以及其他娱乐功能。这些是APP的核心功能。其次是支持层的功能,例如运营管理系统,用户管理系统,车辆管理系统等辅助运营和运维的系统和工具。

Coinbase 已有的监控工具无法为当时遇到的一些关键问题提供明确的答案,我们把这个现象称为“幽灵”。

性能,低延迟读取和写入操作。这意味着:能在本地数据中心应用的节点上,处理读取和写入操作。

能力资源平台:是指的公司具备向外界提供的资源和能力,可以利用开放平台将我们的能力提供给外部需要客户和合作伙伴。例如车队服务,数据应用,位置服务等等。

比如,这些查询操作来自哪里? 这些操作是怎么回事? 为什么Ruby时间显示出相关的峰值? 问题可能源于应用程序方面吗?

数据持久性,通过向多个节点的复制写入来实现,以便在发生系统故障时,数据能保持不变。

第三方合作平台:是指通过调用第三方平台接口来完成为用户提供部分功能,例如保险服务,违章查询功能,停车位查找功能,4S店服务等功能。

简而言之,团队现有的监控服务并没有完全利用 Coinbase 平台环境中的可用信息。

一致性,确保能读取之前写入的结果,而且在不同地区和不同节点所读到的结果应该相同。

2、应用架构

因此,需要一个框架来回答这些问题并可视化 Coinbase 环境组件之间的关系。

可用性,当某个节点、数据中心或网络连接中断时,数据库必须能继续运行。另外,从此类故障中恢复的时间应尽可能短,一般要求是几秒钟。

下图为应用架构,主要分为客户端接入层,负载均衡集群,应用服务器集群,缓存集群,消息队列集群,分布式服务集群,数据存储集群,运维管控集群等。

团队通过修改 MongoDB 的数据库驱动程序来进一步改进数据库的查询操作。

分布式数据库架构

图片 9

修改后的数据库驱动程序会记录超过特定响应时间阈值的所有查询操作,以及请求/响应大小、响应时间、源代码和查询类型等重要信息。

针对双活的应用架构,一般有三种类型的数据库结构:

1.1 数据流介绍

图片 10所有慢速MongoDB查询操作中记录的重要信息

使用两步式提交的分布式事务。

数据采集:

这些改进提供的详细数据使团队能够快速找到一些故障停机期间的异常特征,甚至在非故障停机期间也可以。

多主数据库模式,有时也被称为“无主库模式”。

首先通过车载智能终端设备收集汽车相关行驶数据,然后通过物联网卡(即sim卡)上报到平台,平台经过协议解析服务将数据转换成可读的数据并进行存储下来,并且需要把原始数据也保存一份。

第一个主要异常是查找设备操作的响应信息数据量过大。

分割数据库具有多个主分片,每个主分片负责数据的某个唯一片区。

数据处理:

当用户登录网站购买加密货币或查看相关信息时,大量的查询会导致过重的网络负载。

下面让我们来看看每一种结构的优缺点。

将解析后的数据放到消息队列中,后端的各种应用服务开始处理不同的数据,例如轨迹服务会去消息队列中取出轨迹数据进行分析和处理。从而生成用户的行驶轨迹等功能;再例如故障检测服务,通过订阅消息队列中有关汽车传感器数值进行分析和判断该车辆是否存在故障。

图片 11

两步式提交的分布式事务

数据分析:

造成响应信息数据量过大的原因是当时用户和设备之间为多对多关系。

分布式事务方法是在单次事务中更新所有包含某个记录的节点,而不是写完一个节点后,再复制到其他节点。

部分行车数据经过各个模块的处理最终保存在数据库中,通过利用大数据分析进行特定场景的离线分析,例如驾驶行为分析服务通过分析用户每天驾驶行为(例如急加速,急减速,急转弯等行为)来判断用户的驾驶行为是否良好,等等。

例如,一些用户可能拥有多个设备,而某些设备可能由多名用户共用。 糟糕的设备指纹(用于标定设备)识别算法将大量用户置于同一设备中,从而导致单个设备拥有大量 user_id 对象。

该事务保证了所有节点都会接收到更新,否则如果某个事务失败,则所有节点都恢复到之前的状态。

数据展示:

图片 12

虽然两步式提交协议可以确保持久性和多节点的一致性,但是它牺牲了性能。

用户通过下载并安装手机APP,注册登录App后用户可以在APP 上查看自己车辆的位置,轨迹查询,油耗,车辆故障以及交友,娱乐等功能。

为了解决这个问题,Coinbase 团队将这种多对多关系重构为简单的一对多关系,其中每个设备只映射到一个用户。

两步式提交协议要求在事务中所有参与的节点之间都要进行两步式的通信。即在操作的每个阶段,都要发送请求和确认,以确保每个节点同时完成了相同的写入。

1.2 应用架构介绍

这个改进为 Coinbase 平台带来了2017年最大的一次性能提升。

当数据库节点分布在多个数据中心时,会将查询的延迟从毫秒级别延长到数秒级别。

防火墙:

图片 13

而在大多数应用,尤其是那些客户端是用户设备(移动设备、Web 浏览器、客户端应用等)的应用中,这种响应级别是不可接受的。

当前在传统IDC机房中应用的最前端是一台防火墙,用来防御一些常见的攻击和访问控制的操作。因为防火墙并不是什么高端防火墙所以防御能力有限。因公司业务快速发展,期间已经更换过2次防火墙,分别是用户规模在10万和100万的时候。每次更换防火墙对业务都会造成不同程度的停服时间。用户体验很不好,但是没办法因为业务刚开始的时候用户不多,系统设计之初为10万级别,用户从0到10万规模用了1年左右时间。但是从10万到100万用户规模只有了7个月时间,用户增非常快,无奈又更换防火墙到能支撑到500万用户规模。再这么发展下去就不敢想象了。一是硬件设备成本越来越贵,往往投入几十万但是因为业务发展超出预期,刚买来的设备使用不到1年,又面临瓶颈又得换,真是费钱又费力。二是防火墙是所有业务的入口,如果防火墙出问题业务必然会挂,更换会导致业务停服,不更换防火墙会挂还是会停服。

这一发现说明了良好监控平台的作用。

多主数据库

负载均衡集群:

在精心改进我们的数据库查询操作之前,这几乎是不可能实现的调试问题,有了新工具,现在结果显而易见。

多主数据库是一种分布式的数据库,它允许某条记录只在多个群集节点中一个之上被更新。而写操作通常会复制该记录到多个数据中心的多个节点上。

四层负载均衡集群采用LVS服务器,主要为后端的协议解析和数据处理服务提供负载均衡功能,因为单台协议解析服务最大每秒只能处理10000台车,所以lvs下挂了很多台数据采集服务器。这样可以满足每秒海量车辆同时在线。

另一个问题是某些数据库集群的巨大读取流量。

从表面上看,多主数据库应该是实现双活架构的理想方案。它使得每个应用服务器都能不受限地读取和写入本地数据的副本。但是,它在数据一致性上却有着严重的局限性。

有关mongoDB数据库简单介绍,毕竟是一支怎么样的团组织。七层负载均衡集群采用Nginx服务器,主要为后端web应用服务器提供负载均衡和反向代理功能,此外Nginx支持正则表达式和其他功能。

添加一个查询缓存层,用于在 Memcached(一个高性能的分布式内存对象缓存系统,用于动态 Web 应用以减轻数据库负载)中缓存查询结果。

由于同一记录的两个副本可能在不同地点被不同的会话同时更新。这就会导致相同的记录会出现两个不同的版本,因此数据库必须通过解决冲突来解决不一致的问题。

这一块我们目前遇到瓶颈是在IDC网络带宽扩容上,目前我们IDC机房如果对需要对网络带宽扩容需要提申请报备,内部走流程做完在到运营商那里走流程,时间往往比较长,最快也要1-2天,无法及对网络带宽做到快速扩容,当然也就无法应对突发流量增长。如果长期购买大量闲置带宽,本身是一种资源的浪费。毕竟目前国内优质的网络带宽资源成本还是相当高的。作为公司的运维同学,如何为公司开源节流,把每一分钱用在刀刃上是责任是义务更是一种能力。

在查询数据库之前,特定高读取流量的数据库集群对任何单个文档的查询操作都会先在查询缓存层中进行,对数据库的任何写入操作也会同时更新缓存。

常用的冲突解决策略是:最近的更新“获胜”,或是具有更多修改次数的记录“获胜”。因为如果使用其他更为复杂的解决策略,则性能上将受到显著的影响。

应用服务器集群:

图片 14

这也意味着,从进行写入到完成冲突解决机制的这个时间段内,不同的数据中心会读取到某个相同记录的不同值和冲突值。

应用服务器操作系统统一采用Centos7,运行环境主要为JAVA环境和PHP环境,还有少部分Node.js环境

这样就能够同时在多个数据库集群中推出此更新。 查询缓存是在 ORM(Object Relational Mapping,对象关系映射)和驱动程序级别编写的,这使我们可以同时更新多个有问题的数据库集群。

分区数据库

Java环境:采用Centos7 JDK1.7 Tomcat7

图片 15事实证明,去年5月和6月经历的交易量井喷与去年12月和今年1月经历的交易量井喷根本不是一个数量级的。

分区数据库将数据库分成不同的分区,或称为分片。每个分片由一组服务器来实现,而每个服务器都包含一份分区数据的完整副本。这里关键在于每个分片都保持着对数据分区的独有控制权。

PHP环境:采用Centos7 PHP5.6.11

借助这些修复和其他方法,Coinbase 平台就能够承受更大的交易量激增。

对于任何给定时间内的每个分片来说,由一台服务器充当主服务器,而其他服务器则充当其副本。数据的读取和写入被发布到主数据库上。

Node.js环境:采用Centos7 Node8.9.3

图片 162017年上半年的交易量井喷(红圈处)较后期而言不足为奇

如果主服务器出于任何原因的(例如硬件或网络故障)失败,则某一台备用服务器会自动接任为主服务器的角色。

目前我们的应用开发语言有java 有php 有Python,web环境有tomcat,nginx,Node.js等环境,应用发布自动化程度不够高,大多还是脚本方式进行应用升级发布。通常应用发布升级工作都在半夜进行,加班非常严重。运维重复工作量非常大,导致运维成就感很低。大部分时间不是在解决问题就是在升级发布过程中。没有时间提升自身能力。运维人员开始陷入迷茫找不到方向,运维人员流失率逐渐增高,如果不得到有效解决,必将陷入恶性循环。

为未来做准备

数据库中的每条记录都属于某个特定的分区,并由一个分片来进行管理,以确保它只会被主分片进行写入。分片内的记录映射到每个分片的一个主分片,以确保一致性。

分布式服务集群:

今天,Coinbase 团队正积极努力为下一次加密货币市场的井喷做准备。

由于集群内包含多个分片,因此会有多个主分片,因此这些主分片可以被分配到不同的数据中心,以确保都在每个数据中心的本地都能发生写入操作,如图 3 所示:

分布式服务集群,采用Dubbo ZooKeeper搭建的分布式服务框架。其中zookeeper的服务器需要保持奇数目的是便于选举。

虽然在井喷期间做这些改进工作很容易,即使未来将处于交易量非常低的周期,但仍然需要找到一种方法来改善系统在未来的表现。

图片 17

Dubbo也是比较流行的JAVA应用的分布式服务框架,它是阿里开源的分布式服务框架。但是在使用过程中也发现由于没有一个比较好用的Dubbo监控软件,导致应用出现故障时排查故障很费力,如果有一套比较强大的链路跟踪监控系统对于那分布式应用来说是锦上添花了。

比较有效的方案就是通过模拟几倍于过去经历的交易量峰值来测试平台环境,来发现下一个问题点可能来自哪里。

图 3:分区数据库

缓存集群:

解决方案就是执行交易流量的捕获和回放,明确地说就是在数据库上按需生成人为的“加密狂热(crypto mania)”。

分片数据库可用于实现双活的应用架构,其方法是:至少部署与数据中心一样多的分片,并为分片分配主分片,以便每个数据中心至少有一个主分片,如图 4 所示:

缓存集群采用的Redis3.0 Cluster集群模式,该架构中有10套Redis缓存集群,每个集群的内存从60G-300G不等。缓存服务器是典型的内存型主机,对CPU开销不大,如果要做持久化,对磁盘IO要求较高,磁盘建议使用SSD。

这种方案比生成合成流量的方案更好,因为它去除了合成脚本需要保持最新的要求。每次运行套件时,都要确保查询操作根据捕获的数据准确映射到应用程序生成的流量类型。

图片 18

对于缓存最大痛点在于运维,经常出现因磁盘IO瓶颈导致的redis集群故障,以及因用户快速增长需要经常对Redis集群进行在线扩容等。而且Redis运维都是只能是手动运维,工作量大,且容易误操作。因Redis集群而导致的故障不计其数。当然也跟当时的应用强依赖相关,Redis集群故障就导致整个应用也挂了,这是应用系统设计的缺陷。

为此,我们创建了一个名为“Capture”的工具,其内部封装了现有工具“mongoreplay”。

另外,通过配置分片能保证每个分片在各种数据中心里至少有一个副本。

消息队列集群:

在环境中选择一个特定数据库集群后,Capture 会同时启动数据库集群快照并开始捕获定向到该数据库集群的应用程序服务器上的原始流量。然后,它会在一段时间后将这些捕获的加密信息保存到S3回放。

例如,图 4 中的图表描绘了跨三个数据中心的分布式数据库架构:

由于在高并发环境下,系统来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达MySQL,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。该架构中采用的是开源的Kafka作为消息队列,它是分布式的,基于发布/订阅的消息系统。具有高吞吐率,同时支持实时数据处理和离线数据处理。

当准备好执行回放时,另一个基于“mongoreplay”名为“Cannon”的工具将根据之前的数据库集群快照将记录的流量回放到新启动的数据库集群上。

纽约

这个消息队列的痛点也是刻骨铭心,kafka是开源软件,曾经遇到几次故障都是跟kafka有关系,在0.8.1,遇到kafka删除topic的功能存在bug,随后升级到09版本,不巧又遇到09版本kafka client的BUG,这个bug导致多分区多consumer时rebalancing可能会导致某个分区阻塞。后来升级kafka10版本,但是10版本的消费方式和08版本有差别,没办法又对消费程序进行改造。总之在我们使用kafka过程中遇到太多kafka的bug而导致的故障了。而我们中小企业技术能力有限没有能力第一时间修复这种开源软件的bug,处于非常被动和无奈的局面。

图片 19

伦敦

流计算集群:

在这个过程中,面临的挑战就是如何同时横跨多个应用程序服务器来捕获单个数据库集群的所有 MongoDB 流量。

悉尼

流计算采用的阿里巴巴开源的Jstorm,利用流计算平台可以对实时数据进行处理和分析。该架构中使用2套流计算集群,每个流计算集群规模在8台高性能服务器。并且每个集群中包括2个supervisor管控节点,一主一备实现流计算高可用。流计算主要用于车辆告警,行驶轨迹等一些实时计算场景。

解决方法就是,Cannon 工具通过从每次捕获中打开一个10MB的缓冲区来同时进行合并和过滤捕获。

群集有三个分片,每个分片有三个副本:

数据存储集群:

图片 20

NYC 分片在纽约有一个主分片,在伦敦和悉尼有副本。

数据存储集群包含数据库集群和分布式文件系统。

最终得到一个合并的捕获文件,然后 Cannon 工具可以将其定向到一个新启用的 MongoDB 数据库集群中。

LON 分片在伦敦有一个主分片,在纽约和悉尼有副本。

数据库集群又包含多种数据库,例如MySQL数据库集群,MongoDB集群,Elasticsearch集群。

Cannon 工具允许精确选择回放捕获信息的速度,从而模拟数千倍于平台一天可能遇到的交易数据量的负载。

SYD 分片在悉尼有一个主分片,在伦敦和纽约有副本。

MySQL集群:公司目前拥有几十套大大小小的数据库集群,有的采用一主2从的高可用架构,有的是双主架构,这些MySQL数据库主要用于业务数据库。随着公司业务快速发展以及用户规模的快速增长,对数据库的性能要求也越来越高,从原来的高配虚拟机到后来的高配物理机,后来物理机的本地磁盘IO也满足不了要求,接着就开始上给数据库服务上SSD硬盘。现在勉强能维持着,在不久的将来,即便是目前最高配置的单台数据库服务器性能也不能满足的时候,我们怎么办?数据库团队需要提前掌握和了解未来的解决方案是什么,比如说分布式关系型数据库?

图片 21

通过这种方式,每个数据中心都有来自所有分片的副本,因此本地应用服务器可以读取整个数据集和一个分片的主分片,以便在其本地进行写入操作。

MongoDB集群:公司目前有3套MongoDB集群,主要用来存储车辆上报的原始数据,和解析后的车辆状态、点火、告警、轨迹等数据。采用的是副本集,通常由只是3个节点组成。其中一个是主节点,负责处理客户端请求,其余都是从节点,负责复制主节点上的数据。

虽然才刚刚开始使用 Capture 和 Cannon 工具,但在 MongoDB 数据库集群上执行这类的负载测试时,我们取得了一些新发现。

分片数据库能满足大多数使用场景的一致性和性能要求。由于读取和写入发生在本地服务器上,因此性能会非常好。

Elasticsearch集群:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。该架构中ES集群采用3个节点,这个3个节点都是候选主节点。这里我们主要用于轨迹查询,信息检索、日志系统等场景。

这个发现来自于 Cannon 工具的调试功能。 Cannon 工具能够检查特定的捕获文件并查看其中的前100条消息。 经过检查,确实发现了一些有趣的事:

从主分片中读取时,由于每条记录只能分配给一个主分片,因此保证了一致性。

NFS分布式文件系统:

图片 22有没有注意到 ping 命令(ping 命令用于检查网络是否连通,可以帮助分析和判定网络故障。)与 find 命令(查找)混合在一起?

例如:我们在美国的新泽西州和俄勒冈州有两个数据中心,那么我们可以根据地理区域来分割数据集,并将东海岸用户的流量路由到新泽西州的数据中心。

因为有大量的各类应用图片和用户上传的图片需要保存,所有需要一个高性能的文件存储,这里采用自建NFS分布式文件系统。

事实证明,数据库 MongoDB 的 Ruby 语言驱动程序未完全遵循 MongoDB 驱动程序的设计规范,并且在每次查询数据库时通过执行 ping 命令以检查复制集状态。

因为该数据中心包含的是主要用于东部的分片;并将西海岸用户的流量路由到俄勒冈州数据中心,因为该数据中心包含的是主要用于西部的分片。

但是自建NFS分布式文件系统由于公司投入硬件设备有限,导致本身的扩展性是相当差的,而且需要停机相当影响业务。访问速度因客户端增加而变慢。这是个很影响用户体验的痛点,必须改造。

虽然这种行为不太可能导致 Coinbase 平台故障停机,但几乎可以肯定,这是造成我们在监控中观察到的“幽灵”行为的原因。

我们可以看到分片的数据库为我们提供了多个主数据库的所有好处,而且避免了数据不一致所导致的复杂性。

运维管控集群:

图片 23在团队协作完成这次挑战后,我们为 Coinbase 目前的可靠性状态感到自豪。

应用服务器可以从本地主服务器上进行读取和写入,由于每个主服务器拥有各自的记录,因此不会出现任何的不一致。相反,多主数据库的解决方案则可能会造成数据丢失和读取的不一致。

在复杂的系统架构和海量的服务器环境中,需要合适的运维管控软件来提升运维的工作效率。

2017年的事件再次证明,给客户提供访问和查看资金的可靠服务对于实现Coinbase 成为值得信赖的购买、销售和管理加密货币平台的目标至关重要。

数据库架构比较

监控:采用的是Zabbix开源监控系统;

虽然安全性始终是我们的首要任务,但我们也乐于将确保我们平台可靠性、可扩展性当作Coinbase的主要任务!

图片 24

代码管理:采用gitlab进行代码托管;

目前,我们已经组建了三个独立的专注维护平台高性能和可扩展性团队,为未来加密货币热情的暴涨做好准备。

图 5:数据库架构比较

堡垒机:采用的是Jumpserver开源堡垒机,用于运维人员的操作审计和提升用户登录的安全性;

图 5 提供了每一种数据库架构在满足双活应用需求时所存在的优缺点。在选择多主数据库和分区数据库时,其决定因素在于应用是否可以容忍可能出现的读取不一致和数据的丢失问题。

日志查询和管理:采用ELK,开源日志系统;

如果答案是肯定的,那么多主数据库可能会稍微容易部署些。而如果答案是否定的,那么分片数据库则是最好的选择。

持续集成:我们采用的是Jenkins,它是一款开源持续集成工具,利用Jenkins可以实现代码构建,自动部署,自动测试等持续部署。

由于不一致性和数据丢失对于大多数应用来说都是不可接受的,因此分片数据库通常是最佳的选择。

配置管理系统:提供应用的集中式配置管理,是基于java开发的配置管理。

MongoDB 双活应用

虽然当前的运维体系还算比较规范,但是大多数运维工具都是开源的产品,只能满足部分功能需求。随着运维管控需求的增加,需要的熟悉的开源产品也越多。运维管理不够统一,运维人员通常需要熟悉和掌握很多运维系统,导致新手很难入手。

MongoDB 是一个分片数据库架构的范例。在 MongoDB 中,主服务器和次服务器集的构造被称为副本集。副本集为每个分片提供了高可用性。

1.3 传统IDC架构痛点

一种被称为区域分片(Zone Sharding)的机制被配置为:由每个分片去管理的数据集。如前面所提到的,ZoneSharding 可以实现地域分区。

随着用户规模与日俱增,慢慢的这套架构也暴露出很多问题来。

白皮书《MongoDB多数据中心部署》:

痛点1:运维自动化程度低,运维工作繁重且无意义

Zone Sharding 相关文档: MongoDB 具体实现和运作的细节。

我们公司运维大部分时间还是处于人肉运维,脚本运维时代,运维自动化程度低,原因一是公司业务发展太快,运维人员每天大部分时间不是在处理应用升级就是在解决系统故障,根本没有时间去做运维自动的工作。其次运维开发方向的人才比较难招,也可能是开的薪水没有竞争力。总之各种原因导致我们公司在运维自动化进程上比较慢,有恶性循环的趋势。

其实许多组织,包括:Ebay、YouGov、Ogilvyand Maher 都正在使用 MongoDB 来实现双活的应用架构。

痛点2:没有弹性扩容缩容能力,应对流量高峰代价高

除了标准的分片数据库功能之外,MongoDB 还提供对写入耐久性和读取一致性的细粒度控制,并使其成为多数据中心部署的理想选择。对于写入,我们可以指定写入关注(write concern)来控制写入的持久性。

因为车联网行业的一个特点就是早晚高峰和节假日期间车辆在线率飙升,然后进入平稳期。一天24小时有6个小时是早晚高峰,其余18个小时是正常流量,通常高峰期流量是平常的3-5倍。传统IDC通常需要几天时间才能完成一次线上扩容,根本不可能应对突发性的流量暴涨的情况。我们为了保障系统稳定性以及保障用户体验,只能是投入比平时多几倍的资源,整体资源利用率不到30%,产生巨大资源浪费。

Writeconcern 使得应用在 MongoDB 确认写入之前,就能指定写入的副本数量,从而在一个或多个远程数据中心内的服务器上完成写入操作。籍此,它保证了在节点或数据中心发生故障时,数据库的变更不会被丢失。

痛点3:运维工具零散、运维工作复杂繁琐

另外,MongoDB 也补足了分片数据库的一个潜在缺点:写入可用性无法达到 100%。

我们公司的运维管控软件绝大部分是以开源为主的运维软件,种类繁多,例如开源跳板机Jumpserver,zabbix监控系统,持续集成Jenkins,自动化运维Ansible等等,这些软件都需要配置独立的登录账号。导致账号繁多,管理非常不方便,运维人员需要操作和熟悉很多开源软件。例如zabbix监控在规模不大的时候基本能应付日常的监控告警,但是随着服务器的增加导致监控项的急剧增加之后,数据库性能跟不上,告警延迟或者误报的情况非常多。一些定制监控需求和监控项目仍需要单独开发。所以运维工具种类繁多也直接导致运维工作的复杂繁琐。

由于每条记录只有一个主节点,因此如果该主节点发生故障,则会有一段时间不能对该分区进行写入。

痛点4: 硬件设备采购周期长,成本高,扩展性差

MongoDB 通过多次尝试写入,大幅缩短了故障切换的时间。通过多次尝试的写入操作,MongoDB 能够自动应对由于网络故障等暂时性系统错误而导致的写入失败,因此也大幅简化了应用的代码量。

我们公司应用刚上线的时候系统各方面的设计比较简单,横向扩展能力不强,随着业务爆发式增长,因为我们很多资源无法及时扩展,导致系统故障,用户体验降低。例如文件存储,刚开始的时候我们是自建的NFS文件存储,用于存放用户头像,驾驶证,朋友圈等图片文件。由于各方面原因当初没有投入足够的资源建设,导致一段时间之后存储就不够用,读写性能下降,用户访问延迟等等。最痛的一点是硬件设备的扩展周期长,从提出采购需求到最后的实施硬件扩展,往往需要5-10天甚至更长,因为这期间需要经历采购审批流程,物流发货,到货验收,机房上架等。

MongoDB 的另一个适合于多数据中心部署的显著特征是:MongoDB 自动故障切换的速度。

痛点5:基础设施可靠性差,故障频发

当节点或数据中心出现故障或发生网络中断时,MongoDB 能够在 2-5 秒内(当然也取决于对它的配置和网络本身的可靠性)进行故障切换。

传统IDC底层基础设施通常都是企业自己搭建的,这里会有很多原因导致底座基础设施不稳定的因素。例如企业一开始对硬件投入不重视,使用廉价的设备;再例如工程师技术能力有限,搭建的基础设施架构稳定性差强人意;例如遇到运营商网络质量不稳定,也没有BGP接入,这个时候也只能干瞪眼了。另外我们的IDC机房一年当中遇到过3次意外断电,导致大面积系统瘫痪。所以说底层基础设施不稳定会导致后续应用经常出现莫名其妙的故障,而且无法及时定位,找不到原因。随时会出现意想不到的问题,每天都是提心吊胆的。

发生故障后,剩余的副本集将根据配置去选择一个新的主切片和 MongoDB 驱动程序,从而自动识别出新的主切片。一旦故障切换完成,其恢复进程将自动履行后续的写入操作。

痛点6:安全防护能力弱,易受攻击

对于读取,MongoDB 提供了两种功能来指定所需的一致性级别。

随着公司快速发展和用户规模的增长的同时,很容易被别有用心的人盯上,记得有一天下午3点左右,突然遭受到大量DDOS攻击,我们的防火墙一下就被打垮了,系统瞬间就瘫痪了,没有办法,什么都做不了,防火墙已经跪了,登不上去了,一直持续几个小时,业务也瘫痪了几个小时,一点办法没有。我们的安全防护能力真的很弱,也跟成本有关,高端的防火墙买不起,还有运营商的带宽也很贵。

首先,从次数据进行读取时,应用可以指定最大时效值(maxStalenessSeconds)。

作者:云攻略小攻

这可以确保次节点从主节点复制的滞后时间不能超过指定的时效值,从而次节点所返回的数据具有其时效性。

本文为云栖社区原创内容,未经允许不得转载。返回搜狐,查看更多

另外,读取也可以与读取关注(ReadConcern)相关联,来控制查询到的返回数据的一致性。

责任编辑:

例如,ReadConcern 能通过一些返回值来告知 MongoDB,那些被复制到副本集中的多数节点上的数据。

这样可以确保查询只读取那些没有因为节点或数据中心故障而丢失的数据,并且还能为应用提供一段时间内数据的一致性视图。

MongoDB 3.6 还引入了“因果一致性(causal consistency)”的概念,以保证客户端会话中的每个读取操作,都始终只“关注”之前的写入操作是否已完成,而不管具体是哪个副本正在为请求提供服务。

通过在会话中对操作进行严格的因果排序,这种因果一致性可以确保每次读取都始终遵循逻辑上的一致,从而实现分布式系统的单调式读取(monotonic read)。而这正是各种多节点数据库所无法满足的。

因果一致性不但使开发人员,能够保留过去传统的单节点式关系型数据库,在实施过程中具备的数据严格一致性的优势;又能将时下流行架构充分利用到可扩展和具有高可用性的分布式数据平台之上。

版权声明:本文由永利皇宫登录网址发布于区块链,转载请注明出处:有关mongoDB数据库简单介绍,毕竟是一支怎么样的