您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 商业计划书 > 百度云系统部工程师杨林《百度云MongoDB经验分享》
Mongo@百度云百度云杨林@idning提纲提纲•Mongo的特点•百度云与Mongo•遇到的问题•一些经验Mongo特点特点•丰富的数据类型丰富的数据类型◦嵌套结构◦数组•丰富的索引丰富的索引/查询模式支持查询模式支持◦地理索引/数组索引/全文索引/MapReduce•Schemaless灵活,易上手•autosharding•较高的性能百度云与百度云与Mongo应用场景应用场景•结构化存储平台PSS(PersonalStructuraldataStorage)•典型应用典型应用◦图片exif信息◦通讯录◦设备同步•数据量:百亿-千亿•性能:在线业务,平均响应时间要求10ms内•多索引需求多索引需求◦包含数组索引特点特点•规模大规模大◦单表数据量数百亿(存储百T级别)◦容易触发mongo的一些性能隐患/隐藏BUG•数据冷数据冷◦需要大量机器,期望压缩功能.•用法固定用法固定◦都是基于个人的数据,可以很好按照uidsharding◦查询模式相对简单架构架构1.提供API,隐藏后端多个集群的细节,防止对mongo的滥用2.便于在API层统计,分析和封禁3.系统管理员直接操作Mongo架构架构(2)遇到的问题遇到的问题连接数爆炸连接数爆炸$mongostat-h10.50.18.33--port7111-u__system-pxxxx-n100connectedto:10.50.18.33:7111...faultslockeddbmiss%qr|qwar|awnetInnetOutconn......28xxx:53.7%03|00|21m999k3031......8xxx:48.0%019|00|11m886k3038......16xxx:52.2%00|00|11m1m3055......6xxx:45.1%00|00|01m812k3061......15xxx:52.6%00|00|01m973k3061......13xxx:44.3%06|00|1970k1m3062...conn一直上涨,达到配置的极限值,开始拒绝服务.原因原因•慢查询•客户端太多客户端太多◦php-driver连接池在线程间不共享◦50machines*500threads=25000.解决解决•通过监控及早发现•针对慢查询,用killOp()杀掉•针对客户端过多的情况针对客户端过多的情况,增加一层增加一层proxy◦对后端使用长连接,前端使用短连接◦相当于跨进程连接池慢查询慢查询•导致conn上升•导致qr上升•io打满/lock高避免这些查询模式避免这些查询模式•少用count()db.testColl.find({xxx:testValue}).count()•避免large-skip(特别是sharding)db.testColl.find({xxx:testValue}).skip(100000).limit(10)•不用$nin杀掉慢查询杀掉慢查询命令:db.currentOp()db.killOp()杀慢查询要注意:op['op']=='query'&&!op.startswith('conn')&&!splitVector&&!moveChunk建索引建索引/repair•耗时非常长,单mongod上3亿条数据,对三个字段建索引:db.testColl.ensureIndex({_uid:1,xxxx:1,md5:-1},{background:true})◦类型分别为int,int,string(md5),需要时间18小时◦如果类型为int,int,int,需要时间会比较少•io/cpu压力影响正常业务•阻塞主从同步◦primary上索引建完写oplog之后◦索引通过oplog同步到Secondary◦Secondary执行该oplog时,会阻塞住后续的Oplog(background选项在Secondary会忽略)•repair很慢,还需要2倍磁盘空间解决解决轮转方式建索引•下线一台从库,做好索引后挂上追oplog,然后做下一台机器•也可以做完一个机器后,拷贝数据文件到其它机器.•先做从库,再做主库.利用迁移做索引•在数据迁移到另一个集群的过程中,写数据之前,建索引autobalancer•小数据量时没问题•一旦开始balancer,线上服务就开始不稳定(读写变慢,超时,conn,qr上涨)•调整balancer窗口db.settings.update({_id:balancer},{$set:{activeWindow:{start:2:00,stop:7:00}}})不能从根本上解决问题,要不了几天,窗口被缩小到0.原因原因•autoballance是使用moveChunk实现的•moveChunk删除阶段的问题删除阶段的问题◦chunk迁移所操作的数据,很多不是热数据,迁移和删除过程中导致需要频繁读取磁盘,造成IO负载高◦删除阶段维持时间长,比如move10w条数据后,用1000/s的速度删除,需要维持100s•moveChunk不能并行.解决解决•moveChunk后的删除阶段限速(能缓解问题)•pre-sharding:db.runCommand({split:testDb.testColl,middle:{uid:100000000}});db.runCommand({split:testDb.testColl,middle:{uid:200000000}});...db.runCommand({moveChunk:testDb.testColl,find:{uid:100000001},to:'s0-set0'})db.runCommand({moveChunk:testDb.testColl,find:{uid:200000001},to:'s0-set1'})然后可以关闭autoballance(除非需要扩容)扩容扩容•磁盘用满70%•单mongod读写压力到达极限方案方案(1)1.直接增加直接增加replset,交给交给autobalancer◦遇到autobalancer的问题,每次moveChunk就影响服务◦非常慢.◦2-4个shard时可试一试.2.moveChunk中去掉删除数据阶段中去掉删除数据阶段(noCleanup),通过外部方式来删除通过外部方式来删除◦外部删除可以很好的控制压力,保证不影响线上服务(一般200/s)◦可以并行删◦依然很慢方案方案(2)•扩容慢主要是删数据阶段慢,能不能避免删数据?•把一个replset上所有chunk都move走之后,直接把这个replset上的dbdrop掉.•优点优点◦较快(没有删除阶段)◦全自动化◦可以取代repair操作.•问题问题:◦moveChunk可能因为chunk过大而失败方案方案(2)方案方案(3)•原生的moveChunk一次只能move一个chunk,不能并发,想办法提高moveChunk的速度•不使用原生的不使用原生的moveChunk1.通过外部工具导出数据的方法迁移chunk到新shard(可并发)2.追oplog3.最后一次性修改configsrv中的路由表迁移迁移•扩容来不及•业务隔离需求•升级mongodb到新的版本,不支持平滑升级•新旧架构不一致方案方案步骤:1.迁移基准数据2.追oplog3.api上切换读写到新集群.mongomigrate(部分开源):•迁移时实现pre-sharding•并发导出导入基准数据/并发追oplog•并发追oplog需要在mongod的delete/update的oplog中增加shardkey字段,据此分桶实现并发.•每天可以迁移5-10亿条数据经验经验&工具工具建议建议•HDD=SSD•保证节点间时钟同步30s•一切地方用IP,不要用hostname(rs.add/addshard等)•pre-sharding(和hbase类似)•合理选择合理选择shardkey◦用户数据:按照uid维度sharding◦日志数据:每天一个库.◦_id/md5不是好选择(不均匀,不便于pre-sharding)•如果来不及扩容,可以考虑删一些索引索引选择索引选择•参考参考MySQL建索引的方法建索引的方法◦前缀规则.◦区分度大的字段放前面•注意索引的空间占用mongostat监控监控$mongostat-h10.50.18.33--port7111-u__system-pxxxx-n100connectedto:10.50.18.33:7111...faultslockeddbmiss%qr|qwar|awnetInnetOutconn......28xxx:53.7%03|00|21m999k3061......8xxx:48.0%019|00|11m886k3061......16xxx:52.2%00|00|11m1m3061......6xxx:45.1%00|00|01m812k3061......15xxx:52.6%00|00|01m973k3061......13xxx:44.3%06|00|1970k1m3062...•重点关注:◦conn:有多少连接数,最直观的表现◦qr:有多少读请求在排队(连续几秒大于10=必然有问题)◦locked:锁争用情况,ssd上,该项关系不大慢查询分析慢查询分析mongod日志SunNov1009:28:58[conn3156482]commandadmin.$cmdcommand:{splitVector:testDb.testColl,keyPattern:{cid:1},min:{cid:801753680855133390},max:{cid:916048317419757871},maxChunkSizeBytes:67108864,maxSplitPoints:2,maxChunkObjects:250000,$auth:{local:{__system:2}}}ntoreturn:1keyUpdates:0numYields:946locks(micros)r:1370997reslen:741651msSunNov1011:50:37[conn3141108]updatetestDb.testCollquery:{$and:[{$and:[{$and:[{test_id:{$in:[5555555540808825401]}}]}]},{delete:0},{s_id:555555555}]}update:{$set:{status:1,version:1384055436660}}nscanned:1nupdated:1keyUpdates:3locks(micros)w:3800267ms工具:•dex()◦分析慢查询的模式监控工具监控工具mongoviz其它工具其它工具•部署工具•Replset轮转加索引•Replset增加/重做secondary工具•杀慢查询脚本•chunk数/磁盘空间分析工具.•Web化管理平台•mongoproxy•mongomigrate•draining扩容工具thanks
本文标题:百度云系统部工程师杨林《百度云MongoDB经验分享》
链接地址:https://www.777doc.com/doc-4894665 .html