服务器硬盘miss(服务器硬盘missing,逼迫加载)「服务器硬盘显示missing」

  

  本文根据【2016第七届中国数据库技能大会】现场演讲高朋孙玄老师分享内容整理而成。灌音整理及笔墨编辑IT168@ZYY@老鱼

  讲师简介

  

  ▲孙玄

  58团体高级体系架构师,58团体技能委员会主席架构组主任,产物技能学院良好讲师,58同城即时通讯、转转架构算法部负责人,善于体系架构计划,分布式存储等技能范畴。代表58同城多次参加QCon,SDCC,DTCC,Top100,Strata+HadoopWorld,WOT等大会高朋演讲,并为《程序员》杂志撰稿2篇。前百度高级工程师,参加社区搜刮部多个底子体系的计划与实现。毕业于浙江大学。“架构之美”作者。

  正文

  各人好,我是来自58的孙玄,本日分享的主题是《MongoDB在58同城的应用实践》,重要内容如下所示:

  

  起首先容一下MongoDB在58的利用环境,从2011年到2014年,58根本利用了三年MongoDB,三年中,整个公司的业务线都在大规模利用MongoDB。在2014年,由于技能选型的改变,58共同业务特点做了一些调解。14年和15年,58根本很少利用MongoDB,但随着赶集和英才对MongoDB的频仍利用,58于本年又开始大规模利用MongoDB。

  就我个人而言,从15年开始真正利用MongoDB,重要应用在业务线上,以是分享的内容重要针对15年之前MongoDB在58的应用案例和实践。随着MongoDB社区的发展,特别是3.0的崛起,大概会略有不敷。以上便是此次分享的配景,接下来切入主题。

  

  根本上在2014年底,58比力核心的业务线都在利用MongoDB,包罗IM,交友,雇用,信息质量,测试以及赶集和英才。如今最核心的数据存储也是采取MongoDB在做,后期由于技能选型以及业务调解,利用量有所降落。

  

  接下来讲一下选用MongoDB的缘故起因,作为一款NoSQL产物,选择的同时我们会思量到它的特性,重要有如下几方面:

  一是扩展性,MongoDB提供了两种扩展性,一种是Master—Slave,基于主从复制机制,如今58用的比力多的是ReplicSet,实际上就是副本集布局。我们会针对差别的业务项举行垂直拆分。

  二是高性能,MongoDB在3.0之前,整个的存储引擎依靠于MMAP。MMAP是整个的写内存,就是写磁盘。数据写入内存之后,要通过操纵体系的MMAP机制,特别做数据层的,假如数据存多份的话,就大概会造成数据不同等的题目。MongoDB在提供高性能的同时,数据只存一份。这种环境下,计划提供高性能的同时,可以很好地办理数据同等性题目。

  除此之外,MongoDB也有其他一些特性,包罗丰富的查询,fullindex支持和Auto-Sharding。别的,做任何选择肯定要连合业务逻辑。58原来是分类信息网站,重要的业务特性是并发量比力大,但58和电商的自主买卖业务差别,对事件没那么高要求。在这种场景下,选择MongoDB作为核心存储机制,黑白常不错的选择。

  

  MongoDB不像关系型数据库,必须界说Schema,MongoDB比力个性化,对Schema的支持也没有那么严格,可以在表里随意更改布局。但freeschema是否真的free吗?比如原来的关系型数据库,必要界说每一列的名称和范例,存储时只需存储真正的数据就可以了,schema本身不必要存储。由于MongoDB没有schema的概念,存储的自由度大了,但整个存储空间会带来一些额外开销,毕竟要存储字段名,value值无法改变,但可以镌汰字段名的长度,比如age可以思量用A表现。这时大概会出现可读性题目,我们在业务层做了映射,用A代表age。同时,减小整个数据的字段名,通过上层映射办理可读性题目。

服务器硬盘miss(服务器硬盘missing,强制加载) 服务器硬盘miss(服务器硬盘missing,逼迫
加载)「服务器硬盘显示missing」 行业资讯

  别的我们还做了数据压缩,着实我们有很多文本数据,文本数据的压缩率还是比力高的,我们对部分业务也采取了数据压缩的方式。在Auto-sharding方面,我们采取库级sharding,collectionsharding采取手动sharding。当整个表的行数量比力大时,会举行拆分,把一些比力大的文档切分成小文档,包罗这些文档的嵌套存储,都是MongoDB相对于其他关系型数据库而言比力良好的地方。

  主动天生_id着实就相称于主键的概念,默认的字段长度是12个字节,整个存储空间的占用比力大,我们尽大概根据业务特性,在业务层把该字段添补成我们本身的字段。假如存储用户信息,该字段可以填成UID,由于UID最大是八个字节。一方面可以减小整个存储空间,另一方面,虽说_id可以在MongoDB服务端天生,但我们尽大概把_id天生工作放在业务层或应用层,可以镌汰MongoDB在服务端天生_id的开销,写入压力比力大时,整个性能的节流非常显着。

  

  接下来是摆设层面,每一个分片上是ReplicaSet,同时开启Sharding功能,根本布局如上图右边所示,每个分片做一个Sharding,在Sharding上有ReplicaSet的概念。通过这个架构,全部configs直接通过mongos到shards。增长sharding大概在sharding上做增减,实际上对整个应用是比力透明的。如许摆设一方面可以很好的满意业务需求,另一方面可以很好地满意内部扩展和故障转移。

  另一个比力潜伏的话题就是sharding操纵,各人大概都比力关心,Auto-Sharding到底靠不靠谱。就我个人明白而言,既然要用Auto-sharding,就要办理shardingkey的题目。假如选用单一递增的shardingkey,大概会造成写数据全部在末了一片上,末了一片的写压力增大,数据量增大,会造成数据迁徙到前面的分区。假如选用随机key,简直可以克制写题目,但假如写随机,读就会出现题目,大概会出现大量随机IO,对一些传统磁盘而言影响是致命的。那怎样选取符合的sharding-key呢?先要包管该key在整个大范围内单调递增,如许随机选择时,可以包管相对匀称,不会引发其他题目。

  别的,我们在测试中发现,数据迁徙过程中常常会出现一些题目。一旦发生数据迁徙,比如从A迁到B片,数据大概同时存在于两片数据上,直至迁徙完成,整个数据才会全部存在于B片上。58的业务特点属于中午访问的人很少,这时MongoDB集群的负载比力低,体系会以为此得当举行数据迁徙,将会开启Auto-sharding。午饭时间竣事之后,访问量就开始渐渐增长。此时,整个迁徙尚未完成,不会立即克制,集群的OPS会刹时从几千掉到几十,这对业务的影响非常大。这时,我们会指定整个sharding的迁徙时间,比如从破晓两点到早上六点这段时间属于业务低峰期,这段时间可以答应sharding举行业务迁徙,同时开启数据库级别的分片。如许可以克制Auto-sharding数据迁徙带来的题目。

  

  别的,做整个计划特别是业务计划时,肯定要相识业务发展场景,比如半年或一年内,大概可以增长到什么样的规模,必要提前做预期。根据业务发展环境,就知道大概必要开多少分片,每一片放多少数据量符合。

  

  做整个规划时,也必要思量容量性能。至少要包管Index数据和HotData全部加载到内存中,如许才可以包管MongoDB的高性能,否则性能压力还是蛮大的。2011年开始利用MongoDB时,数据库内存是32g,厥后一起上升至196g,着实随着业务的发展,整个硬件投入本钱也是蛮高的。实际上假如内存充足大,整个性能环境还是比力令人满意的。

  

  别的,MongoDB整个数据库是按照文件来存储的,假如有大量表必要删除的话,发起将这些表放到同一的数据库里,将会镌汰碎片,进步性能。单库单表绝对不是最好的选择,表越多,映射文件越多,从MongoDB的内存管理方式来看,浪费越多;同时,表越多,回写和读取时,无法归并IO资源,大量的随机IO对传统磁盘是致命的;单表数据量大,索引占用高,更新和读取速率慢。

  别的一个是Local库,Local重要存放oplog,oplog到底设多少符合呢?根据58的履历来看,假如更新比力频仍而且存在延时从库,可以将oplog的值设置的轻微大一点,比如20G到50G,假如不存在延时从库,则可以得当放小oplog值。

  

  针对业务场景计划库和表,由于MongoDB实际上是带有嵌入式功能的,比如以人为例,一个人有姓名,性别,年龄和地点,地点本身又是一个复杂的布局,在关系型数据库里,大概必要设置两张表。但在MongoDB里非常简单,把地点做成嵌套文档就可以了。

  

  表计划无非这几种,一对一,一对多和多对多的关系,一对一关系比如用户信息表,实际上就是显着的一对一关系,雷同于关系型数据的计划,用uid更换_id,做一个主键就ok了。

  

  一对多的关系比如用户在线消息表,一个人着实可以收到很多消息,这是显着的一对多关系,可以按照关系型数据库来计划,按行扩展;也可以采取MongoDB嵌套方式来做,把收到的消息存在一个文档里,同时MongoDB对一个文档上的每一行会有限定,假如高出16兆,大概会出现更新不乐成的环境。

  

  多对多关系如上图示例,整个包罗Team表,User表,尚有两者之间的关系表。在关系型数据库里,这是三张表,一张表是整个Team表的元数据,另一张表是User表的元数据,同时尚有关系表,表现二者的包罗关系。在MongoDB里,可以借助嵌套关系来完成这件事。

  

  每次通过Team表中的teammates反查询得到teamid,Teammates必要创建索引,具体计划可以参照上图。当整个表比力大的时间,可以做手工分表,这点与关系型数据库雷同。

  

  当数据库中一个表的数量高出了千万量级时,我们会按照单个id举行拆分,比如用户信息表,我们会按照uid举行拆分。比如一些商品表,既可以按照用户来查询,又可以按照整个人来查询,这时间怎么办呢?

  

  起首对整个表举行分表操纵,infoid包罗uid的信息,对infoid举行程度拆分,既可以按照uid查询,又可以按照infoid查询,可以很好地满意商品信息表的需求,团体思绪还是按照程度拆分的方式。

  

  早先,我们做了IM离线消息聚集布局,也就是说,当或人不在线时,我可以把消息先存起来,待他上线时,再把整个消息拉已往。在这个过程中思量到发生物理删除时,更新压力会比力大,我们采取逻辑更新,在表中设置flag字段,flag为0,表现消息未读,flag为1表现消息已读。批量删除已经读取的离线消息,可以直接采取MongoDB的删除下令,非常简单。但当数据量比力大时,比如到达5KW条时,就没那么简单了,由于flag没有索引,我们晚上20点开始摆设删除,不停到破晓依然没有删除完毕,整个过程报警不绝,集群的服务质量大幅降落。

  

  缘故起因很简单,由于你要举行删除,实际上就是做了一个全表扫描,扫描以后会把大量冷数据互换到内存,造成内存里全都是冷数据。当数据高峰期上来以后,肯定会造成服务本领急剧降落。怎么办理呢?

  

  起首把正在举行的opidkill掉,至少先让它规复正常,别的可以在业务方面做优化,最幸亏用户读完以后,直接把整个逻辑删撤除就OK了。其次,对删除脚本举行优化,从前我们用flag删除时,既没有主键也没有索引,我们每天定期从从库把必要删除的数据导出来,转换成对应的主键来做删除,而且通过脚本控制整个删除速率,整个删除就比力可控了。

  

  别的我们发现,一旦大量删除数据,MongoDB会存在大量的数据空间,这些空洞数据同时也会加载到内存中,导致内存有效负荷低,数据不绝swap,导致MongoDB数据库性能并没有显着的提拔。

  

  这时的办理方案着实很轻易想到,MongoDB数据空间的分配以DB为单位,本身提供了在线紧缩功能,不以Collection为单位,整个紧缩服从并不是很好,由于是online紧缩,又会对在线服务造成影响,这时可以采取线下的办理方案。

  

  方案二,紧缩数据库,把已有的空洞数据remove掉,重新天生一份空洞数据。先预热从库,把预热从库提拔为主库,把之前主库的数据全部删除,重新同步数据,同步完成后,预热此库,把此库提拔为主库,完全没有碎片,紧缩率到达100%。但这种方式连续时间长,投入维护本钱高,假如只有2个副本的环境下,紧缩过程单点存在肯定风险。

  

  这时在线上做对比,我们发现,紧缩前大概是85G的数据量,紧缩之后是30G,大概节流了50G的存储量,整个紧缩结果还是蛮好的,通过这种方式来做还是比力好的。

  

  别的讲一下MongoDB的监控,MongoDB提供了很多监控工具,包罗mongosniff,mongostat,mongotop,以及下令行监控,尚有第三方监控。我们本身怎么做呢?

  

  我们针对MongoDB本身的性能环境,用的比力多的是mongostat,可以反映出整个服务的负载环境,比如insert,query,update以及delete,通过这些数据可以反映出MongoDB的团体性能环境。

  

服务器硬盘miss(服务器硬盘missing,强制加载) 服务器硬盘miss(服务器硬盘missing,逼迫
加载)「服务器硬盘显示missing」 行业资讯

  这此中有些字段比力紧张,locked表现加锁时间占操纵时间的百分比,faults表现缺页停止数量,miss代表索引miss的数量,还包罗客户端查询列队长度,当前毗连数,活泼客户端数量,以及当前时间,都可以通过字段反映出来。

  

  根据履历来说,locked、faults、miss、qr/qw,这些字段的值越小越好,最好都为0,locked最好不要高出10%,faults和miss的缘故起因大概是由于内存不敷,内冷数据或索引设置不公道,qr|qw堆积会造成数据库处理惩罚慢。

  

  Web自带的控制台监控和MongoDB服务一同开启,可以监控当前MongoDB全部的毗连数,各个数据库和collection的访问统计,包罗Reads,Writes,Queries等,写锁的状态以及最新的几百行日记文件。

  

  官方2011年发布了MMS监控,MMS属于云监控服务,可视化图形监控。在MMS服务器上设置必要监控的MongoDB信息(ip/port/user/passwd等),在一台可以或许访问你的MongoDB服务的内网呆板上运行其提供的Agent脚本,Agent脚本从MMS服务器获取到你设置的MongoDB信息,Agent脚本毗连到相应的MongoDB获取须要的监控数据,Agent脚本将监控数据上传到MMS的服务器,登录MMS网站查察整理过后的监控数据图表。

  

  除此之外,尚有第三方监控,由于MongoDB的开源爱好者对它的支持比力多,以是会在常用监控框架上做一些扩展。

  

  以上是MongoDB在58同城的利用环境,包罗利用MongoDB的缘故起因,以及针对差别的业务场景怎样计划库和表,数据量增大和业务并发时碰到的典范题目及办理方案。

  本日的分享到此竣事,谢谢各人!

客户评论

我要评论