1. 聚能聊>
  2. 话题详情

MongoDB 使用场景及运维管理问题交流探讨

MongoDB是一个开源的文档型数据库(Document-oriented database),其灵活的文档模型使得其非常适合于快速开发迭代、需求多变的业务场景,MongoDB 支持复制集(Replica Set)、分片集群(Sharded Cluster)两种部署形态,能很好的服务高可用、水平扩展的大数据应用,目前在电商、游戏、物联网等场景都着有广泛的应用。

大家一起来分享下使用 MongoDB 的业务场景,以及在使用过程中遇到的问题,集思广益,让大家都能用好 MongoDB。

_

参与话题

奖品区域 活动规则 活动已结束,可继续参与讨论哦

  • 奖品一

    虾米VIP季卡 x 2

  • 奖品二

    优酷VIP季卡 x 1

  • 奖品三

    阿里云代金券 x 2

54个回答

2

hunter_dong 已获得虾米VIP季卡

我们第一次使用,目前使用情况下,php mongodb驱动感觉有问题呢。使用的是mongodb这个驱动,大量长连接,貌似也没有其他方法close。有多少fpm进程,就有多少连接。在副本集的情况话,一个fpm会跟所有副本集机器建立长连接。。。。这样吃不消啊。。。一台web服务器,200个fpm进程,副本集是3台机器,就有600个长连接在那里呢。所以,这个是不是不太妥当呢。

yunnotes 回复

你说的这个问题的确存在,主要由 php fpm 服务模型导致,我们同事针对 php 的场景做过一些性能优化,参考 https://yq.aliyun.com/articles/35148?spm=5176.100240.searchblog.66.tIbrsO,这样使得 mongod 支持几千并发短连接都没问题。

hunter_dong 回复

谢谢。

hunter_dong 回复

这个是短连接吧。用的是mongo驱动么。我们现在用的是mongodb驱动,貌似是fpm跟mongodb是建立了长连接。

hunter_dong 回复

而且fpm跟mongodb建立的长连接,每次请求还是会继续做认证。

yunnotes 回复

每次请求都会认证,就说明是短连接

hunter_dong 回复

但是实际fpm会跟mongodb建立很多连接,这个是fpm机制的问题了是吧?我们现在是副本集节点是3个,每个节点会有fpm过来的长连接 connections_current 1200个。因为我6台web,每个web上开启了200个fpm.如果我后期需要继续增加web,fpm继续增加,这个这么多连接翻倍提升。

yunnotes 回复

是的,因为 fpm 机制导致,所以这种场景,只能去优化后端,让后端能支持更多的连接并发,之前发的链接就是对鉴权性能的一个优化。

hunter_dong 回复

恩恩。那也只能是用了阿里的mongodb产品才能,我们这种一般的没有能力更改mongodb代码的还是用不上。貌似鉴权性能,是不是抛弃安全,不用认证,就没有这个问题了。

yunnotes 回复

是的,不开启鉴权,就只会增加 tcp 连接、tcp 关闭的额外开销;但生产环境强烈建议开启鉴权,各种误操作、攻击之类的都是因为没开启鉴权导致的。

hunter_dong 回复

为啥官方不把这个问题给优化了呢。。大大们贡献代码哇。

hunter_dong 回复

sharding我们有发现数据取不到的问题,所以我们直接现在没敢用了。目前还没查到原因,是应用的问题,还是mongodb的问题。还有个问题就是我在3.2.9遇到的,就是做了集群分片后,有部分表没有做,按道理应该是这些没有做分片的表应该是写入primary节点上。但是我们发现他把数据写入了多个节点中。。

yunnotes 回复

sharding 读不到数据的问题,这个得看具体 case,大部分情况下应该是应用使用上的问题。

sharding 集群,没有开启分片的集合会存储在 primary shard,但每个集合的 primary shard 是不同的,选择 primary shard 也是根据当前各个 shard 的存储负载决定的。

hunter_dong 回复
回复@yunnotes:

我这边遇到的是 没有开启分片的集合 他存储到多个shard了,并不是 primary shard

评论
2

lifubang 已获得阿里云代金券

@yunnotes,我们用mongodb已经两年了,mongo副本集和分片都用了,已经跑了快上亿的数据了,目前有2个问题:
1、副本集既然支持读写分离,那么能否让主库和从库有不同的索引?因为写数据时,如果索引太多,会增加写开销,所以我想在主库上少建一点索引(只建update要使用的索引),而在从库上多建一些索引;
2、有没有什么好方法实现副本集a中的一个从库作为副本集b中的主库?因为我想把a中的数据实时重放到b中去进行复杂的使用,这个复杂的使用会影响到a的效率;在b中所作的任何更改,不用体现在a中。目前我是通过写一个程序,从a中去拉取oplog.rs,在b中重放。但是由于oplog.rs无法加索引,所以每次根据时间戳ts进行查询都较慢。

lifubang 回复

@yunnotes,或者其他mongo专家,另外,关于历史数据有没有什么好的办法?最好对业务来说,对历史数据的操作和对热数据的操作是透明的,只是对历史数据的操作会稍微慢点。我有一种想法,使用sharding,把所有表加一个字段,是否是历史数据:history,只有两个值,true和false,并作为片键,不知是否可行,true的在片a,false的在片b。由于没做过两个值的分片,不知道当history从false变成true时,是否会及时moveChunk?
另外,假设会及时moveChunk,我想有时这个数据量也会挺大的,如果sharding能做到每片都有所有的数据就好了,分片时只是配置每片加载哪些数据,并不需要真正去moveChunk,只更新chunks的配置并更新内存就好。毕竟,现在存储是不贵的,而cpu和内存才贵。

yunnotes 回复
回复@lifubang:

问题1,可以这么做,MongoDB 并不强制要求副本集每个成员索引必须一样,做法参考 https://docs.mongodb.com/v3.2/tutorial/build-indexes-on-replica-sets/ ,思路就是把节点从复制集里移除,各自独立建立索引,这个方法也可以用在集合数据太多,建索引可能影响正常服务的场景。

但强烈建议,副本集上所有节点索引保持一致,因为副本集主备可能自动的触发选举,如果上述场景,你主备切换了,则效果就完全跟你预期的相反了。

yunnotes 回复

问题2,目前 MongoDB 不支持副本集之间的同步

如果你说的 b 上的复杂使用,是只读的场景,可以直接通过增加 secondary(根据需要设置成 hidden或选举优先级为0等)方式实现。

副本集间的同步,我们目前也正在做,做法也是通过抓取 oplog、然后重放的方式;你提的 oplog.rs 没有索引的问题,可以考虑使用 tailable cursor 持续去拉,这样不用每次都去遍历oplog.rs找问题。https://docs.mongodb.com/v3.2/core/tailable-cursors/

yunnotes 回复

关于历史数据,将 history 作为片键是不合适的,原因

  1. 取值只有2个,导致你的数据只能有2个 chunk,只能分散到2个 shard
  2. sharding 的片键是不允许更新的

MongoDB 本身能做到尽量将频繁访问的数据 cache 在内存,本身就相当于做了冷热数据的区分;如果是你想历史数据自动删除,可以考虑 TTL 索引。

lifubang 回复
回复@yunnotes:

太感谢了。您考虑太周到了。我确实没考虑触发选举的场景,因为我目前还没有碰到主备切换的时候,都挺稳定的。不过这确实需要考虑。

lifubang 回复

sharding是有些问题,在运行一段时间后,有count不准的情况;另外是在moveChunk的过程中,有可能会取到多条数据,但是还没发现取不到数据的情况。
上线后建议把autoBalance关掉,加一个时间窗口进行balancer调度。

lifubang 回复
回复@yunnotes:

关于历史数据,是不是如果3.4出来了,可以用Shard Zone来解决历史数据的问题?具体可以参考(Tiered Hardware for Varying SLA or SLO)[https://docs.mongodb.com/master/tutorial/sharding-tiered-hardware-for-varying-slas/]

yunnotes 回复
回复@lifubang:

这个机制现在就支持的,tag aware sharding https://docs.mongodb.com/v3.2/core/tag-aware-sharding/ ,需要你有一个固定不变的规则来指定是否是历史数据,比如『创建时间在1个月之前』...

评论
2

天痕散华 已获得虾米VIP季卡

前来支持一下帅气的友东。
业务场景:

  1. 用在应用服务器的日志记录,查找起来比文本灵活,导出也很方便。也是给应用练手,从外围系统开始使用MongoDB。
  2. 用在一些第三方信息的获取或者抓取,因为MongoDB的schema-less,所有格式灵活,不用为了各种格式不一样的信息专门设计统一的格式,极大得减少开发的工作。
    遇到的问题:
  3. 以运维的身份,很难去推动开发使用mongodb,详细的使用/开发案例比较少。也无法就API层面对开发进行指导。
  4. sharding的一致性备份、增量备份、恢复。实施起来还是比较麻烦的。
  5. 副本集的mongod或者分片的mongos上端,不知道有什么可用的均匀负载。
yunnotes 回复

感谢天痕同学

  1. 随着使用的人越来越多,这个问题会好很多
  2. sharding 备份的确是个大难题,我们刚刚把这个问题落地,实现了 sharding 的任意时间点备份恢复
  3. shard 间的均衡靠系统自身,shardkey 选择的合适一般问题不大;mongos 的均衡靠Driver 或应用,driver 连接时,指定多个 mongos 地址,driver 会自动均衡;应用也可以自己显式指定连接到哪些 mongos 来实现负载均衡。
天痕散华 回复
回复@yunnotes:

sharding的任意时间点备份恢复,赞!
你是指driver讲读请求随机或轮流某个节点的那种均匀负载喽,对driver的实现还不太了解。显式的话,需要很好的预估到时候的并发量是多少了。更希望有一种像haproxy那样,可以读写分离,应用也只需要配一个地址的那种。

yunnotes 回复

是的,driver 连接时,你配置一个 mongos 列表,它会自动均衡请求到 多个 mongos 上的;

多个mongos 前面也可以再部署一个 haproxy、lvs

lifubang 回复
回复@yunnotes:

不是建议把mongos和应用布在一起吗?应用只与本地mongos通讯。因为真正的读写是在后端的mongod上。

yunnotes 回复
回复@lifubang:

各有好处;只连单个 mongos 总归是个单点。

评论
1

屋顶小黑猫 已获得阿里云代金券

@yunnotes 问个简单问题 就是我们现在mongo架构在云上 想迁移下来 不知道选择2.6还是3.0以上版本不明白他们之间的主要区别。还有就是迁移过程中需要注意哪些问题,后续的优化有什么需要做的,mongo主要用于读

yunnotes 回复

2.6、3.0的区别可以看官方详细的 release note,现在使用 MongoDB 建议用3.2版本,功能、稳定性上都非常给力。

迁移过程中,主要是控制迁移对业务的影响,迁移完一定要做数据校验。

天痕散华 回复

如果只是迁移升级的话,数据dump出来,再在新环境导入就行。驱动方面需要升级,某些操作的函数变了,尤其是认证那一块需要注意。因为你不是升级,所以可以2.6dump出来,导入到3.2的

评论
1

塞尔鱼 已获得优酷VIP季卡

  1. node.js开发蜜汁偏爱mongodb,mongoose是各大数据库产品里面最好的node.js sdk。
  2. schema比较灵活的情况下,综合稳定性、性能、易用性上的考虑来看,mongodb是一个不错的选择,相对于Hbase/Cassandra/Scylladb而言;当然,不在乎存储效率,非常在意查询效率的话,es也是可以的。

(逃

yunnotes 回复

nodejs 和 mongodb 是最佳拍档,越来越多的开发者在尝试MEAN stack

评论
2

lifubang

有这么一个场景,由于mongodb无模式,所以在系统开发时,初始化的数据并没有考虑所有字段,假设有一个文档,有上亿条数据,在业务运行过程中,所有客户需要高并发频繁update '$set'一个不存在的字段,这个字段是字符型,大小为1个字符到10000个字符不等,update的条件有索引,这样做是否会导致性能下降?查资料说需要为这个字段先预留空间。确实需要这么做吗?

lifubang 回复

@yunnotes,我之所以这么问,是因为我们使用压力测试工具时,业务系统根本没有问题。但是在实际运行过程中,总有几个用户存在访问超时的情况,导致客服老要花费时间解决这种技术问题,也不知道是网络不好,还是确实是因为'$set'后需要挪空间的问题。我在实际模拟用户测试时,也出现过该业务API超过5s的情况,但是我们公司网络确实不太稳定,所以无法定位问题的所在。

lifubang 回复

@yunnotes, 再延伸一下,用了mongodb,还需要用redis吗?例如:mongodb不是也有InMemory引擎吗?另外您也提到“MongoDB 本身能做到尽量将频繁访问的数据 cache 在内存,本身就相当于做了冷热数据的区分;”,那还需要要在高并发的场景中引入redis吗?这决定到我们的架构,而且我们的mongo中的数据越来越多,还没做好历史数据的处理问题。麻烦大神给个建议。

yunnotes 回复

这是个好问题,频繁 update 的场景(尤其是 update 的内容比原文档要大),在 mmapv1引擎里的确是可能有性能问题,而且会造成大量磁盘碎片问题。但这个在 wiredtiger 引擎里完全不存在,wiredtiger 所有的新写入、更新、删除都不会修改原来的内容,而是写入新的 page里,所以更新在 WT 里并不是特殊的场景。

yunnotes 回复

用了 mongodb,是否还需要 redis?

当你的内存已经能容纳活跃的数据集时,性能延时上不能接受,可以考虑使用 redis来缓存; redis 之所以高效,是因为结构简单,简单的 KV 一次查询搞定;但需要注意的是,mongodb 一条查询能实现的功能,通过 redis 可能需要多条查询的结果综合起来,所以最终完成同样的事情,总体开销可能是比较接近的。

关于 in memory 引擎,使用 mmapv1、wiredtiger 引擎,内存足够大,跟 in memory 的性能差不了太多的。

评论
1

何斌斌

我们现在的情况是php-fpm+3台跨国机房的mongodb集群,PHP驱动是新版的mongodb1.1.8。其中主节点在阿里云香港,从节点在杭州阿里云和德国亚马逊,想实现读操作时,杭州节点读取本地数据,现在的问题是mongodb连接池,哪怕是读操作也会创建德国服务器的tcp连接,通过PHP的数据库getserver()方法得知,其实该读操作已经读取的是杭州节点数据,但是由于需要创建德国节点的tcp连接,会造成读操作缓慢,这个如何解决?

yunnotes 回复

如果你用复制集的方式去连接(指定多个节点 ip 地址、或者复制集的名字),driver 的确是会每个MongoDB 复制集的成员都建立 tcp 连接的; 你可以让应用直连节点(直接指定其中一个节点的 ip 地址),这样就只会跟你指定的节点建立 tcp 连接了。

何斌斌 回复
回复@yunnotes:

直连一个服务器IP,不填复制集名字,写操作,会找不到主节点😭

何斌斌 回复
回复@yunnotes:

这样写操作会有问题,找不到主节点

yunnotes 回复

指定 readPreferece 为 secondary

评论
3

初码

MongoDB还是挺有意思的,介于关系数据库与NoSQL数据库之间,与著名的内存数据库Redis相比,可以说MongoDB更接近于MySQL这样的传统数据库,支持对字段索引,游标操作,支持持久化,但是不支持事务,也是弱一致性的。就和Redis能解决大型排行榜场景一样,MongoDB的发明和出现,恰恰是系统架构和业务模型发展的必然结果,想起以前在处理非常复杂难受的多表查询时,会偷懒或者说想个捷径,把关联表的参数内容以JSON方式存在字段中,在开发时反序列化或者在运行时利用客户端资源直接解析展现JSON,后来学习了MongoDB才发现,哦?原来MongoDB不就是为了解决这样的场景吗!

经常会有人问MongoDB能不能完全替代MySQL这样的传统关系数据库,我想从逻辑上完全可以,例如比较典型的像纽约时报等已经将全站架设在了MongoDB上,但我很反感这样为了技术而技术的理念和思维方式,没有谁替代谁,谁比谁好的绝对,都是技术发展过程中,各种各样的精彩,客观的说,Web综合场景中,关系数据库依然是不可或缺的。但如果能使用MongoDB在例如电商产品查询场景中,快速的去处理原本需要各种复杂join才能得到的查询,那也是极好的。

yunnotes 回复

『为了技术而技术』的确不可取,各种数据库各有优劣,用在合适的地方发挥最大的效用才是最好的。

评论
1

修己

我们把mongo主要是做汇总用,从分库分表里面取出来,然后汇总,发现当查询多的时候,会特别卡

yunnotes 回复

可以针对慢的请求针对性的优化

爱车汇 回复

不可否认MongoDB有诸多优点,是分布式存储数据库里强强者。但是不可能取代mysql,因为NOSQL起家的时候针对特定场景而设计的,主要是CAP或者BASE理论的实践,实际上就是反关系数据库的必然结果。而mysql有事务的ACID特性,仍然是交易场景必不可少的因素,在交易的核心场景,能用mysql解决,就不可能使用mongodb来解决。场景不同,mongodb并非通用型数据库,不可能替代所有场景。

评论
3

cjhust

mongodb之前有用过,主要用来存储一些监控数据,对开发人员来说,真的很方便,增加字段不用改table,学习成本极低。
不过当数据量越来越大时,自己维护就有点麻烦了,虽然写了个脚本定期删除数据(某个版本之前好像还要移动数据之类的),但是总有自己搞不定的问题。

最近又想把mongodb好好地拣起来运用下,发现有这么多人在研究,心里更踏实了,持续关注。

明俨 回复

给你个好评哦亲

评论
4

triplelift

针对MongoDB插入效率极高,但查询即使建立索引也会因查询条件增多而变慢的情况。我觉得:1.尽量将唯一索引的内容进行处理后放在_id字段较为方便,毕竟这种NOSQL数据库的文件名(_id字段)还是很重要的;2.接收物联网数据,用于机器学习具有较大优势。
3.数据条目变化比较大的情况,完全不适用于SQL,体现NOSQL的优势。

3

实地此次

我一般就是当服务器端缓存用了

当某一项任务需要频繁存写数据,但是最终记录是在这项任务完成之后才能产生的,过程数据不需要存档的情况下,这类nosql就挺好用了,尤其是要防止浏览器意外关闭的情况下。

比如需要逐项录入大量数据,最后存入数据库的却只是计算后的各种同类数据的数量。。。。

天痕散华 回复

redis+持久化呢?

评论
1

hunter_dong

想请教。mongodb里怎么查看应用程序对那些表的操作比较频繁,比如读,如果发现读非常多,怎么定位是对哪个表的读比较多。或者有啥工具可以看。

yunnotes 回复
  • mongostat 能看实时的 增删改查 qps
  • mongotop 可以看出读写频繁的表
评论
1

qiangchen4

1.运维方面:希望后期能提供片键更改的工具,现在有些片键选择不合理,只能导出来,设置好片键 再导进去 ,有点麻烦,此类问题大规模使用,肯定会遇到。
2.希望阿里大神能开源解析oplog的工具,嘿嘿....
3.执行计划能更详细一点,现在的比较简陋。
问题:
普通索引和唯一索引对执行计划的性能是否有区别?

qiangchen4 回复

问题:sharding的 增量备份和恢复不是很完善

yunnotes 回复
  1. 片键修改实现难度相当高,因为片键决定文档分布到哪个 shard,如果修改了,还要把数据迁移到新的 shard,这个没法做到原子性。
  2. mongooplog就是现成的工具,oplog 本身很简单,就是一个普通的 json 文档,关键看你怎么用,我们的业务结合比较紧密,能应用的场景也不多。
  3. 这个一言难尽,可以看看文档 https://docs.mongodb.com/v3.2/core/query-plans/
  4. 普通索引、唯一索引,查询的时候没啥区别;更新的时候,唯一索引会额外检查索引字段是否已经存在
qiangchen4 回复
回复@yunnotes:

请问:热集合和热索引 是否有办法按使用频率 从高到低 统计,是db.collections.stats()下的哪些参数值呢? 感谢解答上面的疑问

评论
1

孤剑

之前有了解过这个东东,最近准备尝试尝试,不知道mongodb 适合什么场景?

yunnotes 回复

不支持复杂事务、灵活文档模型、快速开发迭代、服务高可用、数据高可靠、可扩展、文件存储、地理位置查询、文本查询等

上面的特性,能对上2条及以上,用 mongodb 准没错

评论
1

1673978249377058

MongoDB是一个开源的文档型数据库(Document-oriented database),其灵活的文档模型使得其非常适合于快速开发迭代、需求多变的业务场景,MongoDB 支持复制集(Replica Set)、分片集群(Sharded Cluster)两种部署形态,能很好的服务高可用、水平扩展的大数据应用,目前在电商、游戏、物联网等场景都着有广泛的应用。

大家一起来分享下使用 MongoDB 的业务场景,以及在使用过程中遇到的问题,集思广益,让大家都能用好 MongoDB。(这个问题我还是有点不明白。能否详细点。。。)

yunnotes 回复

这是个『话题』,希望用过 mongodb 的同学都来分享自己的经验和遇到的问题。希望你也能参与,谈谈你的见解

评论
1

1745822778898592

数据库记录基于map结构,每条记录基于json。与HTML5完美结合。

yunnotes 回复

在快速开发的场景,json 的表达形式很有杀伤力,方便快捷。

评论
1

会流泪的猫

一台web服务器?200个fpm进程,副本集是3台机器,就有600个连接? 客观来说,是个未知!一切皆有可能

hunter_dong 回复

为啥是个未知?实际就是这样呢

何斌斌 回复

为什么开200个进程那么多,进程数量是CPU的整数倍不就可以了,一个时间片也就能处理CPU个数的进程不是吗

评论
1

周梦康

附近的人,地理位置的索引。不过后来我们换成 redis geo 了。

yunnotes 回复

替换的原因能分享下么, 遇到了什么问题?

评论
0

炉火纯青

MongoDB,在我自己的项目中已经完全替代了关系数据库,高效、方便

yunnotes 回复

开发效率上,MongoDB的确碾压关系型数据库,不用create table、alter table了

评论
3
10218
浏览
3
收藏
邀请他人互动
关注
22
粉丝
409
话题
1

简介:

张友东,花名林青,阿里云数据库组技术专家,主要关注分布式存储、Nosql数据库等技术领域,目前主要参与MongoDB云数据库的研发,致力于让开发者用上最好的MongoDB云服务
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...

RDS是一种稳定可靠、可弹性伸缩的在线数据库服务。支持MySQL、SQL Server、PostgreSQL、高...